djcev.com

//

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.