1 void Spawnqueue_Insert(entity e)
5 dprint(strcat("Into queue: ", e.netname, "\n"));
6 e.spawnqueue_in = TRUE;
7 e.spawnqueue_prev = spawnqueue_last;
8 e.spawnqueue_next = world;
10 spawnqueue_last.spawnqueue_next = e;
16 void Spawnqueue_Remove(entity e)
20 dprint(strcat("Out of queue: ", e.netname, "\n"));
21 e.spawnqueue_in = FALSE;
22 if(e == spawnqueue_first)
23 spawnqueue_first = e.spawnqueue_next;
24 if(e == spawnqueue_last)
25 spawnqueue_last = e.spawnqueue_prev;
27 e.spawnqueue_prev.spawnqueue_next = e.spawnqueue_next;
29 e.spawnqueue_next.spawnqueue_prev = e.spawnqueue_prev;
30 e.spawnqueue_next = world;
31 e.spawnqueue_prev = world;
34 void Spawnqueue_Unmark(entity e)
39 numspawned = numspawned - 1;
42 void Spawnqueue_Mark(entity e)
47 numspawned = numspawned + 1;
50 float Arena_CheckWinner()
54 // FIXME do this only once (on round start)
58 if(round_handler_GetTimeLeft() <= 0)
60 FOR_EACH_REALCLIENT(e)
61 centerprint(e, "Round over, there's no winner");
62 bprint("Round over, there's no winner\n");
73 if(e.spawned && e.classname == "player")
79 FOR_EACH_REALCLIENT(e)
80 centerprint(e, strcat("The Champion is ", champion.netname));
81 bprint("The Champion is ", champion.netname, "\n");
82 UpdateFrags(champion, +1);
86 FOR_EACH_REALCLIENT(e)
87 centerprint(e, "Round tied");
88 bprint("Round tied\n");
92 void Arena_AddChallengers()
96 while(numspawned < maxspawned && spawnqueue_first)
98 self = spawnqueue_first;
100 bprint ("^4", self.netname, "^4 is the next challenger\n");
102 Spawnqueue_Remove(self);
103 Spawnqueue_Mark(self);
105 self.classname = "player";
111 float prev_numspawned;
112 float Arena_CheckPlayers()
116 Arena_AddChallengers();
120 if(prev_numspawned != -1)
122 FOR_EACH_REALCLIENT(e)
123 Send_CSQC_Centerprint_Generic_Expire(e, CPID_WAITING_PLAYERS);
125 prev_numspawned = -1;
129 if(prev_numspawned != numspawned && numspawned == 1)
131 FOR_EACH_REALCLIENT(e)
132 Send_CSQC_Centerprint_Generic(e, CPID_WAITING_PLAYERS, "Waiting for players to join...", -1, 0);
133 prev_numspawned = numspawned;
139 MUTATOR_HOOKFUNCTION(arena_ClientDisconnect)
141 Spawnqueue_Unmark(self);
142 Spawnqueue_Remove(self);
146 MUTATOR_HOOKFUNCTION(arena_reset_map_players)
148 FOR_EACH_CLIENT(self)
153 self.player_blocked = 1;
156 PutObserverInServer();
161 MUTATOR_HOOKFUNCTION(arena_MakePlayerObserver)
163 self.frags = FRAGS_PLAYER;
164 if(self.version_mismatch)
166 Spawnqueue_Unmark(self);
167 Spawnqueue_Remove(self);
170 Spawnqueue_Insert(self);
174 MUTATOR_HOOKFUNCTION(arena_PutClientInServer)
177 self.classname = "observer";
181 MUTATOR_HOOKFUNCTION(arena_PlayerSpawn)
183 Spawnqueue_Remove(self);
184 Spawnqueue_Mark(self);
186 self.player_blocked = 1;
190 MUTATOR_HOOKFUNCTION(arena_PlayerPreThink)
192 self.stat_respawn_time = 0;
194 // put dead players in the spawn queue
196 if(self.deadflag && time - self.death_time >= 1.5)
202 MUTATOR_HOOKFUNCTION(arena_ForbidPlayerScore_Clear)
207 MUTATOR_HOOKFUNCTION(arena_GiveFragsForKill)
214 MUTATOR_HOOKFUNCTION(arena_PlayerDies)
216 Spawnqueue_Unmark(self);
220 MUTATOR_HOOKFUNCTION(arena_SV_StartFrame)
222 if(arena_roundbased) return 1;
223 if(time <= game_starttime) return 1;
224 if(gameover) return 1;
226 Arena_AddChallengers();
230 void arena_Initialize()
232 maxspawned = max(2, autocvar_g_arena_maxspawned);
233 arena_roundbased = autocvar_g_arena_roundbased;
235 round_handler_Spawn(Arena_CheckPlayers, Arena_CheckWinner, 5, autocvar_g_arena_warmup, autocvar_g_arena_round_timelimit);
238 MUTATOR_DEFINITION(gamemode_arena)
240 MUTATOR_HOOK(ClientDisconnect, arena_ClientDisconnect, CBC_ORDER_ANY);
241 MUTATOR_HOOK(reset_map_players, arena_reset_map_players, CBC_ORDER_ANY);
242 MUTATOR_HOOK(MakePlayerObserver, arena_MakePlayerObserver, CBC_ORDER_ANY);
243 MUTATOR_HOOK(PutClientInServer, arena_PutClientInServer, CBC_ORDER_ANY);
244 MUTATOR_HOOK(PlayerSpawn, arena_PlayerSpawn, CBC_ORDER_ANY);
245 MUTATOR_HOOK(PlayerPreThink, arena_PlayerPreThink, CBC_ORDER_ANY);
246 MUTATOR_HOOK(ForbidPlayerScore_Clear, arena_ForbidPlayerScore_Clear, CBC_ORDER_ANY);
247 MUTATOR_HOOK(GiveFragsForKill, arena_GiveFragsForKill, CBC_ORDER_ANY);
248 MUTATOR_HOOK(PlayerDies, arena_PlayerDies, CBC_ORDER_ANY);
249 MUTATOR_HOOK(SV_StartFrame, arena_SV_StartFrame, CBC_ORDER_ANY);
253 if(time > 1) // game loads at time 1
254 error("This is a game type and it cannot be added at runtime.");
260 error("This is a game type and it cannot be removed at runtime.");