Figgin
Created By: Sestze
eMail: sestze@yahoo.com
Difficulty Scale: Easy


Hi there! By this time, if you have screwed with any AI code by using findradius functions to make the monsters roam, you have noticed that it makes the game unreasonably slow. Any more than 40 or so monsters, and you end up lagged down so much, you leap five feet every time you press the forward key.

This roaming tutorial will make all monsters move towards one common goalentity.

Step 1.

Type these prototypes at the very top of world.qc:


void() Arc_Figgin;
void() S_Figgin;
void() T_Figgin;
This is the variable that stores our total experience points. You may wish to change the name but if you do remember to do it in all the steps. Go on to the next step.

Step 2.

Type this at the very end of the world.qc QC file.


/*
=================================================================================

FIGGIN

=================================================================================
*/

void() Arc_Figgin =
{
	local entity figgin;				//Make an entity called "figgin"
	
	figgin = spawn();					//Spawn the figgin
	figgin.classname = "figgin";			//It's a figgin
	figgin.movetype = MOVETYPE_NONE;		//It doesn't move
	figgin.solid = SOLID_BBOX;			//It can be touched
	setsize(figgin, '-1 -1 -1', '1 1 1');	//It's size is '2 2 2'
	
	figgin.origin_x = (0.5 - random())* 2 * 5000;	//It's origin is randomized
	figgin.origin_y = (0.5 - random())* 2 * 5000;
	figgin.origin_z = (0.5 - random())* 2 * 5000;
	
	while((pointcontents(figgin.origin) != CONTENT_EMPTY) && (figgin.aflag < 75))
	{
		//If the pointcontents of the figgin's origin is not empty, reset the figgin
		//To a more suitable space. If no space can be found within 75 loops,
		//Leave it where it last was placed.
		figgin.origin_x = (0.5 - random())* 2 * 5000;
		figgin.origin_y = (0.5 - random())* 2 * 5000;
		figgin.origin_z = (0.5 - random())* 2 * 5000;
		
		figgin.aflag = figgin.aflag + 1;
	}
	
	figgin.nextthink = time + 0.1;		//.1 seconds from now
	figgin.think = S_Figgin;			//You will do something else
	
	figgin.touch = T_Figgin;			//If touched...
};

void() S_Figgin =
{
	local entity flick;				//Declare an entity to be used for the
								//findradius function
	
	flick = findradius(self.origin, 10000);
	
	while(flick)
	{
		if(flick.flags & FL_MONSTER)		//If flick is a monster
		{
			if(flick.health > 0)		//If he has health
			{
				if(flick.search_time < time)	//If he aint looking for the player
				{
					if((flick.enemy == world) || (flick.enemy == self))	//If he doesn't have an enemy
					{
						flick.goalentity = self;	//Your target is a figgin.
						flick.nextthink = time + 0.1;	//In .1 seconds
						flick.think = flick.th_walk;	//You will walk
					}
				}
			}
		}
	flick = flick.chain;		//Next entity in line
	}
	
	self.aflag = 0;	//Reset the loop counter
	
	self.nextthink = time + 3 + random() * 3;	//In 3-6 seconds
	self.think = T_Figgin;				//Act as if it's been touched
};

void() T_Figgin =
{
	//Random origin
	self.origin_x = (0.5 - random())* 2 * 5000;
	self.origin_y = (0.5 - random())* 2 * 5000;
	self.origin_z = (0.5 - random())* 2 * 5000;
	
	while((pointcontents(self.origin) != CONTENT_EMPTY) && (self.aflag < 75))
	{
		//Check for where it is
		self.origin_x = (0.5 - random())* 2 * 5000;
		self.origin_y = (0.5 - random())* 2 * 5000;
		self.origin_z = (0.5 - random())* 2 * 5000;
	
		self.aflag = self.aflag + 1;
	}

	self.nextthink = time + 0.1;	//Wash rinse
	self.think = S_Figgin;		//Repeat
};
This function tallys up the experience and prints the amount the person has.

Step 3.

Place at the very end of the worldspawn() function:

Arc_Figgin();

Step 4.

Compile and you have roaming monsters. They walk places. Or straight into walls, you never know.

I hope this tutorial works (I used it in smod1, but something may have broken). If not, Knock me one at sestze@yahoo.com

Lastly: A figgin is a type of fruitcake, for those who gandered as to what the hell it meant.