Game Development Community

dev|Pro Game Development Curriculum

Turret & AITurret classes, Version 1.20

by Brian Howard · 03/14/2004 (9:33 am) · 131 comments

Download Code File

Included in this archive are the original files and the files modified to work with 1.20 version. Most files did not have to be modified. Files that were modified were saved as a new file in an originalname_1_20.ext format. For example, trigger.cc had to be modified and the 1.20 code was saved as trigger_1_20.cc

I've maintained the same commenting format Paul used.

I've included the original turret_readme.txt file and an updated turret_readme_1_20.txt in the archive. The new readme file contains references for other fixes I found along the way. Please let me know if I missed a reference.

***I have not tested this on moving vehicles!

Hope the changes are helpful. I'll check back in, and do what I can to help out. This is my first posting, so let me know if there is a better way to communicate code updates.

About the author

Recent Blogs

#61
05/16/2006 (6:56 pm)
I got working. Good resource.
#62
06/19/2006 (8:43 am)
@ Rodrigo A. Obando

Go to this link www.garagegames.com/mg/forums/result.thread.php?qt=28891 Check out the code that Matt Fairfax adds which is now in the source. It causes aiming problems for me as well so I just commented the code out and it works fine.

No one else has complained about it so i'm guessing it is going to stay in there. Give it a shot and see if it works for you.
#63
06/29/2006 (7:00 pm)
This worked for me in TLK 1.4 Visual Studio 2005 EXPRESS
#64
06/30/2006 (5:58 am)
Did you have to change anything?
#65
06/30/2006 (8:43 am)
Yes allot of little things, but alott of these issues can be resolved by reading Torky and Master Trebs comments.
gamebase.h,trigger.cc and the player.cc where my biggest hurdles. But I resolved each error one at a time as it compiled. and the sDirty was a blocker for a while.

I also was first confused about player_1_20.cc what I did was throw away all the old code supplied in the zip and just used Brians modified files.

I used a regular note pad to merge most of the changes in, but when it came to player.cc and a couple others I used beyond compare.

I compile 100% no errors, inserted all the proper scipts and art pieces and BAM! TURRETS, and AI TURRETS.
My next mission now is to construct my own turret in 3dsmax.

-Hope this helps

-Surge
#66
08/02/2006 (8:08 pm)
Does anyone know how to create a crosshair that represents the aim of a vehicle mounted turret weapon? I've manged to get the turret attached to my vehicle and can freely move the turret and fire using the mouse, however, my crosshair (created using the SuperCrosshair resource) does not follow the turrent movements but instead follows a straight line from my vehicle.
#67
12/24/2006 (1:28 pm)
OK, I got this sorta working.

1.) I got a problem. Now that I added this code and can mount a turret and fire it. The bot and myself cannot take damage. The turret can take damage but not us.

2.) AI is not working at all for the turret.

Any suggestions as I dig back into it?
#68
04/12/2007 (7:20 pm)
i got this working all the way in 1.5.1 with the sample turret model and code, but i cant get it to work when i try to rig up a bare minimum ai turret with my own model.
#69
04/13/2007 (8:41 am)
ah, the problem is because the turret code rotates the codeturret bone around the Z axis, which should be up, but in blender that cant happen, or atleast i cant get it to.

so, by arranging my blender bones in a very odd way i got the axis' right, now the problem is it wont track, i did get it to track once but only when i moved the turret high in the air, but its super inconsistent. and never fired.
#70
04/18/2007 (8:03 pm)
now ive got the tracking to work again(the eyeoffset in the weapon was making it wacky, that and the whole screwy blender bones thing) now my problem is, my weapon, with the default scripts that come with the resource works fine, but when i make my own turret script, and do setaimobject, since i dont have the auto tracking parts of the script copied yet, the Z axis aiming is fine, but the X axis aiming in inversed... its so weird.
#71
06/15/2007 (7:54 pm)
now i just cant get the laser resource to work with this.
edit: ok, got the lasers to work, i just had to add a overload to geteyetransform in the turret class, as turrets dont have eyes the laser was rendering wrong.

now i just need to get it to fully delete itself when dead, instead of leaveing a bit behind that u can run into, and torque crashing when u delete it. cept... torque crashes when you delete the aiturret period lol
#72
06/27/2007 (6:23 pm)
ok cool looking resource, but i get a compilation error when intigrating it into TGE 1.3.

error c2061: Syntax Error : Indentifier 'GameBase' --- gameBase.h

refers to :

virtual void potentialEnterObject(GameBase*);

i have tried many different ways to fix the problem but nothing seems to work. any clues????
#73
06/27/2007 (6:42 pm)
ok nvm, i fiured it out.

the files state to put :

virtual void potentialEnterObject(GameBase*);

inside:

struct GameBaseData : public SimDataBlock {

but once i moved this into:

class GameBase : public SceneObject {

the error went away. and then after adding in a few oversites by myself it compiled fine. now to move on to the script side of things.
#74
12/04/2007 (12:49 pm)
Great resource. Got it working flawlessly right away.

My only question is, how can I make the turrets distinguish between teams? Don't want friendly fire.
#75
12/04/2007 (3:15 pm)
do you have teams implemented already and if so what member variable in the player do you use to distinguish teams (ex. %player.team = 1; the member variable would be team). If you tell me that I will be able to do it. If you don't have teams implemented I know a couple resources I can point you towards and I know how to make AI distinguish using them.

I've done it before but one of my hard drives recently caught on fire so I think it might be lost.
#76
12/08/2007 (3:35 pm)
I have teams implemented and they work flawlessly. =)

And, yes, the way you said it - each player simply has a dynamic field called 'team', set to either 1 or 2 (or 0 in non-team games). Thanks in advance, I really appreciate it.
#77
12/09/2007 (12:47 pm)
Okay, I'm working on it, I also have Math finals next Wednesday and I'm putting up Christmas lights so I have a lot on my to do list, but I should be done in a couple days.
#78
12/18/2007 (9:03 am)
It should be noted that the line if (mOwner != NULL) doesn't quite work right when operating on a turret mounted to a vehicle. that needs changing to the following:

turret.h:
class Trigger : public GameBase
{
...
SimObjectPtr mOwner;

turret.cc/cpp:
void Trigger::potentialEnterObject(GameBase* enter)
{
...
if (!mOwner.isNull())
#79
12/18/2007 (11:51 am)
Okay it's nearly done I have it working for one person, but if you get more than one it flips out so I'm working on it. I wasn't expecting to have to mess with the source code but it looks like that is necessary, I'm trying to figure out the best way to tackle without having the teams defined in C++. Hopefully the resulting code won't be too messy.
#80
12/19/2007 (3:55 pm)
made the following additional changes (tgea 1.03/tge 1.42 +):

turret.h:
static U32 sDirtySetMask = PlayerObjectType     |
						   TurretObjectType     |
                           VehicleObjectType;
static U32 sClientCollisionMask = 
      TerrainObjectType    | InteriorObjectType       |
      PlayerObjectType     | StaticShapeObjectType    |
      VehicleObjectType    | VehicleBlockerObjectType |
	  TurretObjectType     | StaticTSObjectType;

obsolete, so don't obther including those.

aiturret.h:
static void consoleInit(); x2
chuck those too

stability:
// Aiming
	void setAimObject( GameBase *targetObject );
becomes:
// Aiming
	void setAimObject( SimObjectPtr<GameBase> targetObject );

aiturret.cpp/.cc:
toss out
namespace {
// the rest of methods are done below using "ConsoleMethod"
// this done here because of reserved name "delete"
void cAITurretDelete(SimObject* obj, S32, const char** argv)
{
   AssertFatal(dynamic_cast<AITurret*>(obj) != NULL, "Error, how did a non-AITurret get here?");
   AITurret* trigger = static_cast<AITurret*>(obj);
   trigger->preDelete();
   trigger->deleteObject();
} 
} // namespace {}
in favor of
ConsoleMethod(AITurret, delete, void, 2, 2,"obj.delete()")
{
   object->preDelete();
   object->deleteObject();
}
kill off:
void AITurretData::consoleInit()
{
}
and
void AITurret::consoleInit()
{
   // the rest of methods are done below using "ConsoleMethod"
   // this done here because of reserved name "delete"
   Con::addCommand("AITurret", "delete",  cAITurretDelete,  "[AITurret].delete()",            2, 2);
}

setTarget doesn't actually *do* anything other than call script wich turns right arround and calls setAimObject, so just cut out the middle-man, and short-circuit that, changing all instances of setTarget to setAimObject
since were now using a simptr cast for stability (it handles alot of the memory errorchecking all on it's own)
instances of
if (mAimObject != NULL)
now become
if (!mAimObject.isNull())
in order to avoid it flipping out and misallocating the pointer
also to keep it from wigging out, changed
if (mObjects.size() != 0)
to
if (mObjects.size() > 0)
because size returns an S32, meaning it can go negative, wich would of course be a *baaaad thing*
again since were using the ptr cast, changed instances of
if (mAimObject
to
if (!mAimObject.isNull()
void AITurret::setAimObject( GameBase *targetObject )
becomes
void AITurret::setAimObject( SimObjectPtr<GameBase> targetObject )
in keeeping with the general theme of cover your *cough hi kids* fars bad pointers goes,
wich brings us to:
if (targetObject == NULL)
         Con::executef(mDataBlock, 3, "onTargetLost", scriptThis(), mAimObject->scriptThis());
      else
         Con::executef(mDataBlock, 4, "onTargetChanged", scriptThis(), mAimObject->scriptThis(), targetObject->scriptThis());
not entirely sure what th origional intent of the onTargetChanged functionality was for there, but it's erry much incompatible with an if (!targetObject.isNull()) check, so since it was just a stub-function anyway, ripped that right out, leaving us with just:
if (!targetObject.isNull())
         Con::executef(mDataBlock, 3, "onTargetLost", scriptThis(), mAimObject->scriptThis());
in
bool AITurret::pickTarget()
{
...
F32 dist = 1000000.0;
}
changed to
F32 dist = mDataBlock->triggerRadius;
just for a redundant check to make sure were not picking an object and having to immediately turn arround and repick one
and from there it's just following back up with the setTarget to setAimObject conversions