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 ball, int pteam)
123{
124 entity paddle = ball.owner.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 ball, int pteam)
139{
140 entity paddle = ball.owner.pong_paddles[pteam-1];
141 if (!paddle)
142 return false;
143
144 if ( !pong_paddle_hit(ball, pteam) )
145 {
146 pong_add_score(ball.owner ,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 float think_speed = autocvar_sys_ticrate;
158 this.nextthink = time + think_speed;
159
160 this.origin_x += this.velocity_x * think_speed;
161 this.origin_y += this.velocity_y * think_speed;
163
164 int i;
165 for ( i = 1; i <= PONG_MAX_PLAYERS; ++i )
166 if ( pong_paddle_hit(this, i) )
167 {
168 pong_paddle_bounce(this,i);
169 this.team = i;
171 return;
172 }
173
174 if ( this.origin_y <= this.pong_length )
175 {
176 if ( !pong_goal(this,3) )
177 {
178 this.origin_y = this.pong_length;
179 this.velocity_y *= -1;
180 }
181 }
182 else if ( this.origin_y >= 1-this.pong_length )
183 {
184 if ( !pong_goal(this,4) )
185 {
186 this.origin_y = 1-this.pong_length;
187 this.velocity_y *= -1;
188 }
189 }
190
191 if ( this.origin_x <= this.pong_length )
192 {
193 if ( !pong_goal(this,2) )
194 {
195 this.origin_x = this.pong_length;
196 this.velocity_x *= -1;
197 }
198 }
199 else if ( this.origin_x >= 1-this.pong_length )
200 {
201 if ( !pong_goal(this,1) )
202 {
203 this.origin_x = 1-this.pong_length;
204 this.velocity_x *= -1;
205 }
206 }
207
208}
209
210// AI action
212{
214 this.nextthink = time + think_speed;
215
216 float distance;
217 float next_distance;
218 float min_distance = 1;
219 entity ball = NULL;
220 entity mayball = NULL;
221 while ( ( mayball = findentity(mayball,owner,this.owner) ) )
222 if ( mayball.classname == "pong_ball" )
223 {
224 distance = vlen(mayball.origin-this.pong_ai_paddle.origin);
225 next_distance = vlen(mayball.origin+mayball.velocity-this.pong_ai_paddle.origin);
226 if ( distance < min_distance && ( distance < 0.5 || next_distance < distance ) )
227 {
228 min_distance = distance;
229 ball = mayball;
230 }
231 }
232
233 float target = 0.5;
234 float my_pos;
235
236
237 if ( this.team <= 2 )
238 {
239 if ( ball )
240 target = ball.origin_y + ball.velocity_y*think_speed;
241 my_pos = this.pong_ai_paddle.origin_y;
242 }
243 else
244 {
245 if ( ball )
246 target = ball.origin_x + ball.velocity_x*think_speed;
247 my_pos = this.pong_ai_paddle.origin_x;
248 }
249
252
253 if (target < my_pos - distance)
255 else if (target > my_pos + distance)
257 else
258 this.pong_keys = 0;
259}
260
262{
263 entity ai = msle_spawn(paddle.owner,new(pong_ai));
264 ai.minigame_players = ai;
265 ai.team = paddle.team;
267 ai.nextthink = time;
268 ai.pong_ai_paddle = paddle;
269
270 paddle.realowner = ai;
271
272 return ai;
273}
274
275// Moves the paddle
277{
278 float think_speed = autocvar_sys_ticrate;
279 this.nextthink = time + think_speed;
280
281 if ( this.realowner.minigame_players.pong_keys == PONG_KEY_INCREASE ||
282 this.realowner.minigame_players.pong_keys == PONG_KEY_DECREASE )
283 {
284 float pmovement = autocvar_sv_minigames_pong_paddle_speed * think_speed;
285 float halflen = this.pong_length/2;
286
287 if ( this.realowner.minigame_players.pong_keys == PONG_KEY_DECREASE )
288 pmovement *= -1;
289
290 if ( this.team > 2 )
291 this.origin_x = bound(halflen, this.origin_x+pmovement, 1-halflen);
292 else
293 this.origin_y = bound(halflen, this.origin_y+pmovement, 1-halflen);
294
296 }
297}
298
299vector pong_team_to_box_halfsize(int nteam, float length, float width)
300{
301 if ( nteam > 2 )
302 return vec2(length/2, width/2);
303 return vec2(width/2, length/2);
304}
305
307{
308 switch(nteam)
309 {
310 case 1: return '0.99 0.5 0';
311 case 2: return '0.01 0.5 0';
312 case 3: return '0.5 0.01 0';
313 case 4: return '0.5 0.99 0';
314 default:return '0 0 0';
315 }
316}
317
318// Spawns a pong paddle
319// if real_player is NULL, the paddle is controlled by AI
320entity pong_paddle_spawn(entity minigame, int pl_team, entity real_player)
321{
322 entity paddle = msle_spawn(minigame,new(pong_paddle));
323 paddle.pong_length = autocvar_sv_minigames_pong_paddle_size;
324 paddle.origin = pong_team_to_paddlepos(pl_team);
326 paddle.nextthink = time;
327 paddle.team = pl_team;
328 paddle.m_mins = pong_team_to_box_halfsize(pl_team,-paddle.pong_length,-1/16);
329 paddle.m_maxs = pong_team_to_box_halfsize(pl_team,paddle.pong_length,1/16);
330
331 if ( real_player == NULL )
332 pong_ai_spawn(paddle);
333 else
334 paddle.realowner = real_player;
335
336 minigame.pong_paddles[pl_team-1] = paddle;
337
338 return paddle;
339
340}
341
342// required function, handle server side events
343int pong_server_event(entity minigame, string event, ...)
344{
345 switch (event)
346 {
347 case "start":
348 {
349 minigame.minigame_flags |= PONG_STATUS_WAIT;
350 return true;
351 }
352 case "join":
353 {
354 // Don't allow joining a match that is already running
355 if ( minigame.minigame_flags & PONG_STATUS_PLAY )
356 return PONG_SPECTATOR_TEAM;
357
358 entity player = ...(0,entity);
359 int i;
360 for ( i = 0; i < PONG_MAX_PLAYERS; ++i )
361 {
362 if ( minigame.pong_paddles[i] == NULL )
363 {
364 pong_paddle_spawn(minigame,i+1,player);
365 return i+1;
366 }
367 }
368
369 return PONG_SPECTATOR_TEAM;
370 }
371 case "part":
372 {
373 entity player = ...(0,entity);
374 entity paddle;
375 entity ai;
376 int i;
377 for ( i = 0; i < PONG_MAX_PLAYERS; ++i )
378 {
379 paddle = minigame.pong_paddles[i];
380 if ( paddle != NULL && paddle.realowner == player )
381 {
382 ai = pong_ai_spawn(paddle);
383 ai.pong_score = player.minigame_players.pong_score;
384 break;
385 }
386
387 }
388 return false;
389 }
390 case "cmd":
391 {
392 entity player = ...(0,entity);
393 bool event_blocked = (player.team == PONG_SPECTATOR_TEAM);
394 switch(argv(0))
395 {
396 case "throw":
397 if(event_blocked)
398 return true;
399 if ( minigame.minigame_flags & PONG_STATUS_WAIT )
400 {
401 minigame.minigame_flags = PONG_STATUS_PLAY |
402 (minigame.minigame_flags & ~PONG_STATUS_WAIT);
403 minigame.SendFlags |= MINIG_SF_UPDATE;
404
405 entity ball;
406 for ( int j = 0; j < autocvar_sv_minigames_pong_ball_number; ++j )
407 {
408 ball = msle_spawn(minigame,new(pong_ball));
410 ball.m_mins = vec2(-ball.pong_length, -ball.pong_length);
411 ball.m_maxs = vec2(ball.pong_length, ball.pong_length);
412 pong_ball_reset(ball);
413 }
414 }
415 return true;
416 case "+movei":
417 if(event_blocked)
418 return true;
419 player.pong_keys |= PONG_KEY_INCREASE;
420 return true;
421 case "+moved":
422 if(event_blocked)
423 return true;
424 player.pong_keys |= PONG_KEY_DECREASE;
425 return true;
426 case "-movei":
427 if(event_blocked)
428 return true;
429 player.pong_keys &= ~PONG_KEY_INCREASE;
430 return true;
431 case "-moved":
432 if(event_blocked)
433 return true;
434 player.pong_keys &= ~PONG_KEY_DECREASE;
435 return true;
436 case "move":
437 if(event_blocked)
438 return true;
439 if(argv(1))
440 player.pong_keys = stoi(argv(1));
441 return true;
442 case "pong_aimore":
443 {
444 if(event_blocked)
445 return true;
446 // keep declaration here, moving it into for() reverses weapon order
447 // potentially compiler bug
448 int j;
449 if ( minigame.minigame_flags & PONG_STATUS_WAIT )
450 for ( j = 0; j < PONG_MAX_PLAYERS; ++j )
451 //for ( int j = 0; j < PONG_MAX_PLAYERS; ++j )
452 {
453 if ( minigame.pong_paddles[j] == NULL )
454 {
455 pong_paddle_spawn(minigame,j+1,NULL);
456 return true;
457 }
458 }
459 sprint(player.minigame_players,"Cannot spawn AI\n");
460 return true;
461 }
462 case "pong_ailess":
463 {
464 if(event_blocked)
465 return true;
466 if ( minigame.minigame_flags & PONG_STATUS_WAIT )
467 {
468 entity paddle;
469 for ( int j = PONG_MAX_PLAYERS-1; j >= 0; --j )
470 {
471 paddle = minigame.pong_paddles[j];
472 if ( paddle != NULL &&
473 paddle.realowner.classname == "pong_ai" )
474 {
475 minigame.pong_paddles[j] = NULL;
476 delete(paddle.realowner);
477 delete(paddle);
478 return true;
479 }
480 }
481 }
482 sprint(player.minigame_players,"Cannot remove AI\n");
483 return true;
484 }
485
486 }
487 return false;
488 }
489 case "network_send":
490 {
491 entity sent = ...(0,entity);
492 int sf = ...(1,int);
493 if ( sent.classname == "minigame_player" && (sf & PONG_SF_PLAYERSCORE ) )
494 {
495 WriteLong(MSG_ENTITY,sent.pong_score);
496 }
497 return false;
498 }
499 }
500 return false;
501}
502
503
504#elif defined(CSQC)
505
506void drawrotpic(vector org, float rot, string pic, vector sz, vector hotspot, vector rgb, float a, float f);
507
508float pong_team_to_angle(int nteam)
509{
510 switch(nteam)
511 {
512 default:
513 case 1: return 0;
514 case 2: return M_PI;
515 case 3: return M_PI*3/2;
516 case 4: return M_PI/2;
517 }
518}
519
520vector pong_team_to_color(int nteam)
521{
522 switch(nteam)
523 {
524 case 1: return '1 0 0';
525 case 2: return '0 0 1';
526 case 3: return '1 1 0';
527 case 4: return '1 0 1';
528 default:return '1 1 1';
529 }
530}
531
532int pong_keys_pressed;
533int pong_keys_pressed_old;
534
535// Required function, draw the game board
536void pong_hud_board(vector pos, vector mySize)
537{
538 if(pong_keys_pressed != pong_keys_pressed_old)
539 minigame_cmd(strcat("move ", itos(pong_keys_pressed)));
540 pong_keys_pressed_old = pong_keys_pressed;
541
542 minigame_hud_fitsqare(pos, mySize);
543 minigame_hud_simpleboard(pos,mySize,minigame_texture("pong/board"));
544
545 entity e;
546 vector obj_pos;
547 vector obj_size;
549 {
550 if ( e.classname == "pong_ball" )
551 {
552 // Note: 4*radius = 2*diameter because the image is large enough to fit the glow around the ball
553 obj_size = minigame_hud_denormalize_size('4 4 0'*e.pong_length,pos,mySize);
554 obj_pos = minigame_hud_denormalize(e.origin,pos,mySize);
555
556 minigame_drawpic_centered( obj_pos, minigame_texture("pong/ball"),
557 obj_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL );
558
559 minigame_drawpic_centered( obj_pos, minigame_texture("pong/ball-glow"),
560 obj_size, pong_team_to_color(e.team),
562 }
563 else if ( e.classname == "pong_paddle" )
564 {
565 obj_pos = minigame_hud_denormalize(e.origin,pos,mySize);
566 obj_size = minigame_hud_denormalize_size(eX / 16 + eY*e.pong_length,pos,mySize);
567
568 drawrotpic(obj_pos, pong_team_to_angle(e.team), minigame_texture("pong/paddle-glow"),
569 obj_size, obj_size/2, pong_team_to_color(e.team),
571
572 drawrotpic(obj_pos, pong_team_to_angle(e.team), minigame_texture("pong/paddle"),
573 obj_size, obj_size/2, '1 1 1',
575
576 }
577 }
578
579 minigame_show_allspecs(pos, mySize);
580}
581
582// Required function, draw the game status panel
583void pong_hud_status(vector pos, vector mySize)
584{
586 vector ts;
587 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), 1, 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:151
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:118
const int MSG_ENTITY
Definition net.qh:115
float angle
Definition viewloc.qc:114
#define M_PI
Definition mathlib.qh:108
entity findentity(entity start,.entity field, entity match)
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 msle_spawn(entity minigame_session, entity e)
Definition minigames.qc:87
const int MINIG_SF_UPDATE
Definition minigames.qh:109
const int MINIG_SF_CUSTOM
Definition minigames.qh:110
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
bool pong_goal(entity ball, int pteam)
Definition pong.qc:138
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:343
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:320
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
entity pong_ai_spawn(entity paddle)
Definition pong.qc:261
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:306
float autocvar_sv_minigames_pong_paddle_size
Definition pong.qc:30
void pong_paddle_think(entity this)
Definition pong.qc:276
void pong_ball_throw(entity ball)
Definition pong.qc:44
void pong_ai_think(entity this)
Definition pong.qc:211
const int PONG_KEY_DECREASE
Definition pong.qc:16
bool pong_paddle_hit(entity ball, int pteam)
Definition pong.qc:122
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:299
float pong_length
Definition pong.qc:25
#define NULL
Definition post.qh:14
#define setthink(e, f)
vector
Definition self.qh:92
vector org
Definition self.qh:92
float autocvar_sys_ticrate
Definition main.qh:17
#define strfree(this)
Definition string.qh:59
#define strcpy(this, s)
Definition string.qh:52
void SUB_NullThink(entity this)
Definition subs.qc:3
entity realowner
string target
Definition triggers.qh:55
const vector eY
Definition vector.qh:45
#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:73
const vector eX
Definition vector.qh:44
#define vec2(...)
Definition vector.qh:90
void drawrotpic(vector org, float rot, string pic, vector sz, vector hotspot, vector rgb, float a, float f)