]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/arena.qc
allow server admins to stop a running vote with 'sv_cmd vstop'.. not sure if it will...
[divverent/nexuiz.git] / data / qcsrc / server / arena.qc
1 float maxspawned;
2 float numspawned;
3 float arena_roundbased;
4 .float spawned;
5 .entity spawnqueue_next;
6 .entity spawnqueue_prev;
7 .float spawnqueue_in;
8 entity spawnqueue_first;
9 entity spawnqueue_last;
10 entity champion;
11 float warmup;
12
13 void PutObserverInServer();
14 void PutClientInServer();
15 void(entity e) DropFlag;
16 void(entity e) ReturnFlag;
17 void(entity e) removedecor;
18 void dom_controlpoint_setup();
19 void onslaught_generator_reset();
20 void onslaught_controlpoint_reset();
21
22 void reset_map()
23 {
24         if(g_arena)
25         if(cvar("g_arena_warmup"))
26                 warmup = time + cvar("g_arena_warmup");
27         
28         lms_lowest_lives = 999;
29         lms_next_place = player_count;
30
31         self = nextent(world);
32         while(self)
33         {
34                 if(self.classname == STR_ITEM_KH_KEY)
35                 {
36                         kh_Key_AssignTo(self, world);
37                         //if(self.owner)
38                         //      kh_Key_DropAll(self.owner, TRUE);
39                         kh_Key_Remove(self);
40                 }
41                 else if(self.classname == "droppedweapon"               // cleanup
42                                 || self.classname == "gib"
43                                 || self.classname == "body")
44                 {
45                         remove(self);
46                 }
47                 else if(self.items & (IT_KEY1 | IT_KEY2))
48                 {
49                         DropFlag(self);
50                         ReturnFlag(self);
51                 }
52                 else if(self.classname == "rune")
53                 {
54                         if(self.owner)
55                         if(self.owner.classname != "runematch_spawn_point")
56                                 DropAllRunes(self.owner);
57                         rune_respawn();
58                 }
59                 else if(self.classname == "sprite_waypoint")
60                 {
61                         if(self.health | g_keyhunt)
62                                 WaypointSprite_Kill(self);
63                 }
64                 else if(self.classname == "dom_controlpoint")
65                 {
66                         dom_controlpoint_setup();
67                 }
68                 else if(self.flags & FL_ITEM)                   // reset items
69                 {
70                         self.model = self.mdl;
71                         self.solid = SOLID_TRIGGER;
72                         setorigin (self, self.origin);
73                         self.think = SUB_Null;
74                         self.nextthink = 0;
75                 }
76                 else if(self.flags & FL_PROJECTILE)             // remove any projectiles left
77                 {
78                         sound(self, CHAN_BODY, "misc/null.wav", 1, ATTN_NORM);
79                         remove(self);
80                 }
81                 else if(self.isdecor)
82                 {
83                         removedecor(self);
84                 }
85                 // TODO properly reset Onslaught
86                 else if(self.classname == "onslaught_generator")
87                 {
88                         onslaught_generator_reset();
89                 }
90                 else if(self.classname == "onslaught_controlpoint")
91                 {
92                         onslaught_controlpoint_reset();
93                 }
94                 // TODO properly reset Assault
95                 // General teambased game modes
96                 else if(self.classname == "info_player_deathmatch")
97                 {
98                         self.team = self.team_saved;
99                 }
100                 self = nextent(self);
101         }
102
103         // Moving the player reset code here since the player-reset depends
104         // on spawnpoint entities which have to be reset first --blub
105         FOR_EACH_CLIENT(self) {
106                 if(self.flags & FL_CLIENT)                              // reset all players
107                 {
108                         if(time < restart_countdown)
109                         {
110                                 self.frags = (g_lms)?LMS_NewPlayerLives():0;
111                                 self.deaths = 0;
112                                 self.killcount = 0;
113                                 self.classname = "player";
114                                 PutClientInServer();
115                         }
116                         else if(g_arena)
117                         {
118                                 if(self.spawned)
119                                         PutClientInServer();
120                                 else
121                                         PutObserverInServer();
122                         }
123                 }
124         }
125
126         if(g_keyhunt)
127                 kh_Controller_SetThink(cvar("g_balance_keyhunt_delay_round")+RESTART_COUNTDOWN, "", kh_StartRound);
128
129         if(g_arena)
130         if(champion)
131                 UpdateFrags(champion, +1);
132 }
133
134 void Spawnqueue_Insert(entity e)
135 {
136         if(e.spawnqueue_in)
137                 return;
138         dprint(strcat("Into queue: ", e.netname, "\n"));
139         e.spawnqueue_in = TRUE;
140         e.spawnqueue_prev = spawnqueue_last;
141         e.spawnqueue_next = world;
142         if(spawnqueue_last)
143                 spawnqueue_last.spawnqueue_next = e;
144         spawnqueue_last = e;
145         if(!spawnqueue_first)
146                 spawnqueue_first = e;
147 }
148
149 void Spawnqueue_Remove(entity e)
150 {
151         if(!e.spawnqueue_in)
152                 return;
153         dprint(strcat("Out of queue: ", e.netname, "\n"));
154         e.spawnqueue_in = FALSE;
155         if(e == spawnqueue_first)
156                 spawnqueue_first = e.spawnqueue_next;
157         if(e == spawnqueue_last)
158                 spawnqueue_last = e.spawnqueue_prev;
159         if(e.spawnqueue_prev)
160                 e.spawnqueue_prev.spawnqueue_next = e.spawnqueue_next;
161         if(e.spawnqueue_next)
162                 e.spawnqueue_next.spawnqueue_prev = e.spawnqueue_prev;
163         e.spawnqueue_next = world;
164         e.spawnqueue_prev = world;
165 }
166
167 void Spawnqueue_Unmark(entity e)
168 {
169         if(!e.spawned)
170                 return;
171         e.spawned = FALSE;
172         numspawned = numspawned - 1;
173 }
174
175 void Spawnqueue_Mark(entity e)
176 {
177         if(e.spawned)
178                 return;
179         e.spawned = TRUE;
180         numspawned = numspawned + 1;
181 }
182
183 void Arena_Warmup()
184 {
185         float f;
186         string msg;
187
188         if(!g_arena || !arena_roundbased || (time < restart_countdown))
189                 return;
190
191         f = rint(warmup - time);
192
193         msg = NEWLINES;
194         if(time < warmup && self.spawned)
195         {
196                 if(champion)
197                         msg = strcat(msg, "The Champion is ", champion.netname, "^7\n\n\n");
198
199                 if(f)
200                         msg = strcat(msg, "Round will start in ", ftos(f));
201                 else
202                 {
203                         if(self.spawned)
204                                 msg = strcat(msg, "^1Fight!");
205                 }
206
207                 centerprint(self, msg);
208
209                 if(self.spawned)
210                         self.movetype = MOVETYPE_NONE;
211
212                 self.velocity = '0 0 0';
213                 self.avelocity = '0 0 0';
214                 self.movement = '0 0 0';
215                 //self.fixangle = TRUE;
216         }
217         else if(self.movetype == MOVETYPE_NONE)
218         {
219                 self.movetype = MOVETYPE_WALK;
220                 centerprint(self, "\n");
221         }
222
223 }
224
225 float next_round;
226 void Spawnqueue_Check()
227 {
228         if(time < warmup + 1)
229                 return;
230
231         if(!next_round)
232         if(numspawned < 2)
233                 next_round = time + 3;
234
235         if(!arena_roundbased || (next_round && next_round < time && player_count > 1))
236         {
237                 next_round = 0;
238
239                 if(arena_roundbased)
240                 {
241                         champion = find(world, classname, "player");
242                         while(champion && champion.deadflag)
243                                 champion = find(champion, classname, "player");
244                         reset_map();
245                 }
246
247                 while(numspawned < maxspawned && spawnqueue_first)
248                 {
249                         self = spawnqueue_first;
250
251                         bprint ("^4", self.netname, "^4 is the next challenger\n");
252
253                         Spawnqueue_Remove(self);
254                         Spawnqueue_Mark(self);
255
256                         self.classname = "player";
257                         PutClientInServer();
258                 }
259         }
260 }