mirror of
https://github.com/id-Software/quake-rerelease-qc.git
synced 2026-03-19 16:39:51 +01:00
Initial commit of Update 3 QuakeC
This commit is contained in:
265
quakec_rogue/monsters.qc
Normal file
265
quakec_rogue/monsters.qc
Normal file
@@ -0,0 +1,265 @@
|
||||
/* Copyright (C) 1996-2022 id Software LLC
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
See file, 'COPYING', for details.
|
||||
*/
|
||||
|
||||
/* 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!\n");
|
||||
dprint (self.classname);
|
||||
dprint (" 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.team = TEAM_MONSTERS;
|
||||
|
||||
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.team = TEAM_MONSTERS;
|
||||
|
||||
self.flags = self.flags | FL_FLY;
|
||||
self.flags = self.flags | FL_MONSTER;
|
||||
|
||||
if (!walkmove(0,0))
|
||||
{
|
||||
dprint ("flymonster in wall!\n");
|
||||
dprint (self.classname);
|
||||
dprint (" 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.team = TEAM_MONSTERS;
|
||||
|
||||
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;
|
||||
|
||||
// Don't count here. swimmonster_start_go already increments
|
||||
// the monster count!!!
|
||||
// total_monsters = total_monsters + 1;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user