centerprints now are managed independently per line
[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
19 void reset_map()
20 {
21         if(cvar("g_arena_warmup"))
22                 warmup = time + cvar("g_arena_warmup");
23         
24         self = nextent(world);
25         while(self)
26         {
27                 if(self.classname == "droppedweapon"            // cleanup
28                                 || self.classname == "gib"
29                                 || self.classname == "body")
30                 {
31                         remove(self);
32                 }
33                 else if(self.flags & FL_ITEM)                   // reset items
34                 {
35                         self.model = self.mdl;
36                         self.solid = SOLID_TRIGGER;
37                         setorigin (self, self.origin);
38                         self.think = SUB_Null;
39                         self.nextthink = 0;
40                         self.effects = self.effects - (self.effects & EF_STARDUST);
41                 }
42                 else if(self.flags & FL_PROJECTILE)             // remove any projectiles left
43                 {
44                         sound(self, CHAN_BODY, "misc/null.wav", 1, ATTN_NORM);
45                         remove(self);
46                 }
47                 else if(self.isdecor)
48                 {
49                         removedecor(self);
50                 }
51                 else if(self.flags & FL_CLIENT)                 // reset all players
52                 {
53                         if(self.spawned)
54                                 PutClientInServer();
55                         else
56                                 PutObserverInServer();
57                 }
58                 
59                 self = nextent(self);
60         }
61
62         if(champion)
63                 champion.frags += 1;
64 }
65
66 void Spawnqueue_Insert(entity e)
67 {
68         if(e.spawnqueue_in)
69                 return;
70         dprint(strcat("Into queue: ", e.netname, "\n"));
71         e.spawnqueue_in = TRUE;
72         e.spawnqueue_prev = spawnqueue_last;
73         e.spawnqueue_next = world;
74         if(spawnqueue_last)
75                 spawnqueue_last.spawnqueue_next = e;
76         spawnqueue_last = e;
77         if(!spawnqueue_first)
78                 spawnqueue_first = e;
79 }
80
81 void Spawnqueue_Remove(entity e)
82 {
83         if(!e.spawnqueue_in)
84                 return;
85         dprint(strcat("Out of queue: ", e.netname, "\n"));
86         e.spawnqueue_in = FALSE;
87         if(e == spawnqueue_first)
88                 spawnqueue_first = e.spawnqueue_next;
89         if(e == spawnqueue_last)
90                 spawnqueue_last = e.spawnqueue_prev;
91         if(e.spawnqueue_prev)
92                 e.spawnqueue_prev.spawnqueue_next = e.spawnqueue_next;
93         if(e.spawnqueue_next)
94                 e.spawnqueue_next.spawnqueue_prev = e.spawnqueue_prev;
95         e.spawnqueue_next = world;
96         e.spawnqueue_prev = world;
97 }
98
99 void Spawnqueue_Unmark(entity e)
100 {
101         if(!e.spawned)
102                 return;
103         e.spawned = FALSE;
104         numspawned = numspawned - 1;
105 }
106
107 void Spawnqueue_Mark(entity e)
108 {
109         if(e.spawned)
110                 return;
111         e.spawned = TRUE;
112         numspawned = numspawned + 1;
113 }
114
115 void Arena_Warmup()
116 {
117         float f;
118         string msg;
119
120         if(!arena_roundbased)
121                 return;
122
123         f = rint(warmup - time);
124
125         msg = newlines;
126         if(time < warmup && self.spawned)
127         {
128                 if(champion)
129                         centermsg_set(CENTERMSG_ARENACHAMP, strcat("The Champion is ", champion.netname));
130
131                 if(f)
132                         centermsg_set(CENTERMSG_ARENATIMER, strcat("Round will start in ", ftos(f)));
133                 else
134                 {
135                         if(self.spawned)
136                                 centermsg_set(CENTERMSG_ARENATIMER, "^1Fight!");
137                 }
138
139                 if(self.spawned)
140                         self.movetype = MOVETYPE_NONE;
141
142                 self.velocity = '0 0 0';
143                 self.avelocity = '0 0 0';
144                 self.movement = '0 0 0';
145                 //self.fixangle = TRUE;
146         }
147         else if(self.movetype == MOVETYPE_NONE)
148         {
149                 self.movetype = MOVETYPE_WALK;
150                 centermsg_reset();
151         }
152
153 }
154
155 float next_round;
156 void Spawnqueue_Check()
157 {
158         if(time < warmup + 1)
159                 return;
160
161         if(!next_round)
162         if(numspawned < 2)
163                 next_round = time + 3;
164
165         if(!arena_roundbased || (next_round && next_round < time && player_count > 1))
166         {
167                 next_round = 0;
168
169                 if(arena_roundbased)
170                 {
171                         champion = find(world, classname, "player");
172                         while(champion && champion.deadflag)
173                                 champion = find(champion, classname, "player");
174                         reset_map();
175                 }
176
177                 while(numspawned < maxspawned && spawnqueue_first)
178                 {
179                         self = spawnqueue_first;
180
181                         bprint (strcat("^4", self.netname, "^4 is the next challenger\n"));
182
183                         Spawnqueue_Remove(self);
184                         Spawnqueue_Mark(self);
185
186                         self.classname = "player";
187                         PutClientInServer();
188                 }
189         }
190 }