Tutorial *129*
Long ago, iD made it known that the Quake engine could not do rotating brushes. Hypnotic entertainment (now Ritual) proved them wrong, and introduced rotating brushes in their mission pack, "Scourge of Armagon".
The rotating brushes that hypnotic introduced werent too easy to setup in a map though, and scared many a mapper away from using them.
Whilst developing my own engine mod, I made a decision that I wanted easy-to-use rotating brush entities. John carmack came to the rescue after I emailed him asking if it were possible. He gave me a brief rundown of what had to be done, and left me to do it. Little did he say that the majority of the code was just #ifdef'd QUAKE2.
Enough of that now, onto the code!
In sv_phys.c find the function SV_PushMove. Immediately after that function is the line:


#ifdef QUAKE2

Change it to:


// #ifdef QUAKE2 // Rotating brushes fix - MrG (biteme@telefragged.com)

Immediately after that function that was #ifdef'd (SV_PushRotate), change:


#endif

to


// #endif // Rotating brushes fix - MrG (biteme@telefragged.com)

Now in the function you just opened up to the Quake engine (SV_PushRotate), find the code:


if (check->v.movetype == MOVETYPE_PUSH

|| check->v.movetype == MOVETYPE_NONE

|| check->v.movetype == MOVETYPE_FOLLOW

|| check->v.movetype == MOVETYPE_NOCLIP)

continue;

and comment out the line with MOVETYPE_FOLLOW on it, so it should read:


  if (check->v.movetype == MOVETYPE_PUSH

  || check->v.movetype == MOVETYPE_NONE

//|| check->v.movetype == MOVETYPE_FOLLOW

  || check->v.movetype == MOVETYPE_NOCLIP)

  continue;

Now in the very next function in sv_phys.c (SV_Physics_Pusher), find the code:


if (movetime)

{

#ifdef QUAKE2

if (ent->v.avelocity[0] || ent->v.avelocity[1] || ent->v.avelocity[2])

	SV_PushRotate (ent, movetime);

else

#endif

	SV_PushMove (ent, movetime);	// advances ent->v.ltime if not blocked

}

Replace it with this:


if (ent->v.avelocity[0] || ent->v.avelocity[1] || ent->v.avelocity[2])

	SV_PushRotate (ent, host_frametime);



if (movetime)

	SV_PushMove (ent, movetime);	// advances ent->v.ltime if not blocked

Now open up world.c and find the function SV_ClipMoveToEntity. Find both cases of the following:


#ifdef QUAKE2

and comment it out to look like:


//#ifdef QUAKE2 // rotating brushes fix - MrG (biteme@telefragged.com)

Do the same for each occurance of:


#endif

into


//#endif // rotating brushes fix - MrG (biteme@telefragged.com)

Now for the QuakeC side of things. Open up World.QC (or create another QC file and include it in progs.src). Add the following QC function:


void() func_rotating =

{

	self.solid = SOLID_BSP;

	self.movetype = MOVETYPE_PUSH;

	setorigin (self, self.origin);

	setmodel (self, self.model);

	self.classname = "func_rotating";

	setsize (self, self.mins, self.maxs);



	if (!self.speed)

		self.speed = 100;



	if (self.spawnflags & 2) // reverse direction

		self.speed = 0 - self.speed;



	if (self.spawnflags & 64) // not solid

		self.solid = SOLID_NOT;



	if (self.spawnflags & 4)

	{

		self.avelocity_z = self.speed;

		self.avelocity_x = 0;

		self.avelocity_y = 0;

	}

	else if (self.spawnflags & 8)

	{

		self.avelocity_z = 0;

		self.avelocity_x = self.speed;

		self.avelocity_y = 0;

	}

	else

	{

		self.avelocity_z = 0;

		self.avelocity_x = 0;

		self.avelocity_y = self.speed;

	}

};

This will allow a brush entity (created in a Map editor) classnamed "func_rotating" to be created, and will rotate around its origin brush (if your compile tools support origin brushes, otherwise you will need to set an origin vector for your func_rotating to rotate around). The spawn flags in that QC function above allow the mapper to set the axis that the brush-model rotates on, its speed, and whether or not its solid.
Now compile the engine and the QC source. You will need to create a MAP file with a "func_rotating" brush-entity in it to test this out. If all goes well, you will have rotating brush-entitys.


 
Not logged in
Sign up
Login:
Passwd: