home *** CD-ROM | disk | FTP | other *** search
- /* ALL MONSTERS SHOULD BE 1 0 0 IN COLOR */
-
- // name =[framenum, nexttime, nextthink] {code}
- // expands to:
- // name ()
- // {
- // self.frame=framenum;
- // self.nextthink = time + nexttime;
- // self.think = nextthink
- // <code>
- // };
-
-
- /*
- ================
- monster_use
-
- Using a monster makes it angry at the current activator
- ================
- */
- void() monster_use =
- {
- if (self.enemy)
- return;
- if (self.health <= 0)
- return;
- if (activator.items & IT_INVISIBILITY)
- return;
- if (activator.flags & FL_NOTARGET)
- return;
- if (activator.classname != "player")
- return;
-
- // delay reaction so if the monster is teleported, its sound is still
- // heard
- self.enemy = activator;
- self.nextthink = time + 0.1;
- self.think = FoundTarget;
- };
-
- /*
- ================
- monster_death_use
-
- When a mosnter dies, it fires all of its targets with the current
- enemy as activator.
- ================
- */
- void() monster_death_use =
- {
- local entity ent, otemp, stemp;
-
- // fall to ground
- if (self.flags & FL_FLY)
- self.flags = self.flags - FL_FLY;
- if (self.flags & FL_SWIM)
- self.flags = self.flags - FL_SWIM;
-
- if (!self.target)
- return;
-
- activator = self.enemy;
- SUB_UseTargets ();
- };
-
-
- //============================================================================
-
- void() walkmonster_start_go =
- {
- local string stemp;
- local entity etemp;
-
- self.origin_z = self.origin_z + 1; // raise off floor a bit
- droptofloor();
-
- if (!walkmove(0,0))
- {
- dprint ("walkmonster in wall at: ");
- dprint (vtos(self.origin));
- dprint ("\n");
- }
-
- self.takedamage = DAMAGE_AIM;
-
- self.ideal_yaw = self.angles * '0 1 0';
- if (!self.yaw_speed)
- self.yaw_speed = 20;
- self.view_ofs = '0 0 25';
- self.use = monster_use;
-
- self.flags = self.flags | FL_MONSTER;
-
- if (self.target)
- {
- self.goalentity = self.movetarget = find(world, targetname, self.target);
- self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
- if (!self.movetarget)
- {
- dprint ("Monster can't find target at ");
- dprint (vtos(self.origin));
- dprint ("\n");
- }
- // this used to be an objerror
- if (self.movetarget.classname == "path_corner")
- self.th_walk ();
- else
- self.pausetime = 99999999;
- self.th_stand ();
- }
- else
- {
- self.pausetime = 99999999;
- self.th_stand ();
- }
-
- // spread think times so they don't all happen at same time
- self.nextthink = self.nextthink + random()*0.5;
- };
-
-
- void() walkmonster_start =
- {
- // delay drop to floor to make sure all doors have been spawned
- // spread think times so they don't all happen at same time
- self.nextthink = self.nextthink + random()*0.5;
- self.think = walkmonster_start_go;
- total_monsters = total_monsters + 1;
- };
-
-
-
- void() flymonster_start_go =
- {
- self.takedamage = DAMAGE_AIM;
-
- self.ideal_yaw = self.angles * '0 1 0';
- if (!self.yaw_speed)
- self.yaw_speed = 10;
- self.view_ofs = '0 0 25';
- self.use = monster_use;
-
- self.flags = self.flags | FL_FLY;
- self.flags = self.flags | FL_MONSTER;
-
- if (!walkmove(0,0))
- {
- dprint ("flymonster in wall at: ");
- dprint (vtos(self.origin));
- dprint ("\n");
- }
-
- if (self.target)
- {
- self.goalentity = self.movetarget = find(world, targetname, self.target);
- if (!self.movetarget)
- {
- dprint ("Monster can't find target at ");
- dprint (vtos(self.origin));
- dprint ("\n");
- }
- // this used to be an objerror
- if (self.movetarget.classname == "path_corner")
- self.th_walk ();
- else
- self.pausetime = 99999999;
- self.th_stand ();
- }
- else
- {
- self.pausetime = 99999999;
- self.th_stand ();
- }
- };
-
- void() flymonster_start =
- {
- // spread think times so they don't all happen at same time
- self.nextthink = self.nextthink + random()*0.5;
- self.think = flymonster_start_go;
- total_monsters = total_monsters + 1;
- };
-
-
- void() swimmonster_start_go =
- {
- if (deathmatch)
- {
- remove(self);
- return;
- }
-
- self.takedamage = DAMAGE_AIM;
- total_monsters = total_monsters + 1;
-
- self.ideal_yaw = self.angles * '0 1 0';
- if (!self.yaw_speed)
- self.yaw_speed = 10;
- self.view_ofs = '0 0 10';
- self.use = monster_use;
-
- self.flags = self.flags | FL_SWIM;
- self.flags = self.flags | FL_MONSTER;
-
- if (self.target)
- {
- self.goalentity = self.movetarget = find(world, targetname, self.target);
- if (!self.movetarget)
- {
- dprint ("Monster can't find target at ");
- dprint (vtos(self.origin));
- dprint ("\n");
- }
- // this used to be an objerror
- self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
- self.th_walk ();
- }
- else
- {
- self.pausetime = 99999999;
- self.th_stand ();
- }
-
- // spread think times so they don't all happen at same time
- self.nextthink = self.nextthink + random()*0.5;
- };
-
- void() swimmonster_start =
- {
- // spread think times so they don't all happen at same time
- self.nextthink = self.nextthink + random()*0.5;
- self.think = swimmonster_start_go;
- total_monsters = total_monsters + 1;
- };
-
- /*
- * Corpse-related material
- * By AsmodeusB
- * It's a solid corpse which can be gibbed, and moved (by running into it).
- * Also, it falls down if you push it off a cliff. ;)
- * It can't be pushed up something (that's what kicking's for) ;)
- */
-
-
- void() CorpsePain =
- {
- local float t;
-
- SpawnMeatSpray (self.origin, crandom() * 100 * v_right);
- t = random() * 25;
- SpawnBlood(self.origin, crandom() * 100 * v_right, t);
- t = random() * 25;
- SpawnBlood(self.origin, crandom() * -150 * v_right, t);
- t = random() * 25;
- SpawnBlood(self.origin, crandom() * 70 * v_right, t);
- t = random() * 25;
- SpawnBlood(self.origin, crandom() * -50 * v_right, t);
- };
-
- void() CorpseMove =
- {
- local float dir;
-
- if(other.takedamage != DAMAGE_AIM) // not living
- return;
-
- self.velocity_x = other.velocity_x/3;
- self.velocity_y = other.velocity_y/3;
- // no z or we can push the corpse into the ground
-
- if(self.flags & FL_ONGROUND)
- self.flags = self.flags - FL_ONGROUND;
- };
-
- void() CorpseDie =
- {
- local float i, j, num_gibs;
-
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- // MakeSolidCorpse() sets netname to the head model
- // don't throw the head if massive damage
- if(self.health > -35)
- ThrowHead (self.netname, self.health);
- i = 0;
- num_gibs = random() * 6;
- num_gibs = rint(num_gibs);
- while(i<num_gibs)
- {
- j = random();
- if(j > 0.6)
- ThrowGib ("progs/gib1.mdl", self.health);
- else if(j > 0.3)
- ThrowGib ("progs/gib2.mdl", self.health);
- else
- ThrowGib ("progs/gib3.mdl", self.health);
- i = i + 1;
- }
- };
-
-
- /*
- * This uses entity.netname to hold the head file (for CorpseDie())
- * hack so that we don't have to set anything outside this function.
- */
-
- void(string headmdl) MakeSolidCorpse =
- {
- // Make a gibbable corpse, change the size so we can jump on it
-
- self.health = 40;
- // DAMAGE_AIM so that grenades don't bounce off like they do for DAMAGE_YES
- self.takedamage = DAMAGE_AIM;
- self.solid = SOLID_BBOX;
- self.movetype = MOVETYPE_STEP;
- self.flags = self.flags & (!FL_MONSTER);
- setsize(self, '-32 -32 -24', '32 32 10');
- self.th_stand = SUB_Null;
- self.th_walk = SUB_Null;
- self.th_run = SUB_Null;
- self.th_pain = CorpsePain;
- self.th_melee = SUB_Null;
- self.th_missile = SUB_Null;
- self.th_die = CorpseDie;
- self.touch = CorpseMove;
- self.netname = headmdl;
- };
-
-
-