Resolved]Mounting Images on RTS units?
by Johnathan Moore · in RTS Starter Kit · 02/25/2006 (11:57 am) · 10 replies
Hi,
I want to mount objects onto the RTS units but at the moment i dont think it works, I read somewhere it
was disabled because of all the different networking
does anyone know about reactivating it?
I want to mount objects onto the RTS units but at the moment i dont think it works, I read somewhere it
was disabled because of all the different networking
does anyone know about reactivating it?
About the author
Been tinkering with this since I was young.
#2
03/01/2006 (1:01 pm)
Sorry John, been relying on a feed for posts, missed this one! I will check into the RTSUnit class to see what it would need if anything, to support mounted objects.
#3
Whoops! I misspoke. I did not notice that RTSUnit had its own PackUpdate/UnpackUpdate.
Look at the doc here: tdn.garagegames.com/wiki/RTS/RTSUnit at the Packet Updates Section and it talks about the removal of the code, and where to look to get it in again ;)
03/01/2006 (1:06 pm)
It looks like, since it inherits player.h, mounting objects should work fine. I will try it out tomorrow AM and see..Whoops! I misspoke. I did not notice that RTSUnit had its own PackUpdate/UnpackUpdate.
Look at the doc here: tdn.garagegames.com/wiki/RTS/RTSUnit at the Packet Updates Section and it talks about the removal of the code, and where to look to get it in again ;)
#4
03/01/2006 (1:13 pm)
Ok thanks
#5
in rtsunit.cc, there are 3 changes:
1) around line 1001, in PackUpdate, find:
and change it to:
2) right above:
add:
3) and right before the end packUpdate, add:
Any flags we write in packUpdate, we have to read in unpackUpdate.
in unpackUpdate:
1) Right before:
add:
2) Right before the end of the function, add:
Compile!
Now you can script a mount in the standard fashion. I threw one into player.cs->RTSUnitData::onAdd of
%obj.mountImage(CrossbowImage,0);
To get this:
03/02/2006 (7:09 pm)
John- This worked out pretty well.in rtsunit.cc, there are 3 changes:
1) around line 1001, in PackUpdate, find:
if(!stream->writeFlag(mask & (DamageMask | SoundMask | ThreadMask | SkinMask |
ActionMask | AIMask | InitialUpdateMask | CloakMask | ImpactMask |
MoveMask | ModifierMask | ProjectileMask)))
return retMask;and change it to:
if(!stream->writeFlag(mask & (DamageMask | SoundMask | ThreadMask | SkinMask |
ActionMask | AIMask | InitialUpdateMask | CloakMask | MountedMask | ImpactMask |
MoveMask | ModifierMask | ProjectileMask)))
return retMask;2) right above:
if(stream->writeFlag(mask & SkinMask))
con->packStringHandleU(stream,mSkinNameHandle);add:
if (stream->writeFlag(mask & ImageMask)) {
for (int i = 0; i < MaxMountedImages; i++)
if (stream->writeFlag(mask & (ImageMaskN << i))) {
MountedImage& image = mMountedImageList[i];
if (stream->writeFlag(image.dataBlock))
stream->writeInt(image.dataBlock->getId() - DataBlockObjectIdFirst,
DataBlockObjectIdBitSize);
con->packStringHandleU(stream, image.skinNameHandle);
stream->writeFlag(image.wet);
stream->writeFlag(image.ammo);
stream->writeFlag(image.loaded);
stream->writeFlag(image.target);
stream->writeFlag(image.triggerDown);
stream->writeInt(image.fireCount,3);
if (mask & InitialUpdateMask)
stream->writeFlag(isImageFiring(i));
}
}3) and right before the end packUpdate, add:
if (mask & MountedMask) {
if (mMount.object) {
S32 gIndex = con->getGhostIndex(mMount.object);
if (stream->writeFlag(gIndex != -1)) {
stream->writeFlag(true);
stream->writeInt(gIndex,NetConnection::GhostIdBitSize);
stream->writeInt(mMount.node,ShapeBaseData::NumMountPointBits);
}
else
// Will have to try again later
retMask |= MountedMask;
}
else
// Unmount if this isn't the initial packet
if (stream->writeFlag(!(mask & InitialUpdateMask)))
stream->writeFlag(false);
}
else
stream->writeFlag(false);
return retMask;Any flags we write in packUpdate, we have to read in unpackUpdate.
in unpackUpdate:
1) Right before:
if (stream->readFlag()) // SkinMask
{
StringHandle skinDesiredNameHandle = con->unpackStringHandleU(stream);
if (mSkinNameHandle != skinDesiredNameHandle)
{
mSkinNameHandle = skinDesiredNameHandle;
if (mShapeInstance)
{
mShapeInstance->reSkin(mSkinNameHandle);
if (mSkinNameHandle.isValidString())
mSkinHash = _StringTable::hashString(mSkinNameHandle.getString());
}
}
}add:
if (stream->readFlag()) {
for (int i = 0; i < MaxMountedImages; i++) {
if (stream->readFlag()) {
MountedImage& image = mMountedImageList[i];
ShapeBaseImageData* imageData = 0;
if (stream->readFlag()) {
SimObjectId id = stream->readInt(DataBlockObjectIdBitSize) +
DataBlockObjectIdFirst;
if (!Sim::findObject(id,imageData)) {
con->setLastError("Invalid packet (mounted images).");
return;
}
}
StringHandle skinDesiredNameHandle = con->unpackStringHandleU(stream);
image.wet = stream->readFlag();
image.ammo = stream->readFlag();
image.loaded = stream->readFlag();
image.target = stream->readFlag();
image.triggerDown = stream->readFlag();
int count = stream->readInt(3);
if ((image.dataBlock != imageData) || (image.skinNameHandle != skinDesiredNameHandle)) {
setImage(i, imageData, skinDesiredNameHandle, image.loaded, image.ammo, image.triggerDown);
}
if (isProperlyAdded()) {
// Normal processing
if (count != image.fireCount)
{
image.fireCount = count;
setImageState(i,getImageFireState(i),true);
if( imageData && imageData->lightType == ShapeBaseImageData::WeaponFireLight )
{
mLightTime = Sim::getCurrentTime();
}
}
updateImageState(i,0);
}
else
{
bool firing = stream->readFlag();
if(imageData)
{
// Initial state
image.fireCount = count;
if (firing)
setImageState(i,getImageFireState(i),true);
}
}
}
}
}2) Right before the end of the function, add:
if (stream->readFlag()) {
if (stream->readFlag()) {
S32 gIndex = stream->readInt(NetConnection::GhostIdBitSize);
ShapeBase* obj = dynamic_cast<ShapeBase*>(con->resolveGhost(gIndex));
S32 node = stream->readInt(ShapeBaseData::NumMountPointBits);
if(!obj)
{
con->setLastError("Invalid packet from server.");
return;
}
obj->mountObject(this,node);
}
else
unmount();
}Compile!
Now you can script a mount in the standard fashion. I threw one into player.cs->RTSUnitData::onAdd of
%obj.mountImage(CrossbowImage,0);
To get this:
#6
03/04/2006 (6:15 am)
Wow thanks for going to that trouble, ill add that in now
#7
03/08/2006 (3:48 pm)
So this can add objects e.g. weapons to units ??????
#8
03/08/2006 (6:18 pm)
Yep! Take a look at the pic.
#9
I just disabled it as follows, works fine (weapon.cs);
02/07/2010 (4:14 am)
Works great, but it does generate an error on the inventory since its not used for rts game.I just disabled it as follows, works fine (weapon.cs);
function WeaponImage::onMount(%this,%obj,%slot)
{
// Images assume a false ammo state on load. We need to
// set the state according to the current inventory.
/*
if (%obj.getInventory(%this.ammo))
%obj.setImageAmmo(%slot,true);
*/
#10
EDIT: Found the solution. I was mounting it on Player::onAdd() and units were then unable to move afterwards. I moved the call to RTSUnitData::onAdd() and now works great!!
02/07/2010 (4:39 am)
I dont understand how -- but somehow, after I mount an image ... now the units can no longer move. Will test it out some more ... or possibly just find a way to add weapons to units and re-export the models with weapons included.EDIT: Found the solution. I was mounting it on Player::onAdd() and units were then unable to move afterwards. I moved the call to RTSUnitData::onAdd() and now works great!!
// Check to see if this should have a projectile, so look at the datablock
if ((%objClassName $= "RTSUnit") && (%this.isMelee == false))
{
%obj.setProjectileDatablock(CrossbowProjectile);
%obj.mountImage(BowImage,0);
}
Torque Owner Johnathan Moore