1 /* ALL MONSTERS SHOULD BE 1 0 0 IN COLOR */
3 // name =[framenum, nexttime, nextthink] {code}
7 // self.frame=framenum;
8 // self.nextthink = time + nexttime;
9 // self.think = nextthink
21 Using a monster makes it angry at the current activator
22 LordHavoc: using a monster with the spawnflag 'Appear' makes it appear
32 if (self.spawnflags & MONSTER_APPEAR)
34 self.nextthink = time + 0.1;
35 self.spawnflags = self.spawnflags - MONSTER_APPEAR;
36 self.solid = SOLID_SLIDEBOX;
37 self.takedamage = DAMAGE_AIM;
38 //self.movetype = MOVETYPE_STEP;
39 self.model = self.mdl;
41 self.modelindex = self.modelindex2;
43 //setorigin(self, self.origin + '0 0 1');
44 spawn_tdeath(self.origin, self, self.origin);
49 if (activator.items & IT_INVISIBILITY)
52 if (activator.flags & FL_NOTARGET)
54 if (activator.classname != "player")
57 // delay reaction so if the monster is teleported, its sound is still heard
58 self.enemy = activator;
59 self.nextthink = time + 0.1;
60 self.think = FoundTarget;
63 void() monster_appearsetup =
65 if ((self.spawnflags & MONSTER_APPEAR) == 0)
67 self.mdl = self.model;
68 self.modelindex2 = self.modelindex;
70 self.solid = SOLID_NOT;
71 self.takedamage = DAMAGE_NO;
72 //self.movetype = MOVETYPE_NONE;
81 Sets relative alpha of monster in skill 4 mode.
84 void(float a) monster_setalpha =
86 if (skill < 4 || self.classname == "monster_hellfish")
94 // randomly forget enemy, this makes monsters randomly return to their normal ghostlike state
99 // randomly blink (playing the same alarming sound as if attacking)
100 if (self.enemy == world)
103 if (time >= 0.3) // don't blink during the init process because it might become permanent
104 if (random() < 0.005)
106 // blink for an instant, this causes the appear sound, alarming the player as if under attack
107 /* PLEASE FIX THE SOUND CHANNEL BEFORE ACTIVATING THIS
108 sound(self, CHAN_AUTO, "wizard/wsight.wav", 1, ATTN_NORM);
113 // if ghosted, become non-solid and immune to damage
114 if (a <= 0 || self.enemy == world)
116 self.solid = SOLID_NOT;
117 self.takedamage = DAMAGE_NO;
121 // if unghosting, make sure we have an enemy, otherwise stay ghosted (even if blinking) so we can't be shot while blinking
122 /* PLEASE FIX THE SOUND CHANNEL BEFORE ACTIVATING THIS
123 if (self.solid != SOLID_SLIDEBOX)
124 sound(self, CHAN_AUTO, "wizard/wsight.wav", 1, ATTN_NORM);
126 self.solid = SOLID_SLIDEBOX;
127 self.takedamage = DAMAGE_AIM;
130 self.alpha = SKILL4_MINALPHA + (1 - SKILL4_MINALPHA) * bound(0, a, 1);
137 When a mosnter dies, it fires all of its targets with the current
141 void() monster_death_use =
144 if (self.flags & FL_FLY)
145 self.flags = self.flags - FL_FLY;
146 if (self.flags & FL_SWIM)
147 self.flags = self.flags - FL_SWIM;
152 activator = self.enemy;
157 void() monsterinwall =
160 if (!autocvar_developer)
162 // this is handy for level designers,
163 // puts a spikey ball where the error is...
165 setorigin(e, self.origin);
166 setmodel (e, "models/ebomb.mdl");
167 e.movetype = MOVETYPE_NONE;
174 //============================================================================
176 void() walkmonster_start_go =
178 self.origin_z = self.origin_z + 1; // raise off floor a bit
180 tracebox(self.origin, self.mins, self.maxs, self.origin, TRUE, self);
181 if (trace_startsolid)
183 dprint("walkmonster in wall at: ");
184 dprint(vtos(self.origin));
194 dprint("walkmonster in wall at: ");
195 dprint(vtos(self.origin));
201 //self.cantrigger = TRUE;
203 self.takedamage = DAMAGE_AIM;
205 self.ideal_yaw = self.angles * '0 1 0';
208 self.view_ofs = '0 0 25';
209 self.use = monster_use;
211 self.flags = self.flags | FL_MONSTER;
214 self.spawnflags = self.spawnflags | MONSTER_WANDER;
218 self.goalentity = self.movetarget = find(world, targetname, self.target);
219 self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
220 if (!self.movetarget)
222 dprint("Monster can't find target at ");
223 dprint(vtos(self.origin));
226 // this used to be an objerror
227 if (self.movetarget.classname == "path_corner")
231 if ((self.spawnflags & MONSTER_WANDER) && (!self.monsterawaitingteleport) && (self.spawnflags & 3) == 0 && (world.model != "maps/e1m7.bsp"))
233 monster_spawnwanderpath();
234 self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
239 self.pausetime = 99999999;
246 if ((self.spawnflags & MONSTER_WANDER) && (!self.monsterawaitingteleport) && (self.spawnflags & 3) == 0 && (world.model != "maps/e1m7.bsp"))
248 monster_spawnwanderpath();
249 self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
254 self.pausetime = 99999999;
259 // spread think times so they don't all happen at same time
260 self.nextthink = self.nextthink + random()*0.5 + 0.1;
261 self.iscreature = TRUE;
262 self.teleportable = TELEPORT_NORMAL;
263 self.damagedbycontents = TRUE;
265 force_retouch = 2; // mainly to detect teleports
267 monster_appearsetup();
271 void() walkmonster_start =
273 self.candrown = 1; // this is turned off by some monsters like zombies
274 // delay drop to floor to make sure all doors have been spawned
275 // spread think times so they don't all happen at same time
276 self.nextthink = time + random()*0.5 + 0.3;
277 self.think = walkmonster_start_go;
278 total_monsters = total_monsters + 1;
279 self.bot_attack = TRUE;
280 self.frags = 2; // actually just used to get havocbots to attack it...
281 self.bleedfunc = genericbleedfunc;
282 self.ismonster = TRUE;
284 monster_setalpha (0);
289 void() flymonster_start_go =
291 self.takedamage = DAMAGE_AIM;
293 self.ideal_yaw = self.angles * '0 1 0';
296 self.view_ofs = '0 0 25';
297 self.use = monster_use;
299 self.flags = self.flags | FL_FLY;
300 self.flags = self.flags | FL_MONSTER;
304 dprint("flymonster in wall at: ");
305 dprint(vtos(self.origin));
310 //self.cantrigger = TRUE;
313 self.spawnflags = self.spawnflags | MONSTER_WANDER;
317 self.goalentity = self.movetarget = find(world, targetname, self.target);
318 if (!self.movetarget)
320 dprint("Monster can't find target at ");
321 dprint(vtos(self.origin));
324 // this used to be an objerror
325 if (self.movetarget.classname == "path_corner")
329 if ((self.spawnflags & MONSTER_WANDER) && (!self.monsterawaitingteleport) && (self.spawnflags & 3) == 0 && (world.model != "maps/e1m7.bsp"))
331 monster_spawnwanderpath();
332 self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
337 self.pausetime = 99999999;
344 if ((self.spawnflags & MONSTER_WANDER) && (!self.monsterawaitingteleport) && (self.spawnflags & 3) == 0 && (world.model != "maps/e1m7.bsp"))
346 monster_spawnwanderpath();
347 self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
352 self.pausetime = 99999999;
356 self.iscreature = TRUE;
357 self.teleportable = TELEPORT_NORMAL;
358 self.damagedbycontents = TRUE;
360 force_retouch = 2; // mainly to detect teleports
362 monster_appearsetup();
365 void() flymonster_start =
368 // spread think times so they don't all happen at same time
369 self.nextthink = time + random()*0.5 + 0.1;
370 self.think = flymonster_start_go;
371 total_monsters = total_monsters + 1;
372 self.bot_attack = TRUE;
373 self.frags = 2; // actually just used to get havocbots to attack it...
374 self.bleedfunc = genericbleedfunc;
375 self.ismonster = TRUE;
377 monster_setalpha (0);
381 void() swimmonster_start_go =
389 //self.cantrigger = TRUE;
391 self.takedamage = DAMAGE_AIM;
393 self.ideal_yaw = self.angles * '0 1 0';
396 self.view_ofs = '0 0 10';
397 self.use = monster_use;
399 self.flags = self.flags | FL_SWIM;
400 self.flags = self.flags | FL_MONSTER;
403 self.spawnflags = self.spawnflags | MONSTER_WANDER;
407 self.goalentity = self.movetarget = find(world, targetname, self.target);
408 if (!self.movetarget)
410 dprint("Monster can't find target at ");
411 dprint(vtos(self.origin));
414 // this used to be an objerror
415 if (self.movetarget.classname == "path_corner")
419 if ((self.spawnflags & MONSTER_WANDER) && (!self.monsterawaitingteleport) && (self.spawnflags & 3) == 0 && (world.model != "maps/e1m7.bsp"))
421 monster_spawnwanderpath();
422 self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
427 self.pausetime = 99999999;
434 if ((self.spawnflags & MONSTER_WANDER) && (!self.monsterawaitingteleport) && (self.spawnflags & 3) == 0 && (world.model != "maps/e1m7.bsp"))
436 monster_spawnwanderpath();
437 self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
442 self.pausetime = 99999999;
446 self.iscreature = TRUE;
447 self.teleportable = TELEPORT_NORMAL;
448 self.damagedbycontents = TRUE;
450 force_retouch = 2; // mainly to detect teleports
452 monster_appearsetup();
455 void() swimmonster_start =
457 // spread think times so they don't all happen at same time
459 self.nextthink = time + random()*0.5 + 0.1;
460 self.think = swimmonster_start_go;
461 total_monsters = total_monsters + 1;
462 self.bot_attack = TRUE;
463 self.frags = 2; // actually just used to get havocbots to attack it...
464 self.bleedfunc = genericbleedfunc;
465 self.ismonster = TRUE;
470 void(vector org, float bodydamage, float armordamage, vector force, float damgtype) genericbleedfunc =
473 v = '0 0 0' - force * 0.05;
475 te_spark(org, v, armordamage * 3);
477 te_blood(org, v, bodydamage);