Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
pong.qc
Go to the documentation of this file.
1#include "pong.qh"
2REGISTER_MINIGAME(pong, _("Pong"));
3
4// minigame flags
5const int PONG_STATUS_WAIT = 0x0010; // waiting for players to join
6const int PONG_STATUS_PLAY = 0x0020; // playing
7
8// send flags
9// (minigame_player) sent when reporting scores
11// (pong_ball) sent when changing team
13
14// keys
15const int PONG_KEY_INCREASE = 0x01; // Move down/right
16const int PONG_KEY_DECREASE = 0x02; // Move up/left
17const int PONG_KEY_BOTH = 0x03; // Player jamming keys at ramdom
18
19// fields
20const int PONG_MAX_PLAYERS = 4;
21const int PONG_SPECTATOR_TEAM = 255; // must be above max teams and equal to or below 255
22.int pong_score; // (minigame_player) number of goals
23.int pong_keys; // (client) pressed keys
24.entity pong_paddles[PONG_MAX_PLAYERS];// (minigame) paddles
25.float pong_length; // (pong_paddle/pong_ball) size (0,1)
26.entity pong_ai_paddle; // (pong_ai) controlled paddle entity
27
28#ifdef SVQC
29
32
37
40
41void pong_ball_think(entity this);
42
43// Throws a ball in a random direction and sets the think function
45{
46 float angle;
47 do
48 angle = random() * (2 * M_PI);
49 while ( fabs(sin(angle)) < 0.17 || fabs(cos(angle)) < 0.17 );
53 ball.nextthink = time;
54 ball.team = 0;
55 ball.SendFlags |= MINIG_SF_UPDATE|PONG_SF_BALLTEAM;
56}
57
58// Think equivalent of pong_ball_throw, used to delay throws
60{
61 pong_ball_throw(this);
62}
63
64// Moves ball to the center and stops its motion
66{
67 ball.velocity = '0 0 0';
68 ball.origin = '0.5 0.5 0';
70 ball.team = 0;
71 ball.SendFlags |= MINIG_SF_UPDATE|PONG_SF_BALLTEAM;
74}
75
76// Add the score to the given team in the minigame
77void pong_add_score(entity minigame, int team_thrower, int team_receiver, int delta)
78{
79 if ( !minigame )
80 return;
81
82 if ( team_thrower == 0 )
83 team_thrower = team_receiver;
84
85 if ( team_thrower == team_receiver )
86 delta *= -1;
87
88 entity paddle_thrower = minigame.pong_paddles[team_thrower-1];
89 if ( paddle_thrower.realowner.minigame_players )
90 {
91 paddle_thrower.realowner.minigame_players.pong_score += delta;
92 paddle_thrower.realowner.minigame_players.SendFlags |= PONG_SF_PLAYERSCORE;
93 }
94}
95
96// get point in the box nearest to the given one (2D)
98{
99 return vec2( p.x > box_max.x ? box_max.x : ( p.x < box_min.x ? box_min.x : p.x ),
100 p.y > box_max.y ? box_max.y : ( p.y < box_min.y ? box_min.y : p.y ) );
101}
102
103void pong_paddle_bounce(entity ball, int pteam)
104{
105 switch(pteam)
106 {
107 case 1: ball.velocity_x = -fabs(ball.velocity_x); break;
108 case 2: ball.velocity_x = fabs(ball.velocity_x); break;
109 case 3: ball.velocity_y = fabs(ball.velocity_y); break;
110 case 4: ball.velocity_y = -fabs(ball.velocity_y); break;
111 }
112
113 float angle = atan2(ball.velocity_y, ball.velocity_x);
114 angle += ( random() - 0.5 ) * 2 * M_PI/6;
115 float speed = vlen(ball.velocity);
116
117 ball.velocity_y = speed * sin(angle);
118 ball.velocity_x = speed * cos(angle);
119}
120
121// checks if the ball hit the paddle for the given team
122bool pong_paddle_hit(entity minigame, entity ball, int pteam)
123{
124 entity paddle = minigame.pong_paddles[pteam-1];
125 if (!paddle)
126 return false;
127
128#if 1
129 vector near_point = box_nearest(paddle.m_mins+paddle.origin,
130 paddle.m_maxs+paddle.origin, ball.origin);
131 return vdist(near_point - ball.origin, <=, ball.pong_length);
132#else
133 return boxesoverlap(paddle.m_mins + paddle.origin, paddle.m_maxs + paddle.origin, ball.m_mins + ball.origin, ball.m_maxs + ball.origin);
134#endif
135}
136
137// Checks for a goal, when that happes adds scores and resets the ball
138bool pong_goal(entity minigame, entity ball, int pteam)
139{
140 entity paddle = minigame.pong_paddles[pteam-1];
141 if (!paddle)
142 return false;
143
144 if ( !pong_paddle_hit(minigame, ball, pteam) )
145 {
146 pong_add_score(minigame,ball.team, pteam, 1);
147 pong_ball_reset(ball);
148 return true;
149 }
150
151 return false;
152}
153
154// Moves the ball around
156{
157 entity minigame = this.owner;
158 float think_speed = autocvar_sys_ticrate;
159 this.nextthink = time + think_speed;
160
161 this.origin_x += this.velocity_x * think_speed;
162 this.origin_y += this.velocity_y * think_speed;
164
165 int i;
166 for ( i = 1; i <= PONG_MAX_PLAYERS; ++i )
167 if ( pong_paddle_hit(minigame, this, i) )
168 {
169 pong_paddle_bounce(this,i);
170 this.team = i;
172 return;
173 }
174
175 if ( this.origin_y <= this.pong_length )
176 {
177 if ( !pong_goal(minigame,this,3) )
178 {
179 this.origin_y = this.pong_length;
180 this.velocity_y *= -1;
181 }
182 }
183 else if ( this.origin_y >= 1-this.pong_length )
184 {
185 if ( !pong_goal(minigame,this,4) )
186 {
187 this.origin_y = 1-this.pong_length;
188 this.velocity_y *= -1;
189 }
190 }
191
192 if ( this.origin_x <= this.pong_length )
193 {
194 if ( !pong_goal(minigame,this,2) )
195 {
196 this.origin_x = this.pong_length;
197 this.velocity_x *= -1;
198 }
199 }
200 else if ( this.origin_x >= 1-this.pong_length )
201 {
202 if ( !pong_goal(minigame,this,1) )
203 {
204 this.origin_x = 1-this.pong_length;
205 this.velocity_x *= -1;
206 }
207 }
208
209}
210
211// AI action
213{
215 this.nextthink = time + think_speed;
216
217 float distance;
218 float next_distance;
219 float min_distance = 1;
220 entity ball = NULL;
221 entity mayball = NULL;
222 while ( ( mayball = findfloat(mayball,minigame_id,this.minigame_id) ) )
223 if ( mayball.classname == "pong_ball" )
224 {
225 distance = vlen(mayball.origin-this.pong_ai_paddle.origin);
226 next_distance = vlen(mayball.origin+mayball.velocity-this.pong_ai_paddle.origin);
227 if ( distance < min_distance && ( distance < 0.5 || next_distance < distance ) )
228 {
229 min_distance = distance;
230 ball = mayball;
231 }
232 }
233
234 float target = 0.5;
235 float my_pos;
236
237
238 if ( this.team <= 2 )
239 {
240 if ( ball )
241 target = ball.origin_y + ball.velocity_y*think_speed;
242 my_pos = this.pong_ai_paddle.origin_y;
243 }
244 else
245 {
246 if ( ball )
247 target = ball.origin_x + ball.velocity_x*think_speed;
248 my_pos = this.pong_ai_paddle.origin_x;
249 }
250
253
254 if (target < my_pos - distance)
256 else if (target > my_pos + distance)
258 else
259 this.pong_keys = 0;
260}
261
263{
264 entity ai = msle_spawn(minigame,new(pong_ai));
265 ai.minigame_players = ai;
266 ai.team = paddle.team;
268 ai.nextthink = time;
269 ai.pong_ai_paddle = paddle;
270
271 paddle.realowner = ai;
272
273 return ai;
274}
275
276// Moves the paddle
278{
279 float think_speed = autocvar_sys_ticrate;
280 this.nextthink = time + think_speed;
281
282 if ( this.realowner.minigame_players.pong_keys == PONG_KEY_INCREASE ||
283 this.realowner.minigame_players.pong_keys == PONG_KEY_DECREASE )
284 {
285 float pmovement = autocvar_sv_minigames_pong_paddle_speed * think_speed;
286 float halflen = this.pong_length/2;
287
288 if ( this.realowner.minigame_players.pong_keys == PONG_KEY_DECREASE )
289 pmovement *= -1;
290
291 if ( this.team > 2 )
292 this.origin_x = bound(halflen, this.origin_x+pmovement, 1-halflen);
293 else
294 this.origin_y = bound(halflen, this.origin_y+pmovement, 1-halflen);
295
297 }
298}
299
300vector pong_team_to_box_halfsize(int nteam, float length, float width)
301{
302 if ( nteam > 2 )
303 return vec2(length/2, width/2);
304 return vec2(width/2, length/2);
305}
306
308{
309 switch(nteam)
310 {
311 case 1: return '0.99 0.5 0';
312 case 2: return '0.01 0.5 0';
313 case 3: return '0.5 0.01 0';
314 case 4: return '0.5 0.99 0';
315 default:return '0 0 0';
316 }
317}
318
319// Spawns a pong paddle
320// if real_player is NULL, the paddle is controlled by AI
321entity pong_paddle_spawn(entity minigame, int pl_team, entity real_player)
322{
323 entity paddle = msle_spawn(minigame,new(pong_paddle));
324 paddle.pong_length = autocvar_sv_minigames_pong_paddle_size;
325 paddle.origin = pong_team_to_paddlepos(pl_team);
327 paddle.nextthink = time;
328 paddle.team = pl_team;
329 paddle.m_mins = pong_team_to_box_halfsize(pl_team,-paddle.pong_length,-1/16);
330 paddle.m_maxs = pong_team_to_box_halfsize(pl_team,paddle.pong_length,1/16);
331
332 if ( real_player == NULL )
333 pong_ai_spawn(minigame, paddle);
334 else
335 paddle.realowner = real_player;
336
337 minigame.pong_paddles[pl_team-1] = paddle;
338
339 return paddle;
340
341}
342
343// required function, handle server side events
344int pong_server_event(entity minigame, string event, ...)
345{
346 switch (event)
347 {
348 case "start":
349 {
350 minigame.minigame_flags |= PONG_STATUS_WAIT;
351 return true;
352 }
353 case "join":
354 {
355 // Don't allow joining a match that is already running
356 if ( minigame.minigame_flags & PONG_STATUS_PLAY )
357 return PONG_SPECTATOR_TEAM;
358
359 entity player = ...(0,entity);
360 int i;
361 for ( i = 0; i < PONG_MAX_PLAYERS; ++i )
362 {
363 if ( minigame.pong_paddles[i] == NULL )
364 {
365 pong_paddle_spawn(minigame,i+1,player);
366 return i+1;
367 }
368 }
369
370 return PONG_SPECTATOR_TEAM;
371 }
372 case "part":
373 {
374 entity player = ...(0,entity);
375 entity paddle;
376 entity ai;
377 int i;
378 for ( i = 0; i < PONG_MAX_PLAYERS; ++i )
379 {
380 paddle = minigame.pong_paddles[i];
381 if ( paddle != NULL && paddle.realowner == player )
382 {
383 ai = pong_ai_spawn(minigame, paddle);
384 ai.pong_score = player.minigame_players.pong_score;
385 break;
386 }
387
388 }
389 return false;
390 }
391 case "cmd":
392 {
393 entity player = ...(0,entity);
394 bool event_blocked = (player.team == PONG_SPECTATOR_TEAM);
395 switch(argv(0))
396 {
397 case "throw":
398 if(event_blocked)
399 return true;
400 if ( minigame.minigame_flags & PONG_STATUS_WAIT )
401 {
402 minigame.minigame_flags = PONG_STATUS_PLAY |
403 (minigame.minigame_flags & ~PONG_STATUS_WAIT);
404 minigame.SendFlags |= MINIG_SF_UPDATE;
405
406 entity ball;
407 for ( int j = 0; j < autocvar_sv_minigames_pong_ball_number; ++j )
408 {
409 ball = msle_spawn(minigame,new(pong_ball));
411 ball.m_mins = vec2(-ball.pong_length, -ball.pong_length);
412 ball.m_maxs = vec2(ball.pong_length, ball.pong_length);
413 pong_ball_reset(ball);
414 }
415 }
416 return true;
417 case "+movei":
418 if(event_blocked)
419 return true;
420 player.pong_keys |= PONG_KEY_INCREASE;
421 return true;
422 case "+moved":
423 if(event_blocked)
424 return true;
425 player.pong_keys |= PONG_KEY_DECREASE;
426 return true;
427 case "-movei":
428 if(event_blocked)
429 return true;
430 player.pong_keys &= ~PONG_KEY_INCREASE;
431 return true;
432 case "-moved":
433 if(event_blocked)
434 return true;
435 player.pong_keys &= ~PONG_KEY_DECREASE;
436 return true;
437 case "move":
438 if(event_blocked)
439 return true;
440 if(argv(1))
441 player.pong_keys = stoi(argv(1));
442 return true;
443 case "pong_aimore":
444 {
445 if(event_blocked)
446 return true;
447 // keep declaration here, moving it into for() reverses weapon order
448 // potentially compiler bug
449 int j;
450 if ( minigame.minigame_flags & PONG_STATUS_WAIT )
451 for ( j = 0; j < PONG_MAX_PLAYERS; ++j )
452 //for ( int j = 0; j < PONG_MAX_PLAYERS; ++j )
453 {
454 if ( minigame.pong_paddles[j] == NULL )
455 {
456 pong_paddle_spawn(minigame,j+1,NULL);
457 return true;
458 }
459 }
460 sprint(player.minigame_players,"Cannot spawn AI\n");
461 return true;
462 }
463 case "pong_ailess":
464 {
465 if(event_blocked)
466 return true;
467 if ( minigame.minigame_flags & PONG_STATUS_WAIT )
468 {
469 entity paddle;
470 for ( int j = PONG_MAX_PLAYERS-1; j >= 0; --j )
471 {
472 paddle = minigame.pong_paddles[j];
473 if ( paddle != NULL &&
474 paddle.realowner.classname == "pong_ai" )
475 {
476 minigame.pong_paddles[j] = NULL;
477 delete(paddle.realowner);
478 delete(paddle);
479 return true;
480 }
481 }
482 }
483 sprint(player.minigame_players,"Cannot remove AI\n");
484 return true;
485 }
486
487 }
488 return false;
489 }
490 case "network_send":
491 {
492 entity sent = ...(0,entity);
493 int sf = ...(1,int);
494 if ( sent.classname == "minigame_player" && (sf & PONG_SF_PLAYERSCORE ) )
495 {
496 WriteLong(MSG_ENTITY,sent.pong_score);
497 }
498 return false;
499 }
500 }
501 return false;
502}
503
504
505#elif defined(CSQC)
506
507void drawrotpic(vector org, float rot, string pic, vector sz, vector hotspot, vector rgb, float a, float f);
508
509float pong_team_to_angle(int nteam)
510{
511 switch(nteam)
512 {
513 default:
514 case 1: return 0;
515 case 2: return M_PI;
516 case 3: return M_PI*3/2;
517 case 4: return M_PI/2;
518 }
519}
520
521vector pong_team_to_color(int nteam)
522{
523 switch(nteam)
524 {
525 case 1: return '1 0 0';
526 case 2: return '0 0 1';
527 case 3: return '1 1 0';
528 case 4: return '1 0 1';
529 default:return '1 1 1';
530 }
531}
532
533int pong_keys_pressed;
534int pong_keys_pressed_old;
535
536// Required function, draw the game board
537void pong_hud_board(vector pos, vector mySize)
538{
539 if(pong_keys_pressed != pong_keys_pressed_old)
540 minigame_cmd(strcat("move ", itos(pong_keys_pressed)));
541 pong_keys_pressed_old = pong_keys_pressed;
542
543 minigame_hud_fitsqare(pos, mySize);
544 minigame_hud_simpleboard(pos,mySize,minigame_texture("pong/board"));
545
546 entity e;
547 vector obj_pos;
548 vector obj_size;
550 {
551 if ( e.classname == "pong_ball" )
552 {
553 // Note: 4*radius = 2*diameter because the image is large enough to fit the glow around the ball
554 obj_size = minigame_hud_denormalize_size('4 4 0'*e.pong_length,pos,mySize);
555 obj_pos = minigame_hud_denormalize(e.origin,pos,mySize);
556
557 minigame_drawpic_centered( obj_pos, minigame_texture("pong/ball"),
558 obj_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL );
559
560 minigame_drawpic_centered( obj_pos, minigame_texture("pong/ball-glow"),
561 obj_size, pong_team_to_color(e.team),
563 }
564 else if ( e.classname == "pong_paddle" )
565 {
566 obj_pos = minigame_hud_denormalize(e.origin,pos,mySize);
567 obj_size = minigame_hud_denormalize_size(eX / 16 + eY*e.pong_length,pos,mySize);
568
569 drawrotpic(obj_pos, pong_team_to_angle(e.team), minigame_texture("pong/paddle-glow"),
570 obj_size, obj_size/2, pong_team_to_color(e.team),
572
573 drawrotpic(obj_pos, pong_team_to_angle(e.team), minigame_texture("pong/paddle"),
574 obj_size, obj_size/2, '1 1 1',
576
577 }
578 }
579
580 minigame_show_allspecs(pos, mySize);
581}
582
583// Required function, draw the game status panel
584void pong_hud_status(vector pos, vector mySize)
585{
587 vector ts = minigame_drawstring_wrapped(mySize_x,pos,active_minigame.descriptor.message,
588 hud_fontsize * 2, '0.25 0.47 0.72', panel_fg_alpha, DRAWFLAG_NORMAL,0.5);
589 ts_y += hud_fontsize_y;
590 pos_y += ts_y;
591 mySize_y -= ts_y;
592
593 vector player_fontsize = hud_fontsize * 1.75;
594 ts_y = ( mySize_y - PONG_MAX_PLAYERS*player_fontsize_y ) / PONG_MAX_PLAYERS;
595 ts_x = mySize_x;
596 vector mypos;
597
598 entity e;
600 {
601 if ( (e.classname == "minigame_player" || e.classname == "pong_ai") && e.team != PONG_SPECTATOR_TEAM )
602 {
603 mypos = pos;
604 mypos_y += (e.team-1) * (player_fontsize_y + ts_y);
605
606 drawfill(mypos, ts, pong_team_to_color(e.team), 0.25 * panel_fg_alpha, DRAWFLAG_ADDITIVE);
607
609 (e.minigame_playerslot ? entcs_GetName(e.minigame_playerslot-1) : _("AI")),
610 player_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
611
612 drawstring(mypos+eY*player_fontsize_y,ftos(e.pong_score),'48 48 0',
613 '0.7 0.84 1', panel_fg_alpha, DRAWFLAG_NORMAL);
614
615 if ( e == minigame_self )
616 drawborderlines(1, mypos, ts, pong_team_to_color(e.team), panel_fg_alpha, DRAWFLAG_NORMAL);
617 }
618 }
619}
620
621// convert minigame flags to a message
622string pong_message(int mgflags)
623{
624 string rmessage = "";
626 rmessage = _("You are spectating");
627 else if (mgflags & PONG_STATUS_WAIT)
628 rmessage = _("Press ^1Start Match^7 to start the match with the current players");
629 return rmessage;
630}
631
632// Required function, handle client events
633int pong_client_event(entity minigame, string event, ...)
634{
635 switch(event)
636 {
637 case "activate":
638 return false;
639 case "deactivate":
640 {
641 strfree(minigame.message);
642 return false;
643 }
644 case "key_pressed":
645 case "key_released":
646 if ((minigame.minigame_flags & PONG_STATUS_PLAY) && minigame_self.team != PONG_SPECTATOR_TEAM)
647 switch ( ...(0,int) )
648 {
649 case K_UPARROW:
650 case K_KP_UPARROW:
651 case K_LEFTARROW:
652 case K_KP_LEFTARROW:
653 if (event == "key_pressed")
654 {
655 //minigame_cmd("+moved");
656 pong_keys_pressed |= PONG_KEY_DECREASE;
657 }
658 else
659 {
660 //minigame_cmd("-moved");
661 pong_keys_pressed &= ~PONG_KEY_DECREASE;
662 }
663 return true;
664 case K_DOWNARROW:
665 case K_KP_DOWNARROW:
666 case K_RIGHTARROW:
667 case K_KP_RIGHTARROW:
668 if (event == "key_pressed")
669 {
670 //minigame_cmd("+movei");
671 pong_keys_pressed |= PONG_KEY_INCREASE;
672 }
673 else
674 {
675 //minigame_cmd("-movei");
676 pong_keys_pressed &= ~PONG_KEY_INCREASE;
677 }
678 return true;
679 }
680 return false;
681 case "network_receive":
682 {
683 entity sent = ...(0,entity);
684 int sf = ...(1,int);
685 if ( sent.classname == "minigame_player" && (sf & PONG_SF_PLAYERSCORE ) )
686 {
687 sent.pong_score = ReadLong();
688 }
689 else if ( sent.classname == "minigame" )
690 {
691 if ( sf & MINIG_SF_UPDATE )
692 {
693 strcpy(sent.message, pong_message(sent.minigame_flags));
694 }
695 }
696 return false;
697 }
698 case "menu_show":
699 {
700 HUD_MinigameMenu_CustomEntry(...(0,entity),_("Start Match"),"pong_throw");
701 HUD_MinigameMenu_CustomEntry(...(0,entity),_("Add AI player"),"pong_aimore");
702 HUD_MinigameMenu_CustomEntry(...(0,entity),_("Remove AI player"),"pong_ailess");
703 return false;
704 }
705 case "menu_click":
706 {
707 string cmd = ...(0,string);
708 if( cmd == "pong_throw" && ( minigame.minigame_flags & PONG_STATUS_WAIT ) )
709 {
710 minigame_cmd("throw");
711 }
712 else if ( cmd == "pong_aimore" || cmd == "pong_ailess" )
713 {
715 }
716 return false;
717 }
718 }
719
720 return false;
721}
722#endif
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
void minigame_drawcolorcodedstring_trunc(float maxwidth, vector pos, string text, vector fontsize, float theAlpha, int drawflags)
void minigame_show_allspecs(vector boardpos, vector boardsize)
vector minigame_drawstring_wrapped(float maxwidth, vector pos, string text, vector fontsize, vector color, float theAlpha, int drawflags, float align)
void minigame_hud_simpleboard(vector pos, vector mySize, string board_texture)
string minigame_texture(string name)
vector minigame_hud_denormalize_size(vector v, vector pos, vector mySize)
vector minigame_hud_denormalize(vector v, vector pos, vector mySize)
string() ReadString_Raw
void minigame_drawpic_centered(vector pos, string texture, vector sz, vector color, float thealpha, int drawflags)
#define REGISTER_MINIGAME(name, nicename)
entity minigame_self
entity active_minigame
#define minigame_hud_fitsqare(pos, mySize)
#define minigame_cmd(...)
#define FOREACH_MINIGAME_ENTITY(entityvar)
void HUD_MinigameMenu_CustomEntry(entity parent, string menumessage, string event_arg)
void drawborderlines(float thickness, vector pos, vector dim, vector color, float theAlpha, float drawflag)
Definition draw.qc:5
#define drawstring(position, text, scale, rgb, alpha, flag)
Definition draw.qh:27
#define drawfill(position, size, rgb, alpha, flag)
Definition draw.qh:36
vector hud_fontsize
Definition main.qh:77
entity owner
Definition main.qh:87
int team
Definition main.qh:188
const float DRAWFLAG_NORMAL
const float DRAWFLAG_ADDITIVE
float time
float nextthink
float speed
Definition dynlight.qc:9
string entcs_GetName(int i)
Definition ent_cs.qh:148
float panel_fg_alpha
Definition hud.qh:169
#define HUD_Panel_DrawBg()
Definition hud.qh:55
#define stoi(s)
Definition int.qh:4
#define itos(i)
Definition int.qh:6
float K_KP_RIGHTARROW
Definition keycodes.qc:60
float K_UPARROW
Definition keycodes.qc:15
float K_DOWNARROW
Definition keycodes.qc:16
float K_RIGHTARROW
Definition keycodes.qc:18
float K_KP_UPARROW
Definition keycodes.qc:64
float K_KP_LEFTARROW
Definition keycodes.qc:57
float K_KP_DOWNARROW
Definition keycodes.qc:53
float K_LEFTARROW
Definition keycodes.qc:17
#define int
Definition _all.inc:20
int SendFlags
Definition net.qh:159
const int MSG_ENTITY
Definition net.qh:156
float angle
Definition viewloc.qc:114
#define M_PI
pi
Definition mathlib.qh:114
float bound(float min, float value, float max)
void WriteLong(float data, float dest, float desto)
void sprint(float clientnum, string text,...)
float cos(float f)
float random(void)
float vlen(vector v)
void cmd(string command,...)
float sin(float f)
string ftos(float f)
float fabs(float f)
string argv(float n)
entity findfloat(entity start,.float field, float match)
entity msle_spawn(entity minigame_session, entity e)
Definition minigames.qc:96
int minigame_id
Unique ID for the minigame session, associated with all objects currently the result of etof(minigame...
Definition minigames.qh:49
const int MINIG_SF_UPDATE
Definition minigames.qh:113
const int MINIG_SF_CUSTOM
Definition minigames.qh:114
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
const int PONG_SF_BALLTEAM
Definition pong.qc:12
float autocvar_sv_minigames_pong_paddle_speed
Definition pong.qc:31
void pong_add_score(entity minigame, int team_thrower, int team_receiver, int delta)
Definition pong.qc:77
float autocvar_sv_minigames_pong_ball_number
Definition pong.qc:36
vector box_nearest(vector box_min, vector box_max, vector p)
Definition pong.qc:97
float autocvar_sv_minigames_pong_ball_wait
Definition pong.qc:33
void pong_ball_think(entity this)
Definition pong.qc:155
const int PONG_SF_PLAYERSCORE
Definition pong.qc:10
float autocvar_sv_minigames_pong_ball_radius
Definition pong.qc:35
int pong_server_event(entity minigame, string event,...)
Definition pong.qc:344
int pong_keys
Definition pong.qc:23
const int PONG_STATUS_PLAY
Definition pong.qc:6
void pong_ball_throwthink(entity this)
Definition pong.qc:59
const int PONG_KEY_INCREASE
Definition pong.qc:15
entity pong_ai_paddle
Definition pong.qc:26
entity pong_paddle_spawn(entity minigame, int pl_team, entity real_player)
Definition pong.qc:321
float autocvar_sv_minigames_pong_ball_speed
Definition pong.qc:34
int pong_score
Definition pong.qc:22
const int PONG_KEY_BOTH
Definition pong.qc:17
const int PONG_SPECTATOR_TEAM
Definition pong.qc:21
float autocvar_sv_minigames_pong_ai_thinkspeed
Definition pong.qc:38
const int PONG_STATUS_WAIT
Definition pong.qc:5
const int PONG_MAX_PLAYERS
Definition pong.qc:20
void pong_ball_reset(entity ball)
Definition pong.qc:65
vector pong_team_to_paddlepos(int nteam)
Definition pong.qc:307
float autocvar_sv_minigames_pong_paddle_size
Definition pong.qc:30
void pong_paddle_think(entity this)
Definition pong.qc:277
void pong_ball_throw(entity ball)
Definition pong.qc:44
void pong_ai_think(entity this)
Definition pong.qc:212
bool pong_goal(entity minigame, entity ball, int pteam)
Definition pong.qc:138
const int PONG_KEY_DECREASE
Definition pong.qc:16
bool pong_paddle_hit(entity minigame, entity ball, int pteam)
Definition pong.qc:122
entity pong_ai_spawn(entity minigame, entity paddle)
Definition pong.qc:262
void pong_paddle_bounce(entity ball, int pteam)
Definition pong.qc:103
float autocvar_sv_minigames_pong_ai_tolerance
Definition pong.qc:39
entity pong_paddles[PONG_MAX_PLAYERS]
Definition pong.qc:24
vector pong_team_to_box_halfsize(int nteam, float length, float width)
Definition pong.qc:300
float pong_length
Definition pong.qc:25
#define NULL
Definition post.qh:14
#define setthink(e, f)
vector
Definition self.qh:96
vector org
Definition self.qh:96
float autocvar_sys_ticrate
Definition main.qh:17
#define strfree(this)
Definition string.qh:57
#define strcpy(this, s)
Definition string.qh:51
void SUB_NullThink(entity this)
Definition subs.qc:3
entity realowner
string target
Definition triggers.qh:55
const vector eY
Definition vector.qh:44
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt().
Definition vector.qh:8
ERASEABLE float boxesoverlap(vector m1, vector m2, vector m3, vector m4)
Requires that m2>m1 in all coordinates, and that m4>m3.
Definition vector.qh:72
const vector eX
Definition vector.qh:43
#define vec2(...)
Definition vector.qh:95
void drawrotpic(vector org, float rot, string pic, vector sz, vector hotspot, vector rgb, float a, float f)