]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/assault.qc
func_assault_destructible are only attackable by attackers now.
[divverent/nexuiz.git] / data / qcsrc / server / assault.qc
1
2 // attacker spawn point
3 void info_player_attacker() {
4         info_player_deathmatch();
5         self.team = COLOR_TEAM1; // red, gets swapped every round
6 }
7
8 // defender spawn point
9 void info_player_defender() {
10         info_player_deathmatch();
11         self.team = COLOR_TEAM2; // blue, gets swapped every round
12 }
13
14 // reset this objective. Used when spawning an objective
15 // and when a new round starts
16 void assault_objective_reset() {
17         self.health = ASSAULT_VALUE_INACTIVE;
18 }
19
20 void assault_objective_use() {
21         // activate objective
22         self.health = 100; 
23         self.nextthink = time + 0.1;
24 }
25
26 void assault_objective_think() {
27         local entity oldself;   
28         if(self.health < 0) {
29                 //self.effects = 0;
30                 local entity ent;
31                 ent = find(world, targetname, self.target);
32                 while(ent) {
33                         oldself = self;
34                         self = ent;
35                         self.use();
36                         self = oldself;
37                         ent = find(ent, targetname, self.target);
38                         
39                 }
40         } else {
41                 //self.effects = EF_STARDUST;
42                 self.nextthink = time + 0.1;
43         }
44         
45 }
46
47 void target_objective() {
48         self.classname = "target_objective";
49         self.think = assault_objective_think;
50         self.use = assault_objective_use;
51         assault_objective_reset();
52 }
53
54
55 void assault_objective_decrease_think() {
56
57         local entity objective;
58         local float found;
59         found = 0;
60         objective = find(world, targetname, self.target);
61         while(objective && found == 0) {
62                 if(objective.classname == "target_objective") {
63                         found = 1;
64                         if(objective.health < ASSAULT_VALUE_INACTIVE) { // targeted objective is active
65                                 if(self.cnt == 1 && self.max_health >= ASSAULT_VALUE_INACTIVE) { 
66                                         // decrease was fired already, but objective did recover (round reset)
67                                         self.cnt = 0;
68                                 }
69                         } else { // objective isn't active
70                                 self.cnt = 1;
71                         }
72                         self.max_health = objective.health; // save current objective status for next think
73                 }
74         }
75
76         if(self.cnt == 0) {
77                 if(self.model != self.mdl)
78                         setmodel(self, self.mdl);
79         } else {
80                 self.model = "";
81         }
82
83         self.nextthink = time + 0.2;
84 }
85
86
87 // decrease the health of targeted objectives
88 void assault_objective_decrease() {
89
90         local entity ent;
91         ent = find(world, targetname, self.target);
92         while(ent) {
93                 if(ent.health > 0 && ent.health < ASSAULT_VALUE_INACTIVE)
94                         ent.health = ent.health - self.dmg;
95                 ent = find(ent, targetname, self.target);
96         }
97
98         self.cnt = 1;
99 }
100
101 // this entity should target an objective and be targeted by triggers
102 void target_objective_decrease() {
103
104         self.classname = "target_objective_decrease";
105
106         if(!self.dmg) {
107                 self.dmg = 101;
108         }
109         self.cnt = 0; // not used yet
110         self.use = assault_objective_decrease;
111         self.mdl = "models/sprites/here.sp2";
112         self.effects = EF_NODEPTHTEST;
113         self.health = ASSAULT_VALUE_INACTIVE;
114         self.max_health = ASSAULT_VALUE_INACTIVE;
115         self.think = assault_objective_decrease_think;
116         self.nextthink = time;
117 }
118
119
120 void assault_destructible_reset() {
121         self.health = self.max_health;
122         self.model = self.mdl;
123         self.solid = SOLID_BSP;
124         self.cnt = 0; // not active
125         if(self.spawnflags)
126                 self.use();
127 }
128
129 void assault_destructible_use() {
130         self.cnt = 1; // mark active
131         self.takedamage = DAMAGE_YES;
132         self.nextthink = time + 0.1;
133 }
134
135 void assault_destructible_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) {
136
137         if(self.cnt > 0 && self.team == attacker.team)  
138                 self.health = self.health - damage;
139
140 }
141
142
143 void assault_destructible_think() {
144         local entity oldself;
145
146         if(self.cnt > 0 && self.health < 0) {
147                 self.model = "";
148                 self.takedamage = DAMAGE_NO;
149                 self.solid = SOLID_NOT;
150                 local entity ent;
151                 ent = find(world, targetname, self.target);
152                 while(ent) {
153                         oldself = self;
154                         self = ent;
155                         self.use();
156                         self = oldself;
157                         ent = find(ent, targetname, self.target);
158                 }
159         } else {
160                 self.nextthink = time + 0.1;
161         }
162 }
163
164 // destructible walls that can be used to trigger target_objective_decrease
165 void func_assault_destructible() {
166         if(!self.health)
167                 self.health = 100;
168
169         self.max_health = self.health;
170         
171         self.cnt = 0; // not yet activated
172
173         self.classname = "func_assault_destructible";
174         self.team = COLOR_TEAM1; // red team, gets swapped every round
175         self.mdl = self.model;
176         setmodel(self, self.mdl);
177
178         self.solid = SOLID_BSP;
179         self.think = assault_destructible_think;
180         self.use = assault_destructible_use;
181         self.event_damage = assault_destructible_damage;
182
183 }
184
185
186 // trigger new round
187 // reset objectives, toggle spawnpoints, reset triggers, ...
188 void assault_new_round() {
189         
190         // this assumes self.classname == "func_assault_roundend"!
191         self.cnt = self.cnt + 1;
192
193         // swap spawn point teams
194         local entity ent;
195         local entity oldself;
196
197         ent = find(world, classname, "info_player_deathmatch");
198         while (ent)
199         {
200                 oldself = self;
201                 self = ent;
202                 if(self.team == COLOR_TEAM1) {
203                         self.team = COLOR_TEAM2;
204                 } else {
205                         self.team = COLOR_TEAM1;
206                 }
207                 self = oldself;
208
209                 ent = find(ent, classname, "info_player_deathmatch");
210         } 
211
212         // reset all objectives
213         ent = find(world, classname, "target_objective");
214         while (ent)
215         {
216                 oldself = self;
217                 self = ent;
218                 assault_objective_reset();
219                 self = oldself;
220
221                 ent = find(ent, classname, "target_objective");
222         } 
223
224         // reset all target_object_decrease
225         ent = find(world, classname, "target_objective_decrease");
226         while (ent)
227         {
228                 ent.cnt = 0;
229                 ent = find(ent, classname, "target_objective_decrease");
230         } 
231
232         // reset all func_assault_destructible
233         ent = find(world, classname, "func_assault_destructible");
234         while (ent)
235         {
236                 oldself = self;
237                 self = ent;
238                 assault_destructible_reset();
239                 if(self.team == COLOR_TEAM1) {
240                         self.team = COLOR_TEAM2;
241                 } else {
242                         self.team = COLOR_TEAM1;
243                 }
244                 self = oldself;
245                 ent = find(ent, classname, "func_assault_destructible");
246         }
247
248         ent = find(world, classname, "target_assault_roundstart");
249         while (ent)
250         {
251                 oldself = self;
252                 self = ent;
253                 self.use();
254                 self = oldself;
255                 ent = find(ent, classname, "target_assault_roundstart");
256         }
257
258         // actually restart round... how to do that?
259 }
260
261 void target_assault_roundend() {
262         self.cnt = 0; // round counter
263         self.classname = "target_assault_roundend";
264         self.use = assault_new_round;
265 }
266
267 void assault_roundstart_use() {
268         local entity ent;
269         local entity oldself;
270         ent = find(world, targetname, self.target);
271         while(ent) {
272                 oldself = self;
273                 self = ent;
274                 self.use();
275                 self = oldself;
276                 ent = find(ent, targetname, self.target);
277         }
278 }
279
280 void target_assault_roundstart() {
281         self.classname = "target_assault_roundstart";
282         self.use = assault_roundstart_use;
283         self.think = assault_roundstart_use;
284         self.nextthink = time + 0.1;
285 }
286
287