Game Development Community

My object derived from GameBase won

by Mike Stoddart · in Torque Game Engine · 04/22/2005 (5:14 pm) · 6 replies

Forgive me for such a long post but this problem is driving me nuts. This code worked when compiled on Fedora Core 2 using its version of GCC. Now under Core 3 it doesn't render my object. I can choose to add an instance of this object using the editor, but it doesn't render the object there either. There are no errors in the console.

I haven't had much luck chatting on IRC, so I thought it would be easier for people to see my code. Hopefully someone can point out my stupid mistake!

Source code in the next post....

#1
04/22/2005 (5:14 pm)
My C++ source file is:

IMPLEMENT_CO_DATABLOCK_V1(UnitData);
IMPLEMENT_CO_NETOBJECT_V1(Unit);

//--------------------------------------------------------------------------
//
UnitData::UnitData()
{
	initialStrength = 0;
        unitShapeName = NULL;
}
//--------------------------------------------------------------------------
IMPLEMENT_GETDATATYPE(UnitData)
IMPLEMENT_SETDATATYPE(UnitData)

void UnitData::initPersistFields()
{
   Parent::initPersistFields();

   Con::registerType("UnitDataPtr", TypeUnitDataPtr, sizeof(UnitData*),
                     REF_GETDATATYPE(UnitData),
                     REF_SETDATATYPE(UnitData));

	addNamedField(initialStrength, TypeS32, UnitData);
}

//--------------------------------------------------------------------------
bool UnitData::onAdd()
{
   if(!Parent::onAdd())
      return false;
   
	std::cout << "Adding new English Unit - inside C++" << std::endl;
	  
   return true;
}

bool UnitData::preload(bool server, char errorBuffer[256])
{
   if (Parent::preload(server, errorBuffer) == false)
      return false;

   return true;
}

//--------------------------------------------------------------------------
void UnitData::packData(BitStream* stream)
{
   Parent::packData(stream);
}

void UnitData::unpackData(BitStream* stream)
{
   Parent::unpackData(stream);
}

//-------------------------------------------------------------------------
Unit::Unit()
{
	std::cout << "Creating Unit" << std::endl;
		
	mNetFlags.set(Ghostable);
	mTypeMask |= PlayerObjectType;
	mCurrTick = 0;	
	mCurrentStrength = 0;
}

Unit::~Unit()
{
	std::cout << "Destroying Unit" << std::endl;
}

void Unit::initPersistFields()
{
   Parent::initPersistFields();

   addGroup("Basic");
   addField("currentStrength", TypeS32, Offset(mCurrentStrength, Unit));
   endGroup("Basic");
}

void Unit::advanceTime(F32 dt)
{
   Parent::advanceTime(dt);

   if (dt == 0.0)
      return;
}

bool Unit::onAdd()
{
	std::cout << "Adding Unit" << std::endl;
   
   if(!Parent::onAdd())
      return false;
   
	addToScene();
	
   if (isServerObject())
   {
      scriptOnAdd();
   }
	
	return true;
}

void Unit::onRemove()
{
	std::cout << "Removing Unit" << std::endl;

   scriptOnRemove();
   removeFromScene();
   
   Parent::onRemove();
}

bool Unit::onNewDataBlock(GameBaseData *dptr)
{
	std::cout << "Unit::onNewDataBlock" << std::endl;
	
   mDataBlock = dynamic_cast<UnitData*>(dptr);
   if (!mDataBlock || !Parent::onNewDataBlock(dptr))
      return false;

   scriptOnNewDataBlock();
   return true;
}

void Unit::processTick(const Move *move)
{
   Parent::processTick(move);

   mCurrTick++;
}

void Unit::interpolateTick(F32 delta)
{
   Parent::interpolateTick(delta);
}

// Rendering
void Unit::prepModelView    ( SceneState *state)
{
}

bool Unit::prepRenderImage  ( SceneState *state, const U32 stateKey,
										const U32 startZone, const bool modifyBaseZoneState)
{
  return Parent::prepRenderImage(state, stateKey, startZone, modifyBaseZoneState);
}

void Unit::renderObject     ( SceneState *state, SceneRenderImage *image)
{
   Parent::renderObject(state, image);
}

U32  Unit::packUpdate  (NetConnection *conn, U32 mask, BitStream *stream)
{
  U32 retMask = Parent::packUpdate(conn, mask, stream);

   // Initial update
   stream->write(mCurrentStrength);

	// Were done ...
	return(retMask);
}

void Unit::unpackUpdate(NetConnection *conn, BitStream *stream)
{
   Parent::unpackUpdate(conn, stream);

   stream->read(&mCurrentStrength);
}


More code in the next post.....
#2
04/22/2005 (5:14 pm)
My header file is:

class UnitData : public GameBaseData
{
   typedef GameBaseData Parent;

protected:
   bool onAdd();   
   const char* unitShapeName;   
	S32      initialStrength;

public: 
   UnitData();
   void packData(BitStream*);
   void unpackData(BitStream*);
   bool preload(bool server, char errorBuffer[256]);
   static void initPersistFields();
   DECLARE_CONOBJECT(UnitData);
};

class Unit: public GameBase
{
   typedef GameBase Parent;

public:
   // Initial conditions
   enum UpdateMasks {
      UpdateMask    = Parent::NextFreeMask,
      NextFreeMask  = Parent::NextFreeMask << 1
   };
	
	protected:
	   UnitData* mDataBlock;
	S32      mCurrentStrength;
	
   // Time related variables common to all projectiles, managed by processTick

   U32 mCurrTick;                         ///< Current time in ticks
   SimObjectPtr<ShapeBase> mSourceObject; ///< Actual pointer to the source object, times out after SourceIdTimeoutTicks

   bool onAdd();
   void onRemove();
   bool onNewDataBlock(GameBaseData *dptr);

   void processTick(const Move *move);
   void advanceTime(F32 dt);
   void interpolateTick(F32 delta);

   // Rendering
   void prepModelView    ( SceneState *state);
   bool prepRenderImage  ( 	SceneState *state, const U32 stateKey,
   											const U32 startZone, const bool modifyBaseZoneState=false);
   void renderObject     ( SceneState *state, SceneRenderImage *image);

   U32  packUpdate  (NetConnection *conn, U32 mask, BitStream *stream);
   void unpackUpdate(NetConnection *conn,           BitStream *stream);

	public:
		DECLARE_CONOBJECT(Unit);
		static void initPersistFields();		
   		Unit();
   		virtual ~Unit();
};

My script is:

datablock UnitData(English)
{
	initialStrength = 198;
	shapeFile = "~/data/shapes/unit/redbox.dts";
	category="Unit";
};

function English::onAdd(%this,%obj)
{
	echo("Adding English unit");
}

function UnitData::create(%data)
{
   // The mission editor invokes this method when it wants to create
   // an object of the given datablock type.  For the mission editor
   // we always create "static" re-spawnable rotating objects.
   %obj = new Unit() {
      dataBlock = %data;
   };
   return %obj;
}

I know the DTS renders as it worked for me before on Core 2. I only changed platform/event.h and core/resManager.h to get them to compile under GCC 3.4. Any help greatly appreciated!

Thanks
#3
04/22/2005 (5:37 pm)
I'll leave this here, but the solution is to derive from ShapeBase. I was on the right track, thinking I could just use the parent class to perform the rendering, I just chose the wrong one!!! :)

Hope this is useful to someone.
#4
04/22/2005 (6:11 pm)
Ok so that didn't really make it work. It doesn't render until I select it in the editor. More research!!
#5
04/23/2005 (4:36 pm)
Ok so I deleted the above and copied item.cc and item.h. Made sure the files are in the Makefile and re-built. I'm getting:

Unable to instantiate non-conobject class UnitData.
Unable to instantiate non-conobject class Unit.

My script file is:
datablock UnitData(English)
{
   category = "Unit";

   // Basic Item properties
   shapeFile = "~/data/shapes/units/redbox.dts";
   mass = 1;
   friction = 1;
   elasticity = 0.3;

   // Dynamic properties defined by the scripts
   pickupName = "the English";
   repairAmount = 50;
};

//-----------------------------------------------------------------------------
// Hook into the mission editor.

function UnitData::create(%data)
{
   %obj = new Unit() {
      dataBlock = %data;
      static = true;
      rotate = false;
	  //className="Unit";
   };
   return %obj;
}

So what else have I forgotten?

Thanks
#6
04/23/2005 (4:42 pm)
Ah never mind, it was a stupid build issue!