Magicians can pull a rabbit out of a hat. I'll teach you how to pull an ogre out of thin air.
Yes, it's time to stop screwing around with wimpy tutorials and get to the real deal, how to spawn a mobot. We will run into a contradiction while doing this: spawning a monster bot is very simple, yet very technical.
I'm sure you've had tough classes like Calculus in school where you learned how to solve problems without really understanding them. Just memorize the steps and repeat them on the test. Spawning bots is a bit like this. You don't have to understand each line, just cut and paste them.
As you know from earlier lessons, a bot is nothing more than an entity. It is an entity with a size, model, animation, movement type, and other characteristics. It only takes one subroutine to create this entity, and here it is:
// ------------------------------------------------ void() create_mobot = // ------------------------------------------------ { local entity bot, spawn_spot; // start entity and place it in world bot = spawn(); spawn_spot = SelectSpawnPoint (); bot.origin = spawn_spot.origin + '0 0 1'; bot.angles = spawn_spot.angles; bot.fixangle = TRUE; spawn_tfog (bot.origin); spawn_tdeath (bot.origin, bot); // set size and shape setsize (bot, VEC_HULL2_MIN, VEC_HULL2_MAX); bot.solid = SOLID_SLIDEBOX; bot.movetype = MOVETYPE_STEP; setmodel(bot, "progs/ogre.mdl"); bot.flags = bot.flags | FL_MONSTER; bot.takedamage = DAMAGE_AIM; // define his animation bot.th_stand = ogre_stand1; bot.th_walk = ogre_walk1; bot.th_run = ogre_run1; bot.th_die = ogre_die; bot.th_melee = ogre_melee; bot.th_missile = ogre_nail1; bot.th_pain = ogre_pain; bot.health = 200; // polish him up bot.classname = "monster_ogre"; bot.ideal_yaw = bot.angles * '0 1 0'; bot.yaw_speed = 120; bot.view_ofs = '0 0 22'; bprint("an ogre joins the game\n"); // begin his thinking bot.nextthink = time + 0.1 + random(); bot.think = bot.th_walk; };Copy this code, open up OGRE.QC, and paste it at the very end (so the ogre animations we refer to are already defined).
So let's put this bad boy into the game. Open up WEAPONS.QC and scroll down to this:
/* ============ ImpulseCommands ============ */ void() ImpulseCommands = { if (self.impulse >= 1 && self.impulse <= 8) W_ChangeWeapon ();After this code, add the following lines:
if (self.impulse == 100) create_mobot();Okay, we didn't do any calculus, so I bet you could tell me what that means. Yes, you're right; when we type impulse 100 into the Quake console, we will create a mobot. Even simpler, we could type this into the console:
bind m "impulse 100"
Then every time you press m, a bot will be spawned at a different deathmatch point. There are two last simple steps. Go back up to the very beginning of WEAPONS.QC, where you will see this:
// called by worldspawn void() W_Precache = {After that, paste in the following code:
precache_model ("progs/ogre.mdl"); precache_model ("progs/h_ogre.mdl"); precache_model ("progs/grenade.mdl"); precache_sound ("ogre/ogdrag.wav"); precache_sound ("ogre/ogdth.wav"); precache_sound ("ogre/ogidle.wav"); precache_sound ("ogre/ogidle2.wav"); precache_sound ("ogre/ogpain1.wav"); precache_sound ("ogre/ogsawatk.wav"); precache_sound ("ogre/ogwake.wav");When you play Quake, all sounds and models that will be used must be pre-loaded. We just took care of that. Honestly, I just copied these from the bottom of the OGRE.QC file.
void() create_mobot;Let me say one last thing, then I'll let you compile and play with your new pet ogre. This creature isn't really a mobot yet. That is, he won't act like a bot. This ogre will use all of id software's normal AI code.