]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/monsters.qc
Rename rotfish to stingray
[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_ANIMUS:
28                 {
29                         precache_model(ANIMUS_MODEL);
30                         break;
31                 }
32                 case MONSTER_SHAMBLER:
33                 {
34                         precache_model(SHAMBLER_MODEL);
35                         break;
36                 }
37                 case MONSTER_BRUISER:
38                 {
39                         precache_model(BRUISER_MODEL);
40                         break;
41                 }
42                 case MONSTER_WYVERN:
43                 {
44                         precache_model(WYVERN_MODEL);
45                         break;
46                 }
47                 case MONSTER_CERBERUS:
48                 {
49                         precache_model(CERBERUS_MODEL);
50                         break;
51                 }
52                 case MONSTER_SLIME:
53                 {
54                         precache_model(SLIME_MODEL);
55                         precache_sound("weapons/rocket_impact.wav");
56                         break;
57                 }
58                 case MONSTER_KNIGHT:
59                 {
60                         precache_model(KNIGHT_MODEL);
61                         break;
62                 }
63                 case MONSTER_STINGRAY:
64                 {
65                         precache_model(STINGRAY_MODEL);
66                         break;
67                 }
68                 case MONSTER_MAGE:
69                 {
70                         precache_model(MAGE_MODEL);
71                         break;
72                 }
73                 case MONSTER_SPIDER:
74                 {
75                         precache_model(SPIDER_MODEL);
76
77                         break;
78                 }
79     }    
80     monster_precached[_mid] = TRUE;
81 }
82
83 void Monsters_Precache()
84 {
85         float i;
86         for(i = MONSTER_FIRST + 1; i < MONSTER_LAST; ++i)
87                 monster_precache(i);
88 }
89
90 void monster_mid2info(float _mid)
91 {
92         switch(_mid)
93         {
94                 case MONSTER_ZOMBIE:
95                 {
96                         mid2info_model = ZOMBIE_MODEL;
97                         mid2info_name = "Zombie";
98                         mid2info_min = ZOMBIE_MIN;
99                         mid2info_max = ZOMBIE_MAX;
100                         break;
101                 }
102                 case MONSTER_OGRE:
103                 {
104                         mid2info_model = OGRE_MODEL;
105                         mid2info_name = "Ogre";
106                         mid2info_min = OGRE_MIN;
107                         mid2info_max = OGRE_MAX;
108                         break;
109                 }
110                 case MONSTER_ANIMUS:
111                 {
112                         mid2info_model = ANIMUS_MODEL;
113                         mid2info_name = "Animus";
114                         mid2info_min = ANIMUS_MIN;
115                         mid2info_max = ANIMUS_MAX;
116                         if(self) self.scale = 1.3;
117                         break;
118                 }
119                 case MONSTER_SHAMBLER:
120                 {
121                         mid2info_model = SHAMBLER_MODEL;
122                         mid2info_name = "Shambler";
123                         mid2info_min = SHAMBLER_MIN;
124                         mid2info_max = SHAMBLER_MAX;
125                         if(self) self.scale = 1.3;
126                         break;
127                 }
128                 case MONSTER_BRUISER:
129                 {
130                         mid2info_model = BRUISER_MODEL;
131                         mid2info_name = "Bruiser";
132                         mid2info_min = BRUISER_MIN;
133                         mid2info_max = BRUISER_MAX;
134                         if(self) self.scale = 1.3;
135                         break;
136                 }
137                 case MONSTER_WYVERN:
138                 {
139                         mid2info_model = WYVERN_MODEL;
140                         mid2info_name = "Wyvern";
141                         mid2info_min = WYVERN_MIN;
142                         mid2info_max = WYVERN_MAX;
143                         if(self) self.scale = 1.3;
144                         break;
145                 }
146                 case MONSTER_CERBERUS:
147                 {
148                         mid2info_model = CERBERUS_MODEL;
149                         mid2info_name = "Cerberus";
150                         mid2info_min = CERBERUS_MIN;
151                         mid2info_max = CERBERUS_MAX;
152                         break;
153                 }
154                 case MONSTER_SLIME:
155                 {
156                         mid2info_model = SLIME_MODEL;
157                         mid2info_name = "Slime";
158                         mid2info_min = SLIME_MIN;
159                         mid2info_max = SLIME_MAX;
160                         break;
161                 }
162                 case MONSTER_KNIGHT:
163                 {
164                         mid2info_model = KNIGHT_MODEL;
165                         mid2info_name = "Knight";
166                         mid2info_min = KNIGHT_MIN;
167                         mid2info_max = KNIGHT_MAX;
168                         if(self) self.scale = 1.3;
169                         break;
170                 }
171                 case MONSTER_STINGRAY:
172                 {
173                         mid2info_model = STINGRAY_MODEL;
174                         mid2info_name = "Stingray";
175                         mid2info_min = STINGRAY_MIN;
176                         mid2info_max = STINGRAY_MAX;
177                         if(self) self.scale = 1.3;
178                         break;
179                 }
180                 case MONSTER_MAGE:
181                 {
182                         mid2info_model = MAGE_MODEL;
183                         mid2info_name = "Mage";
184                         mid2info_min = MAGE_MIN;
185                         mid2info_max = MAGE_MAX;
186                         break;
187                 }
188                 case MONSTER_SPIDER:
189                 {
190                         mid2info_model = SPIDER_MODEL;
191                         mid2info_name = "Spider";
192                         mid2info_min = SPIDER_MIN;
193                         mid2info_max = SPIDER_MAX;
194                         break;
195                 }
196                 default:
197                 {
198                         dprint("WARNING: Unknown monster in CSQC\n");
199                         break;
200                 }
201         }       
202 }
203
204 .vector glowmod;
205 void monster_changeteam()
206 {       
207         self.glowmod = Team_ColorRGB(self.team - 1);
208         self.teamradar_color = Team_ColorRGB(self.team - 1);
209         
210         if(self.team)
211                 self.colormap = 1024 + (self.team - 1) * 17;
212         else
213                 self.colormap = 1024;
214 }
215
216 void monster_die()
217 {
218         if(self.monsterid == MONSTER_SPIDER)
219                 self.angles += '180 0 0';
220                 
221         self.solid = SOLID_CORPSE;
222 }
223
224 void monster_draw()
225 {        
226     float dt;
227             
228     dt = time - self.move_time;
229     self.move_time = time;
230     if(dt <= 0)
231         return;
232     
233     fixedmakevectors(self.angles);
234     //movelib_groundalign4point(300, 100, 0.25, 45);
235     setorigin(self, self.origin + self.velocity * dt);
236     self.angles_y = self.move_angles_y;  
237 }
238
239 void monster_construct()
240 {       
241         monster_mid2info(self.monsterid);
242         self.netname = mid2info_name;
243
244         setorigin(self, self.origin);
245         setmodel(self, mid2info_model);
246         setsize(self, mid2info_min, mid2info_max);
247         
248         self.move_movetype      = MOVETYPE_BOUNCE;
249         self.health                     = 255;
250         self.solid                      = SOLID_BBOX;
251         self.movetype           = MOVETYPE_BOUNCE; 
252         self.move_origin        = self.origin;
253         self.move_time          = time;
254         self.drawmask           = MASK_NORMAL;  
255         self.alpha                      = 1;
256         self.draw                       = monster_draw;
257 }
258
259 void ent_monster()
260 {
261         float sf;
262         sf = ReadByte();
263
264         if(sf & MSF_SETUP)
265         {
266                 self.monsterid = ReadByte();
267                                 
268                 self.origin_x = ReadCoord();
269                 self.origin_y = ReadCoord();
270                 self.origin_z = ReadCoord();
271                 setorigin(self, self.origin);
272                 
273                 self.angles_x = ReadAngle();
274                 self.angles_y = ReadAngle();
275                 
276                 self.skin = ReadByte();
277                 self.team = ReadByte();
278                 
279                 monster_precache(self.monsterid);
280                 monster_construct();
281                 monster_changeteam();
282         }
283         
284         if(sf & MSF_ANG)
285         {
286                 self.move_angles_x = ReadShort();
287                 self.move_angles_y = ReadShort();
288                 self.angles = self.move_angles;
289         }
290         
291         if(sf & MSF_MOVE)
292         {
293                 self.origin_x = ReadShort();
294                 self.origin_y = ReadShort();
295                 self.origin_z = ReadShort();
296                 setorigin(self, self.origin);
297                 
298                 self.velocity_x = ReadShort();
299                 self.velocity_y = ReadShort();
300                 self.velocity_z = ReadShort();
301                 
302                 self.move_angles_y = ReadShort();
303                         
304                 self.move_time   = time;
305                 self.move_velocity = self.velocity;
306                 self.move_origin   = self.origin;
307         }
308                 
309         if(sf & MSF_ANIM)
310         {
311                 self.frame1time = ReadCoord();
312                 self.frame        = ReadByte();
313         }
314
315         if(sf & MSF_STATUS)
316         {
317                 self.skin = ReadByte();
318         
319                 float _tmp;
320                 _tmp = ReadByte();
321                 if(_tmp != self.team)
322                 {                       
323                         self.team = _tmp;                               
324                         monster_changeteam();
325                 }
326                 
327                 _tmp = ReadByte();
328                 if(_tmp == 4) // respawning
329                         setmodel(self, "null");
330                 
331                 _tmp = ReadByte();
332                 
333                 if(_tmp == 0 && self.health != 0)
334                         monster_die();
335
336                 self.health = _tmp;
337         }
338 }