]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/monsters.qc
Move td generator model loading to client
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / monsters.qc
1 string mid2info_model;
2 string mid2info_name;
3 vector mid2info_min;
4 vector mid2info_max;
5
6 float monster_precached[MONSTER_LAST];
7 void monster_mid2info(float _mid);
8
9 void monster_precache(float _mid)
10 {    
11     monster_mid2info(_mid);
12     if(monster_precached[_mid])
13         return;
14
15     switch(_mid)
16     {
17         case MONSTER_ZOMBIE:
18                 {
19                         precache_model(ZOMBIE_MODEL);
20                         break;
21                 }
22                 case MONSTER_OGRE:
23                 {
24                         precache_model(OGRE_MODEL);
25                         break;
26                 }
27                 case MONSTER_DEMON:
28                 {
29                         precache_model(DEMON_MODEL);
30                         break;
31                 }
32                 case MONSTER_SHAMBLER:
33                 {
34                         precache_model(SHAMBLER_MODEL);
35                         break;
36                 }
37                 case MONSTER_KNIGHT:
38                 {
39                         precache_model(KNIGHT_MODEL);
40                         break;
41                 }
42                 case MONSTER_MARINE:
43                 {
44                         precache_model(SOLDIER_MODEL);
45                         precache_sound("weapons/shotgun_fire.wav");
46                         precache_sound("weapons/uzi_fire.wav");
47                         precache_sound("weapons/laser_fire.wav");
48                         precache_sound("weapons/reload.wav");
49                         precache_model("models/weapons/v_seeker.md3");
50                         break;
51                 }
52                 case MONSTER_SCRAG:
53                 {
54                         precache_model(WIZARD_MODEL);
55                         break;
56                 }
57                 case MONSTER_DOG:
58                 {
59                         precache_model(DOG_MODEL);
60                         break;
61                 }
62                 case MONSTER_TARBABY:
63                 {
64                         precache_model(TARBABY_MODEL);
65                         precache_sound("weapons/rocket_impact.wav");
66                         break;
67                 }
68                 case MONSTER_HELLKNIGHT:
69                 {
70                         precache_model(HELLKNIGHT_MODEL);
71                         break;
72                 }
73                 case MONSTER_FISH:
74                 {
75                         precache_model(FISH_MODEL);
76                         break;
77                 }
78                 case MONSTER_MAGE:
79                 {
80                         precache_model(SHALRATH_MODEL);
81                         break;
82                 }
83                 case MONSTER_SPIDER:
84                 {
85                         precache_model(SPIDER_MODEL);
86
87                         break;
88                 }
89     }    
90     monster_precached[_mid] = TRUE;
91 }
92
93 void Monsters_Precache()
94 {
95         float i;
96         for(i = MONSTER_FIRST; i <= MONSTER_LAST; ++i)
97                 monster_precache(i);
98 }
99
100 void monster_mid2info(float _mid)
101 {
102         switch(_mid)
103         {
104                 case MONSTER_ZOMBIE:
105                 {
106                         mid2info_model = ZOMBIE_MODEL;
107                         mid2info_name = "Zombie";
108                         mid2info_min = ZOMBIE_MIN;
109                         mid2info_max = ZOMBIE_MAX;
110                         break;
111                 }
112                 case MONSTER_OGRE:
113                 {
114                         mid2info_model = OGRE_MODEL;
115                         mid2info_name = "Ogre";
116                         mid2info_min = OGRE_MIN;
117                         mid2info_max = OGRE_MAX;
118                         break;
119                 }
120                 case MONSTER_DEMON:
121                 {
122                         mid2info_model = DEMON_MODEL;
123                         mid2info_name = "Fiend";
124                         mid2info_min = DEMON_MIN;
125                         mid2info_max = DEMON_MAX;
126                         break;
127                 }
128                 case MONSTER_SHAMBLER:
129                 {
130                         mid2info_model = SHAMBLER_MODEL;
131                         mid2info_name = "Shambler";
132                         mid2info_min = SHAMBLER_MIN;
133                         mid2info_max = SHAMBLER_MAX;
134                         break;
135                 }
136                 case MONSTER_KNIGHT:
137                 {
138                         mid2info_model = KNIGHT_MODEL;
139                         mid2info_name = "Knight";
140                         mid2info_min = KNIGHT_MIN;
141                         mid2info_max = KNIGHT_MAX;
142                         break;
143                 }
144                 case MONSTER_MARINE:
145                 {
146                         mid2info_model = SOLDIER_MODEL;
147                         mid2info_name = "Marine";
148                         mid2info_min = SOLDIER_MIN;
149                         mid2info_max = SOLDIER_MAX;
150                         break;
151                 }
152                 case MONSTER_SCRAG:
153                 {
154                         mid2info_model = WIZARD_MODEL;
155                         mid2info_name = "Scrag";
156                         mid2info_min = WIZARD_MIN;
157                         mid2info_max = WIZARD_MAX;
158                         break;
159                 }
160                 case MONSTER_DOG:
161                 {
162                         mid2info_model = DOG_MODEL;
163                         mid2info_name = "Cerberus";
164                         mid2info_min = DOG_MIN;
165                         mid2info_max = DOG_MAX;
166                         break;
167                 }
168                 case MONSTER_TARBABY:
169                 {
170                         mid2info_model = TARBABY_MODEL;
171                         mid2info_name = "Spawn";
172                         mid2info_min = TARBABY_MIN;
173                         mid2info_max = TARBABY_MAX;
174                         break;
175                 }
176                 case MONSTER_HELLKNIGHT:
177                 {
178                         mid2info_model = HELLKNIGHT_MODEL;
179                         mid2info_name = "Hell-Knight";
180                         mid2info_min = HELLKNIGHT_MIN;
181                         mid2info_max = HELLKNIGHT_MAX;
182                         break;
183                 }
184                 case MONSTER_FISH:
185                 {
186                         mid2info_model = FISH_MODEL;
187                         mid2info_name = "Rotfish";
188                         mid2info_min = FISH_MIN;
189                         mid2info_max = FISH_MAX;
190                         break;
191                 }
192                 case MONSTER_MAGE:
193                 {
194                         mid2info_model = SHALRATH_MODEL;
195                         mid2info_name = "Mage";
196                         mid2info_min = SHALRATH_MIN;
197                         mid2info_max = SHALRATH_MAX;
198                         break;
199                 }
200                 case MONSTER_SPIDER:
201                 {
202                         mid2info_model = SPIDER_MODEL;
203                         mid2info_name = "Spider";
204                         mid2info_min = SPIDER_MIN;
205                         mid2info_max = SPIDER_MAX;
206                         break;
207                 }
208                 default:
209                 {
210                         dprint("WARNING: Unknown monster in CSQC\n");
211                         break;
212                 }
213         }       
214 }
215
216 .vector glowmod;
217 void monster_changeteam()
218 {       
219         switch(self.team - 1)
220         {
221                 case NUM_TEAM_1: // Red
222                 {
223                         self.glowmod = '2 0 0';
224                         self.teamradar_color = '1 0 0';
225                         break;
226                 }
227                 case NUM_TEAM_2: // Blue
228                 {
229                         self.glowmod = '0 0 2';
230                         self.teamradar_color = '0 0 1';
231                         break;
232                 }
233                 case NUM_TEAM_3: // Yellow
234                 {
235                         self.glowmod = '1 1 0';
236                         self.teamradar_color = '1 1 0';
237                         break;
238                 }
239                 case NUM_TEAM_4: // Pink
240                 {
241                         self.glowmod = '1 0 1';
242                         self.teamradar_color = '1 0 1';
243                         break;
244                 }
245         }
246         
247         if(self.team)
248                 self.colormap = 1024 + (self.team - 1) * 17;
249 }
250
251 void monster_die()
252 {
253         if(self.monsterid == MONSTER_SPIDER)
254                 self.angles += '180 0 0';
255                 
256         self.solid = SOLID_CORPSE;
257 }
258
259 void monster_draw()
260 {        
261     float dt;
262             
263     dt = time - self.move_time;
264     self.move_time = time;
265     if(dt <= 0)
266         return;
267     
268     fixedmakevectors(self.angles);
269     //movelib_groundalign4point(300, 100, 0.25, 45);
270     setorigin(self, self.origin + self.velocity * dt);
271     self.angles_y = self.move_angles_y;  
272 }
273
274 void monster_construct()
275 {       
276         monster_mid2info(self.monsterid);
277         self.netname = mid2info_name;
278
279         setorigin(self, self.origin);
280         setmodel(self, mid2info_model);
281         setsize(self, mid2info_min, mid2info_max);
282         
283         self.move_movetype      = MOVETYPE_BOUNCE;
284         self.health                     = 255;
285         self.solid                      = SOLID_BBOX;
286         self.movetype           = MOVETYPE_BOUNCE; 
287         self.move_origin        = self.origin;
288         self.move_time          = time;
289         self.drawmask           = MASK_NORMAL;  
290         self.alpha                      = 1;
291         self.draw                       = monster_draw;
292 }
293
294 void ent_monster()
295 {
296         float sf;
297         sf = ReadByte();
298
299         if(sf & MSF_SETUP)
300         {               
301                 self.monsterid = ReadByte();
302                                 
303                 self.origin_x = ReadCoord();
304                 self.origin_y = ReadCoord();
305                 self.origin_z = ReadCoord();
306                 setorigin(self, self.origin);
307                 
308                 self.angles_x = ReadAngle();
309                 self.angles_y = ReadAngle();
310                 
311                 self.scale = ReadByte();
312                 self.skin = ReadByte();
313                 
314                 monster_precache(self.monsterid);
315                 monster_construct();
316                 self.colormap = 1024;
317                 self.glowmod = '0 1 1'; 
318         }
319         
320         if(sf & MSF_SIZE)
321         {
322                 self.scale = ReadByte();
323                 self.mins_x = ReadCoord();
324                 self.mins_y = ReadCoord();
325                 self.mins_z = ReadCoord();
326                 
327                 self.maxs_x = ReadCoord();
328                 self.maxs_y = ReadCoord();
329                 self.maxs_z = ReadCoord();
330
331                 setsize(self, self.mins, self.maxs);
332         }
333         
334         if(sf & MSF_ANG)
335         {
336                 self.move_angles_x = ReadShort();
337                 self.move_angles_y = ReadShort();
338                 self.angles = self.move_angles;
339         }
340         
341         if(sf & MSF_MOVE)
342         {
343                 self.origin_x = ReadShort();
344                 self.origin_y = ReadShort();
345                 self.origin_z = ReadShort();
346                 setorigin(self, self.origin);
347                 
348                 self.velocity_x = ReadShort();
349                 self.velocity_y = ReadShort();
350                 self.velocity_z = ReadShort();
351                 
352                 self.move_angles_y = ReadShort();
353                         
354                 self.move_time   = time;
355                 self.move_velocity = self.velocity;
356                 self.move_origin   = self.origin;
357         }
358                 
359         if(sf & MSF_ANIM)
360         {
361                 self.frame1time = ReadCoord();
362                 self.frame        = ReadByte();
363         }
364
365         if(sf & MSF_STATUS)
366         {
367                 self.skin = ReadByte();
368         
369                 float _tmp;
370                 _tmp = ReadByte();
371                 if(_tmp != self.team)
372                 {                       
373                         self.team = _tmp;                               
374                         monster_changeteam();
375                 }
376                 
377                 _tmp = ReadByte();
378                 
379                 if(_tmp == 0 && self.health != 0)
380                         monster_die();
381
382                 self.health = _tmp;
383         }
384 }
385
386 void td_generator_precache()
387 {
388         precache_model("models/onslaught/generator.md3");
389         precache_model("models/onslaught/generator_dead.md3");
390         precache_sound("onslaught/generator_underattack.wav");
391 }
392
393 void td_generator_die()
394 {
395         setmodel(self, "models/onslaught/generator_dead.md3");
396         pointparticles(particleeffectnum("explosion_medium"), self.origin, '0 0 0', 1);
397 }
398
399 void td_generator_draw() { } // TODO
400
401 void td_generator_construct()
402 {       
403         self.netname = "Generator";
404
405         setorigin(self, self.origin);
406         setmodel(self, "models/onslaught/generator.md3");
407         setsize(self, GENERATOR_MIN, GENERATOR_MAX);
408         
409         self.move_movetype      = MOVETYPE_NOCLIP;
410         self.health                     = 255;
411         self.solid                      = SOLID_BBOX;
412         self.movetype           = MOVETYPE_NOCLIP; 
413         self.move_origin        = self.origin;
414         self.move_time          = time;
415         self.drawmask           = MASK_NORMAL;  
416         self.alpha                      = 1;
417         self.draw                       = td_generator_draw;
418 }
419
420 void ent_td_generator()
421 {
422         float sf;
423         sf = ReadByte();
424
425         if(sf & MSF_SETUP)
426         {
427                 self.origin_x = ReadCoord();
428                 self.origin_y = ReadCoord();
429                 self.origin_z = ReadCoord();
430                 setorigin(self, self.origin);
431                 
432                 td_generator_precache();
433                 td_generator_construct();
434                 self.colormap = 1024;
435                 self.glowmod = '1 1 0'; 
436         }
437
438         if(sf & MSF_STATUS)
439         {
440                 float _tmp = ReadByte();
441                 
442                 if(_tmp == 0 && self.health != 0)
443                         td_generator_die();
444
445                 self.health = _tmp;
446         }
447 }
448