]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/monsters.qc
Fix scrag not falling when killed
[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_ENFORCER:
84                 {
85                         precache_model(ENFORCER_MODEL);
86                         precache_model("models/turrets/ewheel-gun1.md3");
87                         break;
88                 }
89                 case MONSTER_SPIDER:
90                 {
91                         precache_model(SPIDER_MODEL);
92
93                         break;
94                 }
95     }    
96     monster_precached[_mid] = TRUE;
97 }
98
99 void Monsters_Precache()
100 {
101         float i;
102         for(i = MONSTER_FIRST; i <= MONSTER_LAST; ++i)
103                 monster_precache(i);
104 }
105
106 void monster_mid2info(float _mid)
107 {
108         switch(_mid)
109         {
110                 case MONSTER_ZOMBIE:
111                 {
112                         mid2info_model = ZOMBIE_MODEL;
113                         mid2info_name = "Zombie";
114                         mid2info_min = ZOMBIE_MIN;
115                         mid2info_max = ZOMBIE_MAX;
116                         break;
117                 }
118                 case MONSTER_OGRE:
119                 {
120                         mid2info_model = OGRE_MODEL;
121                         mid2info_name = "Ogre";
122                         mid2info_min = OGRE_MIN;
123                         mid2info_max = OGRE_MAX;
124                         break;
125                 }
126                 case MONSTER_DEMON:
127                 {
128                         mid2info_model = DEMON_MODEL;
129                         mid2info_name = "Fiend";
130                         mid2info_min = DEMON_MIN;
131                         mid2info_max = DEMON_MAX;
132                         break;
133                 }
134                 case MONSTER_SHAMBLER:
135                 {
136                         mid2info_model = SHAMBLER_MODEL;
137                         mid2info_name = "Shambler";
138                         mid2info_min = SHAMBLER_MIN;
139                         mid2info_max = SHAMBLER_MAX;
140                         break;
141                 }
142                 case MONSTER_KNIGHT:
143                 {
144                         mid2info_model = KNIGHT_MODEL;
145                         mid2info_name = "Knight";
146                         mid2info_min = KNIGHT_MIN;
147                         mid2info_max = KNIGHT_MAX;
148                         break;
149                 }
150                 case MONSTER_MARINE:
151                 {
152                         mid2info_model = SOLDIER_MODEL;
153                         mid2info_name = "Marine";
154                         mid2info_min = SOLDIER_MIN;
155                         mid2info_max = SOLDIER_MAX;
156                         break;
157                 }
158                 case MONSTER_SCRAG:
159                 {
160                         mid2info_model = WIZARD_MODEL;
161                         mid2info_name = "Scrag";
162                         mid2info_min = WIZARD_MIN;
163                         mid2info_max = WIZARD_MAX;
164                         break;
165                 }
166                 case MONSTER_DOG:
167                 {
168                         mid2info_model = DOG_MODEL;
169                         mid2info_name = "Cerberus";
170                         mid2info_min = DOG_MIN;
171                         mid2info_max = DOG_MAX;
172                         break;
173                 }
174                 case MONSTER_TARBABY:
175                 {
176                         mid2info_model = TARBABY_MODEL;
177                         mid2info_name = "Spawn";
178                         mid2info_min = TARBABY_MIN;
179                         mid2info_max = TARBABY_MAX;
180                         break;
181                 }
182                 case MONSTER_HELLKNIGHT:
183                 {
184                         mid2info_model = HELLKNIGHT_MODEL;
185                         mid2info_name = "Hell-Knight";
186                         mid2info_min = HELLKNIGHT_MIN;
187                         mid2info_max = HELLKNIGHT_MAX;
188                         break;
189                 }
190                 case MONSTER_FISH:
191                 {
192                         mid2info_model = FISH_MODEL;
193                         mid2info_name = "Rotfish";
194                         mid2info_min = FISH_MIN;
195                         mid2info_max = FISH_MAX;
196                         break;
197                 }
198                 case MONSTER_MAGE:
199                 {
200                         mid2info_model = SHALRATH_MODEL;
201                         mid2info_name = "Mage";
202                         mid2info_min = SHALRATH_MIN;
203                         mid2info_max = SHALRATH_MAX;
204                         break;
205                 }
206                 case MONSTER_ENFORCER:
207                 {
208                         mid2info_model = ENFORCER_MODEL;
209                         mid2info_name = "Enforcer";
210                         mid2info_min = ENFORCER_MIN;
211                         mid2info_max = ENFORCER_MAX;
212                         break;
213                 }
214                 case MONSTER_SPIDER:
215                 {
216                         mid2info_model = SPIDER_MODEL;
217                         mid2info_name = "Spider";
218                         mid2info_min = SPIDER_MIN;
219                         mid2info_max = SPIDER_MAX;
220                         break;
221                 }
222                 default:
223                 {
224                         dprint("WARNING: Unknown monster in CSQC\n");
225                         break;
226                 }
227         }       
228 }
229
230 .vector glowmod;
231 void monster_changeteam()
232 {       
233         switch(self.team - 1)
234         {
235                 case NUM_TEAM_1: // Red
236                 {
237                         self.glowmod = '2 0 0';
238                         self.teamradar_color = '1 0 0';
239                         break;
240                 }
241                 case NUM_TEAM_2: // Blue
242                 {
243                         self.glowmod = '0 0 2';
244                         self.teamradar_color = '0 0 1';
245                         break;
246                 }
247                 case NUM_TEAM_3: // Yellow
248                 {
249                         self.glowmod = '1 1 0';
250                         self.teamradar_color = '1 1 0';
251                         break;
252                 }
253                 case NUM_TEAM_4: // Pink
254                 {
255                         self.glowmod = '1 0 1';
256                         self.teamradar_color = '1 0 1';
257                         break;
258                 }
259         }
260         
261         if(self.team)
262                 self.colormap = 1024 + (self.team - 1) * 17;
263 }
264
265 void monster_die()
266 {
267         if(self.monsterid == MONSTER_SPIDER)
268                 self.angles += '180 0 0';
269                 
270         self.solid = SOLID_CORPSE;
271 }
272
273 void monster_draw()
274 {        
275     float dt;
276             
277     dt = time - self.move_time;
278     self.move_time = time;
279     if(dt <= 0)
280         return;
281     
282     fixedmakevectors(self.angles);
283     //movelib_groundalign4point(300, 100, 0.25, 45);
284     setorigin(self, self.origin + self.velocity * dt);
285     self.angles_y = self.move_angles_y;  
286 }
287
288 void monster_construct()
289 {       
290         monster_mid2info(self.monsterid);
291         self.netname = mid2info_name;
292
293         setorigin(self, self.origin);
294         setmodel(self, mid2info_model);
295         setsize(self, mid2info_min, mid2info_max);
296         
297         self.move_movetype      = MOVETYPE_BOUNCE;
298         self.health                     = 255;
299         self.solid                      = SOLID_BBOX;
300         self.movetype           = MOVETYPE_BOUNCE; 
301         self.move_origin        = self.origin;
302         self.move_time          = time;
303         self.drawmask           = MASK_NORMAL;  
304         self.alpha                      = 1;
305         self.draw                       = monster_draw;
306 }
307
308 void ent_monster()
309 {
310         float sf;
311         sf = ReadByte();
312
313         if(sf & MSF_SETUP)
314         {               
315                 self.monsterid = ReadByte();
316                                 
317                 self.origin_x = ReadCoord();
318                 self.origin_y = ReadCoord();
319                 self.origin_z = ReadCoord();
320                 setorigin(self, self.origin);
321                 
322                 self.angles_x = ReadAngle();
323                 self.angles_y = ReadAngle();
324                 
325                 self.scale = ReadByte();
326                 self.skin = ReadByte();
327                 
328                 monster_precache(self.monsterid);
329                 monster_construct();
330                 self.colormap = 1024;
331                 self.glowmod = '0 1 1'; 
332         }
333         
334         if(sf & MSF_SIZE)
335         {
336                 self.scale = ReadByte();
337                 self.mins_x = ReadCoord();
338                 self.mins_y = ReadCoord();
339                 self.mins_z = ReadCoord();
340                 
341                 self.maxs_x = ReadCoord();
342                 self.maxs_y = ReadCoord();
343                 self.maxs_z = ReadCoord();
344
345                 setsize(self, self.mins, self.maxs);
346         }
347         
348         if(sf & MSF_ANG)
349         {
350                 self.move_angles_x = ReadShort();
351                 self.move_angles_y = ReadShort();
352                 self.angles = self.move_angles;
353         }
354         
355         if(sf & MSF_MOVE)
356         {
357                 self.origin_x = ReadShort();
358                 self.origin_y = ReadShort();
359                 self.origin_z = ReadShort();
360                 setorigin(self, self.origin);
361                 
362                 self.velocity_x = ReadShort();
363                 self.velocity_y = ReadShort();
364                 self.velocity_z = ReadShort();
365                 
366                 self.move_angles_y = ReadShort();
367                         
368                 self.move_time   = time;
369                 self.move_velocity = self.velocity;
370                 self.move_origin   = self.origin;
371         }
372                 
373         if(sf & MSF_ANIM)
374         {
375                 self.frame1time = ReadCoord();
376                 self.frame        = ReadByte();
377         }
378
379         if(sf & MSF_STATUS)
380         {
381                 self.skin = ReadByte();
382         
383                 float _tmp;
384                 _tmp = ReadByte();
385                 if(_tmp != self.team)
386                 {                       
387                         self.team = _tmp;                               
388                         monster_changeteam();
389                 }
390                 
391                 _tmp = ReadByte();
392                 
393                 if(_tmp == 0 && self.health != 0)
394                         monster_die();
395
396                 self.health = _tmp;
397         }
398 }