Git Repos / fte_dogmode / qc / func / monster_spawner.qc
Last update to this file was on 2024-04-08 at 15:40.
Show monster_spawner.qc
//==============================================================================
// func_monster_spawner -- mobot.qc
//==============================================================================
// Using "bot" creation code for func_monster_spawner
// most of the code is from a tutorial on creating a bot monster found here:
// https://www.quaddicted.com/webarchive/minion.planetquake.gamespy.com/tutorial/tutor9.htm
// I added the MobotSpawnPoint, retriggering and random gen with help from
// kreathor, 4LT, Paril, Spoike and others on the Quake Mapping Discord.
// ===================================================================
// Big thanks to ryanscissorhands for helping fix telefragging issues!
// ===================================================================
//======================================================================
// constants
//======================================================================
const float MOBOT_SPAWNER_RESET = 1;
const float MOBOT_DONT_SPAWN_ANGRY = 2;
const float MOBOT_DONT_ADD_KILL_COUNT = 4;
const float MOBOT_SILENT_SPAWN = 32;
//======================================================================
// forward declarations
//======================================================================
//------------------------------------------------------------------------------
/*QUAKED func_monster_spawner (.75 0 .75) (-8 -8 -8) (8 8 8) REUSABLE X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
Spawns monsters to targeted info_monster_spawnpoint
bot
Choose Style
• 1 (Dog (Default)
• 2 (Grunt)
• 3 (Enforcer)
• 4 (Ogre)
• 5 (Fiend)
• 6 (Wizard)
• 7 (Shambler)
• 8 (Knight)
• 9 (HellKnight)
• 11 (Zombie)
• 12 (Shalrath)
Style 2 set to 1 overrides Style and chooses a random monster (excluding Zombies and Vores)
Default time between spawns is 5 seconds; 12 for Zombies and Vores to reduce telefrags
Can set Berserk to 1 to skip most pain animations.
Can only use default health, models and sounds.
*/
//----------------------------------------------------------------------
// class func_monster_spawner: base_func
// {
//--------------------------------------------------------------
// find_spawnpoint -- Returns the entity to spawn at; was named
// MobotSpawnPoint
//--------------------------------------------------------------
entity() find_spawnpoint =
{
local entity spot;
// spot = find (world, classname, "info_monster_spawnpoint");
spot = find (world, targetname, self.target);
if (!spot)
objerror ("func_monster_spawner::find_spawnpoint: "
"couldn't find target!\n");
return spot;
};
//--------------------------------------------------------------
void(base_monster bot) create_mobot_tfrag =
{
if (!(self.spawnflags & MOBOT_SILENT_SPAWN))
// SILENT
spawn_tfog (bot.origin);
spawn_tdeath (bot.origin, bot);
};
//--------------------------------------------------------------
void() create_mobot =
{
// let's not use deathmatch points for self -- dumptruck_ds
// spawn_spot = SelectSpawnPoint ();
local entity spawn_spot = find_spawnpoint ();
local float angry;
if (self.spawnflags & MOBOT_DONT_SPAWN_ANGRY)
angry = FALSE;
else
angry = TRUE;
switch (self.style)
{
case 1:
// spawn a Doggo
monster_dog bot1 = spawn (monster_dog,
origin: spawn_spot.origin + '0 0 1',
angles: spawn_spot.angles,
yaw_speed: 120,
spawn_angry: angry,
fixangle: TRUE,
view_ofs: '0 0 22');
create_mobot_tfrag (bot1);
break;
case 2:
// spawn a Grunt
monster_army bot2 = spawn (monster_army,
origin: spawn_spot.origin + '0 0 1',
angles: spawn_spot.angles,
yaw_speed: 120,
spawn_angry: angry,
fixangle: TRUE,
view_ofs: '0 0 22');
create_mobot_tfrag (bot2);
break;
case 3:
// spawn an Enforcer
monster_enforcer bot3 = spawn (monster_enforcer,
origin: spawn_spot.origin + '0 0 1',
angles: spawn_spot.angles,
yaw_speed: 120,
spawn_angry: angry,
fixangle: TRUE,
view_ofs: '0 0 22');
create_mobot_tfrag (bot3);
break;
case 4:
// spawn an Ogre
monster_ogre bot4 = spawn (monster_ogre,
origin: spawn_spot.origin + '0 0 1',
angles: spawn_spot.angles,
yaw_speed: 120,
spawn_angry: angry,
fixangle: TRUE,
view_ofs: '0 0 22');
create_mobot_tfrag (bot4);
break;
case 5:
// spawn a Fiend
monster_demon1 bot5 = spawn (monster_demon1,
origin: spawn_spot.origin + '0 0 1',
angles: spawn_spot.angles,
yaw_speed: 120,
spawn_angry: angry,
fixangle: TRUE,
view_ofs: '0 0 22');
create_mobot_tfrag (bot5);
break;
case 6:
// spawn a Wizard / Scrag
monster_wizard bot6 = spawn (monster_wizard,
origin: spawn_spot.origin + '0 0 1',
angles: spawn_spot.angles,
mdl_proj: "progs/w_spike.mdl",
yaw_speed: 120,
spawn_angry: angry,
fixangle: TRUE,
view_ofs: '0 0 22');
create_mobot_tfrag (bot6);
break;
case 7:
// spawn a Shambler
monster_shambler bot7 = spawn (monster_shambler,
origin: spawn_spot.origin + '0 0 1',
angles: spawn_spot.angles,
yaw_speed: 120,
spawn_angry: angry,
fixangle: TRUE,
view_ofs: '0 0 2');
create_mobot_tfrag (bot7);
break;
case 8:
// spawn a Knight
monster_knight bot8 = spawn (monster_knight,
origin: spawn_spot.origin + '0 0 1',
angles: spawn_spot.angles,
yaw_speed: 120,
spawn_angry: angry,
fixangle: TRUE,
view_ofs: '0 0 22');
create_mobot_tfrag (bot8);
break;
case 9:
// spawn a HellKnight
monster_hell_knight bot9 = spawn (
monster_hell_knight,
origin: spawn_spot.origin + '0 0 1',
angles: spawn_spot.angles,
yaw_speed: 120,
spawn_angry: angry,
fixangle: TRUE,
view_ofs: '0 0 22');
create_mobot_tfrag (bot9);
break;
case 11:
// spawn a Zombie
monster_zombie botB = spawn (monster_zombie,
origin: spawn_spot.origin + '0 0 1',
angles: spawn_spot.angles,
yaw_speed: 120,
spawn_angry: angry,
fixangle: TRUE,
view_ofs: '0 0 2');
create_mobot_tfrag (botB);
break;
case 12:
// spawn a Shalrath
monster_shalrath botC = spawn (monster_shalrath,
origin: spawn_spot.origin + '0 0 1',
angles: spawn_spot.angles,
yaw_speed: 120,
spawn_angry: angry,
fixangle: TRUE,
view_ofs: '0 0 22');
create_mobot_tfrag (botC);
break;
default:
dprint (sprintf("func_monster_spawner::"
"create_mobot: unknown style %g!\n",
self.style));
}
if (!(self.spawnflags & MOBOT_DONT_ADD_KILL_COUNT))
// replacement function from iw -- dumptruck_ds
monster_update_total (1);
};
//--------------------------------------------------------------
void() do_think =
{
dprint ("mobot thinking\n");
// telefrag check thanks to ryanscissorhands for self code!
// -- dumptruck_ds
local entity nearby;
// findradius (vector origin, float radius in Quake units)
nearby = findradius (self.origin, 128);
while (nearby)
{
if (nearby.takedamage)
{
dprint ("monster waiting to spawn\n");
// qss crash fix from paavohuhtala
// -- dumptruck_ds
// delay the spawn by some amount;
self.nextthink = time + 1;
return;
}
nearby = nearby.chain;
}
self.count = self.count - 1;
if (self.count < 0)
return;
if (self.count != 0)
{
if !(self.wait)
self.nextthink = time + 5;
else
self.nextthink = time + self.wait;
if (self.style2 == 1)
{
// random monster!! -- dumptruck_ds
self.style = floor (random() * 12) + 1;
// re-roll 10s -- CEV
while (self.style == 10)
self.style = floor (random() * 12) + 1;
// thanks whirledtsar for your help on this
// -- dumptruck_ds
create_mobot ();
}
else
{
create_mobot ();
}
}
else
{
if (self.spawnflags & MOBOT_SPAWNER_RESET)
{
self.count = self.cnt;
self.interaction_flags |= DISABLE_THINK;
}
}
};
//--------------------------------------------------------------
void(entity caller) do_use =
{
self.do_think ();
};
//--------------------------------------------------------------
void() init_spawned =
{
if !(this.target)
{
objerror ("func_monster_spawner needs a target");
remove (this);
return;
}
if !(this.style)
this.style = 1;
if (!this.count)
this.count = 5;
// fixes count display
this.count = this.count + 1;
// hold original count
this.cnt = this.count;
};
//--------------------------------------------------------------
void() func_monster_spawner =
{
this.classtype = CT_FUNC_MONSTER_SPAWNER;
};
// };
Return to the top of this page or return to the overview of this repo.
Log monster_spawner.qc
Date | Commit Message | Author | + | - |
---|---|---|---|---|
2024-04-08 | Registered monsters, projectile bugfixes | cev | +47 | -54 |
2024-02-18 | Client/player, projectiles, entrypoints refactor | cev | +141 | -436 |
2024-01-31 | Class based monster refactor & start projectiles | cev | +58 | -3 |
2024-01-09 | Continue OO / Class-based refactor | cev | +514 | -503 |
2023-11-27 | Code reorg, minor movement changes, misc | cev | +565 |
Return to the top of this page or return to the overview of this repo.