Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
sv_minigames.qc File Reference
Include dependency graph for sv_minigames.qc:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define FIELD(Flags, Type, Name)
#define MINIGAME_CMD(cmd_id)
#define MSLE(Name, Fields)

Functions

void ClientCommand_minigame (entity caller, int request, int argc, string command)
void end_minigame (entity minigame_session)
void end_minigames ()
string invite_minigame (entity inviter, entity player)
 Invite a player to join in a minigame.
entity join_minigame (entity player, string game_id)
 Join an existing minigame session.
int minigame_addplayer (entity minigame_session, entity player)
bool minigame_CheckSend (entity this, entity client)
entity minigame_find_player (entity client)
void minigame_resend (entity minigame)
void minigame_rmplayer (entity minigame_session, entity player)
bool minigame_SendEntity (entity this, entity to, int sf)
bool MinigameImpulse (entity this, int imp)
void part_minigame (entity player)
void player_clear_minigame (entity player)
entity start_minigame (entity player, string minigame)
 Create a new minigame session.

Macro Definition Documentation

◆ FIELD

#define FIELD ( Flags,
Type,
Name )
Value:
if ( sf & (Flags) ) Write##Type(MSG_ENTITY, this.Name);
const int MSG_ENTITY
Definition net.qh:115

Definition at line 56 of file sv_minigames.qc.

◆ MINIGAME_CMD

#define MINIGAME_CMD ( cmd_id)
Value:
MINIGAME_COMMON_CMD[MINIGAME_COMMON_CMD_ID_##cmd_id]
string MINIGAME_COMMON_CMD[MINIGAME_COMMON_CMD_COUNT]

Definition at line 308 of file sv_minigames.qc.

Referenced by ClientCommand_minigame().

◆ MSLE

#define MSLE ( Name,
Fields )
Value:
else if ( this.classname == #Name ) { \
if ( sf & MINIG_SF_CREATE ) WriteString(MSG_ENTITY,this.owner.netname); \
Fields }
entity owner
Definition main.qh:87
string classname
void WriteString(string data, float dest, float desto)
const int MINIG_SF_CREATE
Definition minigames.qh:108

Definition at line 57 of file sv_minigames.qc.

57#define MSLE(Name,Fields) \
58 else if ( this.classname == #Name ) { \
59 if ( sf & MINIG_SF_CREATE ) WriteString(MSG_ENTITY,this.owner.netname); \
60 Fields }

Function Documentation

◆ ClientCommand_minigame()

void ClientCommand_minigame ( entity caller,
int request,
int argc,
string command )

Definition at line 310 of file sv_minigames.qc.

311{
313 {
314 sprint(caller,"Minigames are not enabled!\n");
315 return;
316 }
317
319 {
320 Send_Notification(NOTIF_ONE_ONLY, caller, MSG_CENTER, CENTER_JOIN_PLAYBAN);
321 sprint(caller, "You aren't allowed to play minigames because you are banned from them in this server.\n");
322 return;
323 }
324
325 if (request == CMD_REQUEST_COMMAND )
326 {
327 string minig_cmd = argv(1);
328 if ( minig_cmd == MINIGAME_CMD(CREATE) && argc > 2 )
329 {
330 entity minig = start_minigame(caller, argv(2));
331 if ( minig )
332 sprint(caller,"Created minigame session: ",minig.netname,"\n");
333 else
334 sprint(caller,"Cannot start minigame session!\n");
335 return;
336 }
337 else if ( minig_cmd == MINIGAME_CMD(JOIN) && argc > 2 )
338 {
339 entity minig = join_minigame(caller, argv(2));
340 if ( minig )
341 sprint(caller,"Joined: ",minig.netname,"\n");
342 else
343 {
344 Send_Notification(NOTIF_ONE, caller, MSG_CENTER, CENTER_JOIN_PREVENT_MINIGAME);
345 sprint(caller,"Cannot join given minigame session!\n");
346 }
347 return;
348 }
349 else if ( minig_cmd == MINIGAME_CMD(LIST) )
350 {
351 FOREACH(Minigames, true, sprint(caller, it.netname, " (", it.message, ") ", "\n"));
352 return;
353 }
354 else if ( minig_cmd == MINIGAME_CMD(LIST_SESSIONS) )
355 {
356 entity e;
357 for ( e = minigame_sessions; e != NULL; e = e.list_next )
358 sprint(caller,e.netname,"\n");
359 return;
360 }
361 else if ( minig_cmd == MINIGAME_CMD(END) || minig_cmd == MINIGAME_CMD(PART) )
362 {
363 if ( CS(caller).active_minigame )
364 {
365 part_minigame(caller);
366 sprint(caller,"Left minigame session\n");
367 }
368 else
369 sprint(caller,"You aren't playing any minigame...\n");
370 return;
371 }
372 else if ( minig_cmd == MINIGAME_CMD(INVITE) && argc > 2 )
373 {
374 if ( CS(caller).active_minigame )
375 {
376 entity client = GetIndexedEntity(argc, 2);
377 string error = invite_minigame(caller,client);
378 if ( error == "" )
379 {
380 sprint(caller,"You have invited ",client.netname,
381 " to join your game of ", CS(caller).active_minigame.descriptor.message, "\n");
382 }
383 else
384 sprint(caller,"Could not invite: ", error, ".\n");
385 }
386 else
387 sprint(caller,"You aren't playing any minigame...\n");
388 return;
389 }
390 else if ( CS(caller).active_minigame )
391 {
392 entity e = minigame_find_player(caller);
393 string subcommand = substring(command,argv_end_index(0),-1);
394 int arg_c = tokenize_console(subcommand);
395 if ( CS(caller).active_minigame.minigame_event(CS(caller).active_minigame,"cmd",e,arg_c,subcommand) )
396 return;
397
398 }
399 else sprint(caller,strcat("Wrong command:^1 ",command,"\n"));
400 }
401
402 sprint(caller, "\nUsage:^3 cmd minigame create <minigame>\n");
403 sprint(caller, " Start a new minigame session\n");
404 sprint(caller, "Usage:^3 cmd minigame join <session>\n");
405 sprint(caller, " Join an exising minigame session\n");
406 sprint(caller, "Usage:^3 cmd minigame list\n");
407 sprint(caller, " List available minigames\n");
408 sprint(caller, "Usage:^3 cmd minigame list-sessions\n");
409 sprint(caller, " List available minigames sessions\n");
410 sprint(caller, "Usage:^3 cmd minigame part|end\n");
411 sprint(caller, " Leave the current minigame\n");
412 sprint(caller, "Usage:^3 cmd minigame invite <player>\n");
413 sprint(caller, " Invite the given player to join you in a minigame\n");
414}
string autocvar_g_playban_list
Definition banning.qh:14
bool autocvar_g_playban_minigames
Definition banning.qh:15
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
entity active_minigame
const int CMD_REQUEST_COMMAND
Definition command.qh:3
#define argv_end_index
#define tokenize_console
#define FOREACH(list, cond, body)
Definition iter.qh:19
string substring(string s, float start, float length)
void sprint(float clientnum, string text,...)
string argv(float n)
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
Definition all.qc:1573
#define NULL
Definition post.qh:14
#define error
Definition pre.qh:6
bool PlayerInList(entity player, string list)
Definition client.qc:1045
entity GetIndexedEntity(int argc, int start_index)
Definition common.qc:82
ClientState CS(Client this)
Definition state.qh:47
#define MINIGAME_CMD(cmd_id)
entity join_minigame(entity player, string game_id)
Join an existing minigame session.
void part_minigame(entity player)
entity start_minigame(entity player, string minigame)
Create a new minigame session.
string invite_minigame(entity inviter, entity player)
Invite a player to join in a minigame.
entity minigame_find_player(entity client)
entity minigame_sessions
bool autocvar_sv_minigames

References active_minigame, argv(), argv_end_index, autocvar_g_playban_list, autocvar_g_playban_minigames, autocvar_sv_minigames, CMD_REQUEST_COMMAND, CS(), entity(), error, FOREACH, GetIndexedEntity(), invite_minigame(), join_minigame(), MINIGAME_CMD, minigame_find_player(), minigame_sessions, NULL, part_minigame(), PlayerInList(), Send_Notification(), sprint(), start_minigame(), strcat(), substring(), and tokenize_console.

Referenced by CLIENT_COMMAND().

◆ end_minigame()

void end_minigame ( entity minigame_session)

Definition at line 224 of file sv_minigames.qc.

225{
226 if ( minigame_session.owner )
227 minigame_session.owner.list_next = minigame_session.list_next;
228 else
229 minigame_sessions = minigame_session.list_next;
230
231 minigame_session.minigame_event(minigame_session,"end");
232 GameLogEcho(strcat(":minigame:end:",minigame_session.netname));
233
234
235 entity e = NULL;
236 while( (e = findentity(e, owner, minigame_session)) )
237 if ( e.minigame_autoclean )
238 {
239 LOG_TRACE("SV Auto-cleaned: ",ftos(etof(e)), " (",e.classname,")");
240 delete(e);
241 }
242
243 entity p;
244 for ( e = minigame_session.minigame_players; e != NULL; e = p )
245 {
246 p = e.list_next;
247 player_clear_minigame(e.minigame_players);
248 delete(e);
249 }
250
251 strfree(minigame_session.netname);
252 delete(minigame_session);
253}
void GameLogEcho(string s)
Definition gamelog.qc:15
#define LOG_TRACE(...)
Definition log.qh:76
entity findentity(entity start,.entity field, entity match)
string ftos(float f)
#define etof(e)
Definition misc.qh:25
#define strfree(this)
Definition string.qh:59
void player_clear_minigame(entity player)

References entity(), etof, findentity(), ftos(), GameLogEcho(), LOG_TRACE, minigame_sessions, NULL, owner, player_clear_minigame(), strcat(), and strfree.

Referenced by end_minigames(), minigame_rmplayer(), and start_minigame().

◆ end_minigames()

void end_minigames ( )

Definition at line 255 of file sv_minigames.qc.

256{
257 while ( minigame_sessions )
258 {
260 }
261}
void end_minigame(entity minigame_session)

References end_minigame(), and minigame_sessions.

◆ invite_minigame()

string invite_minigame ( entity inviter,
entity player )

Invite a player to join in a minigame.

Returns
Error string

Definition at line 263 of file sv_minigames.qc.

264{
265 if ( !inviter || !CS(inviter).active_minigame )
266 return "Invalid minigame";
267 if ( VerifyClientEntity(player, true, false) <= 0 )
268 return "Invalid player";
269 if ( inviter == player )
270 return "You can't invite yourself";
272 return "You can't invite a banned player";
273 if ( CS(player).active_minigame == CS(inviter).active_minigame )
274 return strcat(player.netname," is already playing");
275
276 Send_Notification(NOTIF_ONE, player, MSG_INFO, INFO_MINIGAME_INVITE,
277 CS(inviter).active_minigame.netname, inviter.netname );
278
279 GameLogEcho(strcat(":minigame:invite:",CS(inviter).active_minigame.netname,":",
280 ftos(etof(player)),":",player.netname));
281
282 return "";
283}
int VerifyClientEntity(entity client, bool must_be_real, bool must_be_bots)
Definition common.qc:47

References active_minigame, autocvar_g_playban_list, autocvar_g_playban_minigames, CS(), entity(), etof, ftos(), GameLogEcho(), PlayerInList(), Send_Notification(), strcat(), and VerifyClientEntity().

Referenced by ClientCommand_minigame().

◆ join_minigame()

entity join_minigame ( entity player,
string game_id )

Join an existing minigame session.

Returns
minigame session entity

Definition at line 200 of file sv_minigames.qc.

201{
202 if ( !autocvar_sv_minigames || !IS_REAL_CLIENT(player) )
203 return NULL;
204
205 entity minig;
206 for ( minig = minigame_sessions; minig != NULL; minig = minig.list_next )
207 {
208 if ( minig.netname == game_id )
209 if ( minigame_addplayer(minig,player) )
210 return minig;
211 }
212
213 return NULL;
214}
int minigame_addplayer(entity minigame_session, entity player)
#define IS_REAL_CLIENT(v)
Definition utils.qh:17

References autocvar_sv_minigames, entity(), IS_REAL_CLIENT, minigame_addplayer(), minigame_sessions, and NULL.

Referenced by ClientCommand_minigame().

◆ minigame_addplayer()

int minigame_addplayer ( entity minigame_session,
entity player )

Definition at line 127 of file sv_minigames.qc.

128{
129 if ( CS(player).active_minigame )
130 {
131 if ( CS(player).active_minigame == minigame_session )
132 return 0;
133 minigame_rmplayer(CS(player).active_minigame,player);
134 }
135 entity player_pointer = new(minigame_player);
136 int mgteam = minigame_session.minigame_event(minigame_session,"join",player,player_pointer);
137
138 if ( mgteam )
139 {
140 player_pointer.owner = minigame_session;
141 player_pointer.minigame_players = player;
142 player_pointer.team = mgteam;
143 player_pointer.list_next = minigame_session.minigame_players;
144 minigame_session.minigame_players = player_pointer;
145 CS(player).active_minigame = minigame_session;
146 player.minigame_players = player_pointer;
147 setcefc(player_pointer, minigame_CheckSend);
148 Net_LinkEntity(player_pointer, false, 0, minigame_SendEntity);
149
151 PutObserverInServer(player, true, true);
154
155 minigame_resend(minigame_session);
156 }
157 else { delete(player_pointer); }
158 GameLogEcho(strcat(":minigame:join",(mgteam?"":"fail"),":",minigame_session.netname,":",
159 ftos(etof(player)),":",player.netname));
160
161 return mgteam;
162}
void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
Definition net.qh:123
#define setcefc(e, f)
void PutObserverInServer(entity this, bool is_forced, bool use_spawnpoint)
putting a client as observer in the server
Definition client.qc:261
bool minigame_CheckSend(entity this, entity client)
void minigame_rmplayer(entity minigame_session, entity player)
bool minigame_SendEntity(entity this, entity to, int sf)
void minigame_resend(entity minigame)
bool autocvar_sv_minigames_observer
void Player_SetForcedTeamIndex(entity player, int team_index)
Sets the index of the forced team of the given player.
Definition teamplay.qc:323
@ TEAM_FORCE_SPECTATOR
Force the player to spectator team.
Definition teamplay.qh:137
#define IS_OBSERVER(v)
Definition utils.qh:11

References active_minigame, autocvar_sv_minigames_observer, CS(), entity(), etof, ftos(), GameLogEcho(), IS_OBSERVER, minigame_CheckSend(), minigame_resend(), minigame_rmplayer(), minigame_SendEntity(), Net_LinkEntity(), Player_SetForcedTeamIndex(), PutObserverInServer(), setcefc, strcat(), and TEAM_FORCE_SPECTATOR.

Referenced by join_minigame(), and start_minigame().

◆ minigame_CheckSend()

bool minigame_CheckSend ( entity this,
entity client )

Definition at line 118 of file sv_minigames.qc.

119{
120 entity e;
121 for ( e = this.owner.minigame_players; e != NULL; e = e.list_next )
122 if ( e.minigame_players == client )
123 return true;
124 return false;
125}

References entity(), NULL, and owner.

Referenced by minigame_addplayer(), and msle_spawn().

◆ minigame_find_player()

entity minigame_find_player ( entity client)

Definition at line 285 of file sv_minigames.qc.

286{
287 if ( ! CS(client).active_minigame )
288 return NULL;
289 entity e;
290 for ( e = CS(client).active_minigame.minigame_players; e; e = e.list_next )
291 if ( e.minigame_players == client )
292 return e;
293 return NULL;
294}

References active_minigame, CS(), entity(), and NULL.

Referenced by ClientCommand_minigame(), and MinigameImpulse().

◆ minigame_resend()

void minigame_resend ( entity minigame)

Definition at line 108 of file sv_minigames.qc.

109{
110 minigame.SendFlags = MINIG_SF_ALL;
111 entity e = NULL;
112 while (( e = findentity(e,owner,minigame) ))
113 {
114 e.SendFlags = MINIG_SF_ALL;
115 }
116}
const int MINIG_SF_ALL
Definition minigames.qh:112

References entity(), findentity(), MINIG_SF_ALL, NULL, and owner.

Referenced by minigame_addplayer().

◆ minigame_rmplayer()

void minigame_rmplayer ( entity minigame_session,
entity player )

Definition at line 17 of file sv_minigames.qc.

18{
19 entity e;
20 entity p = minigame_session.minigame_players;
21
22 if ( p.minigame_players == player )
23 {
24 if ( p.list_next == NULL )
25 {
26 end_minigame(minigame_session);
27 return;
28 }
29 minigame_session.minigame_event(minigame_session,"part",player);
30 GameLogEcho(strcat(":minigame:part:",minigame_session.netname,":",
31 ftos(etof(player)),":",player.netname));
32 minigame_session.minigame_players = p.list_next;
33 delete( p );
35 }
36 else
37 {
38 for ( e = p.list_next; e != NULL; e = e.list_next )
39 {
40 if ( e.minigame_players == player )
41 {
42 minigame_session.minigame_event(minigame_session,"part",player);
43 GameLogEcho(strcat(":minigame:part:",minigame_session.netname,":",
44 ftos(etof(player)),":",player.netname));
45 p.list_next = e.list_next;
46 delete(e);
48 return;
49 }
50 p = e;
51 }
52 }
53}

References end_minigame(), entity(), etof, ftos(), GameLogEcho(), NULL, player_clear_minigame(), and strcat().

Referenced by minigame_addplayer(), and part_minigame().

◆ minigame_SendEntity()

bool minigame_SendEntity ( entity this,
entity to,
int sf )

Definition at line 64 of file sv_minigames.qc.

65{
66 WriteHeader(MSG_ENTITY, ENT_CLIENT_MINIGAME);
68
69 if ( sf & MINIG_SF_CREATE )
70 {
73 }
74
75 entity minigame_ent = this.owner;
76
77 if ( this.classname == "minigame" )
78 {
79 minigame_ent = this;
80
81 if ( sf & MINIG_SF_CREATE )
82 WriteString(MSG_ENTITY,this.descriptor.netname);
83
84 if ( sf & MINIG_SF_UPDATE )
86 }
87 else if ( this.classname == "minigame_player" )
88 {
89 if ( sf & MINIG_SF_CREATE )
90 {
91 WriteString(MSG_ENTITY,this.owner.netname);
93 }
94 if ( sf & MINIG_SF_UPDATE )
96 }
98
99 minigame_ent.minigame_event(minigame_ent,"network_send",this,sf);
100
101 return true;
102
103}
string netname
Definition powerups.qc:20
int team
Definition main.qh:188
#define WriteHeader(to, id)
Definition net.qh:221
void WriteLong(float data, float dest, float desto)
void WriteShort(float data, float dest, float desto)
void WriteByte(float data, float dest, float desto)
#define MINIGAME_SIMPLELINKED_ENTITIES
Set up automatic entity read/write functionality To ensure that everything is handled automatically,...
Definition all.qh:100
int msle_id(string class_name)
Definition minigames.qc:99
int minigame_flags
Definition minigames.qh:103
const int MINIG_SF_UPDATE
Definition minigames.qh:109
entity descriptor
For minigame sessions: minigame descriptor object.
Definition minigames.qh:45
entity minigame_players
For minigame sessions: list of players For minigame_player: client entity.

References classname, descriptor, entity(), etof, MINIG_SF_CREATE, MINIG_SF_UPDATE, minigame_flags, minigame_players, MINIGAME_SIMPLELINKED_ENTITIES, MSG_ENTITY, msle_id(), netname, owner, team, WriteByte(), WriteHeader, WriteLong(), WriteShort(), and WriteString().

Referenced by minigame_addplayer(), msle_spawn(), and start_minigame().

◆ MinigameImpulse()

bool MinigameImpulse ( entity this,
int imp )

Definition at line 296 of file sv_minigames.qc.

297{
298 if (!CS(this).active_minigame) return false;
300 if ( imp && CS(this).active_minigame && e )
301 {
302 return CS(this).active_minigame.minigame_event(CS(this).active_minigame,"impulse",e,imp);
303 }
304 return false;
305}
int int int imp
Definition impulse.qc:90

References active_minigame, CS(), entity(), imp, and minigame_find_player().

Referenced by ImpulseCommands(), and ObserverOrSpectatorThink().

◆ part_minigame()

void part_minigame ( entity player)

Definition at line 216 of file sv_minigames.qc.

217{
218 entity minig = CS(player).active_minigame;
219
220 if ( minig && minig.classname == "minigame" )
221 minigame_rmplayer(minig,player);
222}

References CS(), entity(), and minigame_rmplayer().

Referenced by BanCommand_playban(), ClientCommand_minigame(), and ClientDisconnect().

◆ player_clear_minigame()

void player_clear_minigame ( entity player)

Definition at line 6 of file sv_minigames.qc.

7{
8 CS(player).active_minigame = NULL;
9 player.minigame_players = NULL;
10 if ( IS_PLAYER(player) )
12 else
15}
#define IS_PLAYER(s)
Definition player.qh:243
void set_movetype(entity this, int mt)
Definition movetypes.qc:4
const int MOVETYPE_WALK
Definition movetypes.qh:132
const int MOVETYPE_FLY_WORLDONLY
Definition movetypes.qh:143
@ TEAM_FORCE_DEFAULT
Don't force any team.
Definition teamplay.qh:138

References CS(), entity(), IS_PLAYER, MOVETYPE_FLY_WORLDONLY, MOVETYPE_WALK, NULL, Player_SetForcedTeamIndex(), set_movetype(), and TEAM_FORCE_DEFAULT.

Referenced by end_minigame(), and minigame_rmplayer().

◆ start_minigame()

entity start_minigame ( entity player,
string minigame )

Create a new minigame session.

Returns
minigame session entity

Definition at line 164 of file sv_minigames.qc.

165{
166 if ( !autocvar_sv_minigames || !IS_REAL_CLIENT(player) )
167 return NULL;
168
169 entity e = minigame_get_descriptor(minigame);
170 if ( e )
171 {
172 entity minig = new(minigame);
173 minig.netname = strzone(strcat(e.netname,"_",ftos(etof(minig))));
174 minig.descriptor = e;
175 minig.minigame_event = e.minigame_event;
176 minig.minigame_event(minig,"start");
177 GameLogEcho(strcat(":minigame:start:",minig.netname));
178 if ( ! minigame_addplayer(minig,player) )
179 {
180 LOG_TRACE("Minigame ",minig.netname," rejected the first player join!");
181 end_minigame(minig);
182 return NULL;
183 }
184 Net_LinkEntity(minig, false, 0, minigame_SendEntity);
185
186 if ( !minigame_sessions )
187 minigame_sessions = minig;
188 else
189 {
190 minigame_sessions.owner = minig;
191 minig.list_next = minigame_sessions;
192 minigame_sessions = minig;
193 }
194 return minig;
195 }
196
197 return NULL;
198}
string strzone(string s)
entity minigame_get_descriptor(string id)
Definition minigames.qc:5

References autocvar_sv_minigames, end_minigame(), entity(), etof, ftos(), GameLogEcho(), IS_REAL_CLIENT, LOG_TRACE, minigame_addplayer(), minigame_get_descriptor(), minigame_SendEntity(), minigame_sessions, Net_LinkEntity(), NULL, strcat(), and strzone().

Referenced by ClientCommand_minigame().