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