Moveable, Destroyable, Mission Area Aware ITEMS
by Robert Brower · 01/24/2003 (11:45 am) · 4 comments
01/22/03 - Robert Brower.
Prelude... I am working on a first person shooter in space. It is similar to the classic arcade game 'Asteroids'. I needed a way to create asteroids that would float around the mission area. One of the problems with this was that I needed a way to confine the asteroids to the mission area. Another problem was that projectiles normally don't collide with Items. To solve these problems follow these steps. If you are working on a space related game then you can also include the optional modifications by Wendell Brown and Chris 'Dark' Evans. I implemented some of their changes but not all of them.
The following instructions will enable you to create destructable Item objects that have mission area bounds checking.
1. torque\engine\game\item.h
Insert the following block of code into the private section of the class right after Box3F mWorkingQueryBox;
// RFB ->
void checkMissionArea();
bool mInMissionArea;
// <- RFB
-----------------------------------------------------------------------------
2. torque\engine\game\item.cc
Insert the following block of code right after #include "math/mathIO.h".
// RFB -> adding item mission area bounds check
#include "game/missionArea.h"
// <- RFB
Insert the following block of code inside Item::Item() right after mWorkingQueryBox.max.set(-1e9, -1e9, -1e9);
// RFB ->
mInMissionArea = true;
// <- RFB
Insert the following block of code inside Item::updatePos(). Insert it after the water condition as shown in the
following block of code.
// water
if(bool(safePtr))
{
if(!mInLiquid && mWaterCoverage != 0.0f)
{
Con::executef(mDataBlock,4,"onEnterLiquid",scriptThis(), Con::getFloatArg(mWaterCoverage),
Con::getIntArg(mLiquidType));
mInLiquid = true;
}
else if(mInLiquid && mWaterCoverage == 0.0f)
{
Con::executef(mDataBlock,3,"onLeaveLiquid",scriptThis(), Con::getIntArg(mLiquidType));
mInLiquid = false;
}
}
// RFB ->
checkMissionArea();
// <- RFB
Insert the following function.
void Item::checkMissionArea()
{
// Checks to see if the item is in the Mission Area...
Point3F pos;
MissionArea * obj = dynamic_cast(Sim::findObject("MissionArea"));
F32 flightCeiling = obj->getFlightCeiling();
F32 ceilingRange = obj->getFlightCeilingRange();
const RectI &area = obj->getArea();
getTransform().getColumn(3, &pos);
if ((pos.x < area.point.x || pos.x > area.point.x + area.extent.x ||
pos.y < area.point.y || pos.y > area.point.y + area.extent.y)) {
if(mInMissionArea) {
mInMissionArea = false;
Con::executef(mDataBlock,3,"onLeaveMissionArea",scriptThis());
}
}
else if(!mInMissionArea)
{
mInMissionArea = true;
Con::executef(mDataBlock,3,"onEnterMissionArea",scriptThis());
}
}
-----------------------------------------------------------------------------
3. torque\engine\game\projectile.cc
Change csmDynamicCollisionMask to include ItemObjectType as shown in the following block of code.
const U32 Projectile::csmDynamicCollisionMask = PlayerObjectType |
VehicleObjectType |
ItemObjectType | // RFB -> adding items to this damage mask
DamagableItemObjectType;
-----------------------------------------------------------------------------
4. Add the following torque script functions to the item class of your choice. Substitute the word 'Asteroid'
for whatever your object is called. You can define your own behavior if you want but I am creating asteroids
that will wrap around to the other side of the mission area when they leave the mission area.
function Asteroid::onLeaveMissionArea(%this, %obj)
{
//echo("Asteroid " @ %obj @ " left the mission area");
%pos = %obj.getTransform();
//echo("Asteroid " @ %obj @ " position = " @ %pos);
%missionArea = nameToId("MissionArea");
if (isObject(%missionArea))
{
// get mission area bounds
%area = %missionArea.getArea();
%minx = getWord(%area, 0);
%miny = getWord(%area, 1);
%maxx = %minx + getWord(%area, 2);
%maxy = %miny + getWord(%area, 3);
%minz = -1 * %missionArea.flightCeiling;
%maxz = %missionArea.flightCeilingRange;
// get asteroid location
%ax = getWord(%pos, 0);
%ay = getWord(%pos, 1);
%az = getWord(%pos, 2);
// max x reached?
if (%ax >= %maxx)
%ax = %ax - (%maxx - %minx);
// min x reached?
if (%ax <= %minx)
%ax = %ax + (%maxx - %minx);
// max y reached?
if (%ay >= %maxy)
%ay = %ay - (%maxy - %miny);
// min y reached?
if (%ay <= %miny)
%ay = %ay + (%maxy - %miny);
// max z reached?
if (%az >= %maxz)
%az = %az - (%maxz - %minz);
// min z reached?
if (%az <= %minz)
%az = %az + (%maxz - %minz);
%pos = %ax @ " " @ %ay @ " " @ %az;
//echo("Asteroid " @ %obj @ " new position = " @ %pos);
%obj.setTransform(%pos);
}
}
function Asteroid::onEnterMissionArea(%this, %obj)
{
//echo("Asteroid " @ %obj @ " entered the mission area");
//%pos = %obj.getTransform();
//echo("Asteroid " @ %obj @ " position = " @ %pos);
}
-----------------------------------------------------------------------------
5. Optional Space Environment modifications by Wendell Brown.
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=3007
-----------------------------------------------------------------------------
6. Optional 'Zero-G' modifications by Chris 'Dark' Evans
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=1723
-----------------------------------------------------------------------------
Good luck with your torque project! If you have questions or problems, post them so we can figure them out. Thanks!
Robert Brower
Prelude... I am working on a first person shooter in space. It is similar to the classic arcade game 'Asteroids'. I needed a way to create asteroids that would float around the mission area. One of the problems with this was that I needed a way to confine the asteroids to the mission area. Another problem was that projectiles normally don't collide with Items. To solve these problems follow these steps. If you are working on a space related game then you can also include the optional modifications by Wendell Brown and Chris 'Dark' Evans. I implemented some of their changes but not all of them.
The following instructions will enable you to create destructable Item objects that have mission area bounds checking.
1. torque\engine\game\item.h
Insert the following block of code into the private section of the class right after Box3F mWorkingQueryBox;
// RFB ->
void checkMissionArea();
bool mInMissionArea;
// <- RFB
-----------------------------------------------------------------------------
2. torque\engine\game\item.cc
Insert the following block of code right after #include "math/mathIO.h".
// RFB -> adding item mission area bounds check
#include "game/missionArea.h"
// <- RFB
Insert the following block of code inside Item::Item() right after mWorkingQueryBox.max.set(-1e9, -1e9, -1e9);
// RFB ->
mInMissionArea = true;
// <- RFB
Insert the following block of code inside Item::updatePos(). Insert it after the water condition as shown in the
following block of code.
// water
if(bool(safePtr))
{
if(!mInLiquid && mWaterCoverage != 0.0f)
{
Con::executef(mDataBlock,4,"onEnterLiquid",scriptThis(), Con::getFloatArg(mWaterCoverage),
Con::getIntArg(mLiquidType));
mInLiquid = true;
}
else if(mInLiquid && mWaterCoverage == 0.0f)
{
Con::executef(mDataBlock,3,"onLeaveLiquid",scriptThis(), Con::getIntArg(mLiquidType));
mInLiquid = false;
}
}
// RFB ->
checkMissionArea();
// <- RFB
Insert the following function.
void Item::checkMissionArea()
{
// Checks to see if the item is in the Mission Area...
Point3F pos;
MissionArea * obj = dynamic_cast
F32 flightCeiling = obj->getFlightCeiling();
F32 ceilingRange = obj->getFlightCeilingRange();
const RectI &area = obj->getArea();
getTransform().getColumn(3, &pos);
if ((pos.x < area.point.x || pos.x > area.point.x + area.extent.x ||
pos.y < area.point.y || pos.y > area.point.y + area.extent.y)) {
if(mInMissionArea) {
mInMissionArea = false;
Con::executef(mDataBlock,3,"onLeaveMissionArea",scriptThis());
}
}
else if(!mInMissionArea)
{
mInMissionArea = true;
Con::executef(mDataBlock,3,"onEnterMissionArea",scriptThis());
}
}
-----------------------------------------------------------------------------
3. torque\engine\game\projectile.cc
Change csmDynamicCollisionMask to include ItemObjectType as shown in the following block of code.
const U32 Projectile::csmDynamicCollisionMask = PlayerObjectType |
VehicleObjectType |
ItemObjectType | // RFB -> adding items to this damage mask
DamagableItemObjectType;
-----------------------------------------------------------------------------
4. Add the following torque script functions to the item class of your choice. Substitute the word 'Asteroid'
for whatever your object is called. You can define your own behavior if you want but I am creating asteroids
that will wrap around to the other side of the mission area when they leave the mission area.
function Asteroid::onLeaveMissionArea(%this, %obj)
{
//echo("Asteroid " @ %obj @ " left the mission area");
%pos = %obj.getTransform();
//echo("Asteroid " @ %obj @ " position = " @ %pos);
%missionArea = nameToId("MissionArea");
if (isObject(%missionArea))
{
// get mission area bounds
%area = %missionArea.getArea();
%minx = getWord(%area, 0);
%miny = getWord(%area, 1);
%maxx = %minx + getWord(%area, 2);
%maxy = %miny + getWord(%area, 3);
%minz = -1 * %missionArea.flightCeiling;
%maxz = %missionArea.flightCeilingRange;
// get asteroid location
%ax = getWord(%pos, 0);
%ay = getWord(%pos, 1);
%az = getWord(%pos, 2);
// max x reached?
if (%ax >= %maxx)
%ax = %ax - (%maxx - %minx);
// min x reached?
if (%ax <= %minx)
%ax = %ax + (%maxx - %minx);
// max y reached?
if (%ay >= %maxy)
%ay = %ay - (%maxy - %miny);
// min y reached?
if (%ay <= %miny)
%ay = %ay + (%maxy - %miny);
// max z reached?
if (%az >= %maxz)
%az = %az - (%maxz - %minz);
// min z reached?
if (%az <= %minz)
%az = %az + (%maxz - %minz);
%pos = %ax @ " " @ %ay @ " " @ %az;
//echo("Asteroid " @ %obj @ " new position = " @ %pos);
%obj.setTransform(%pos);
}
}
function Asteroid::onEnterMissionArea(%this, %obj)
{
//echo("Asteroid " @ %obj @ " entered the mission area");
//%pos = %obj.getTransform();
//echo("Asteroid " @ %obj @ " position = " @ %pos);
}
-----------------------------------------------------------------------------
5. Optional Space Environment modifications by Wendell Brown.
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=3007
-----------------------------------------------------------------------------
6. Optional 'Zero-G' modifications by Chris 'Dark' Evans
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=1723
-----------------------------------------------------------------------------
Good luck with your torque project! If you have questions or problems, post them so we can figure them out. Thanks!
Robert Brower
About the author
#2
Can you post the entire asteroids.cs file?
04/10/2003 (6:55 pm)
I don't see any code here showing an example of destroyable items.Can you post the entire asteroids.cs file?
#3
{
if (%obj.getDamageState() $= "Destroyed")
return;
%obj.applyDamage(%damage);
}
function Asteroid::onDamage(%this, %obj)
{
%damage = %obj.getDamageLevel();
if (%damage >= %this.destroyedLevel / %obj.scaleLevel)
{
if(%obj.getDamageState() !$= "Destroyed")
{
%obj.setDamageState(Destroyed);
}
}
else
{
if(%obj.getDamageState() !$= "Enabled")
%obj.setDamageState(Enabled);
}
}
function Asteroid::onDestroyed(%data, %obj, %prevState)
{
if (isObject(%obj))
{
%pos = %obj.getTransform();
%explosion = new explosion() {
dataBlock = "AsteroidExplosion";
position = %pos;
};
MissionCleanup.add(%explosion);
radiusDamage(%explosion,%pos,30,30,"Asteroid",30);
%minX = %obj.minX;
%maxX = %obj.maxX;
%minY = %obj.minY;
%maxY = %obj.maxY;
%minZ = %obj.minZ;
%maxZ = %obj.maxZ;
%obj.schedule(300, "delete");
}
}
04/23/2003 (9:04 pm)
function Asteroid::damage(%this, %obj, %sourceObject, %position, %damage, %damageType){
if (%obj.getDamageState() $= "Destroyed")
return;
%obj.applyDamage(%damage);
}
function Asteroid::onDamage(%this, %obj)
{
%damage = %obj.getDamageLevel();
if (%damage >= %this.destroyedLevel / %obj.scaleLevel)
{
if(%obj.getDamageState() !$= "Destroyed")
{
%obj.setDamageState(Destroyed);
}
}
else
{
if(%obj.getDamageState() !$= "Enabled")
%obj.setDamageState(Enabled);
}
}
function Asteroid::onDestroyed(%data, %obj, %prevState)
{
if (isObject(%obj))
{
%pos = %obj.getTransform();
%explosion = new explosion() {
dataBlock = "AsteroidExplosion";
position = %pos;
};
MissionCleanup.add(%explosion);
radiusDamage(%explosion,%pos,30,30,"Asteroid",30);
%minX = %obj.minX;
%maxX = %obj.maxX;
%minY = %obj.minY;
%maxY = %obj.maxY;
%minZ = %obj.minZ;
%maxZ = %obj.maxZ;
%obj.schedule(300, "delete");
}
}
#4
I uploaded a patch to apply on a clean 1.4.2 TGE install on my website here, and I left this resource's code commented out.
Can you give me some hints on what I done wrong? Thanks in advance for anything.
Bye, Berserk.
.
09/11/2007 (5:51 pm)
Hello. I had some troubles using this resource in my project (see here for details).I uploaded a patch to apply on a clean 1.4.2 TGE install on my website here, and I left this resource's code commented out.
Can you give me some hints on what I done wrong? Thanks in advance for anything.
Bye, Berserk.
.

Associate Edward F. Maurina III
Roaming Gamer LLC
-Ed