Mission Area Forcefield V2
by Leslie Young · 06/13/2003 (9:11 am) · 14 comments
Download Code File
in my previous Mission Area forcefield, the mission area was rendered in game.cc , there was some bad side effects like the forcefield showing up before translucent objects.
This new approach will rather cgange the missionArea class into a scene object rather than a simple net object it is currently, so that it can be put into the scene for rendering and thus sorted against other translucent objects.
In the included zip file you'll find replacement missionarea h and c files. im not gonna try explain all the changes in there as it's too much :) Credit should also go to Melv for his fxRednerObject that helped me understand what to do :)
Right, all this should render the mission area with some texture, don't run it yet, cause it won't work :b The follwing changes will add detection of the player leaving the mission area and then I''' show you some needed changes in the mission files. Now on to detecting the 'collision'. Open up player.h and find void checkMissionArea(); , and add, after it:
REMEMBER BEFORE REPLACING FILES OR MAKING HEAVY CHANGES YOU SHOULD BAK UP YOUR OLD FILES
player.cc Find bool Player::updatePos(const F32 travelTime) and in there find:
and change it to look like this (added the else):
Now find void Player::checkMissionArea() and change the function like this:
And add the following function after the previous one. This function will allow the flash to appear on the client's machine too, the above changes were not enough. The flash also appears on the other clients too.
Compile, and hopefully I remembered to show you everything that need be changed 8D
Now for some scripts:
Open up player.cs from server/scipts:
Find function Armor::onLeaveMissionArea(%this, %obj) and change like this:
and after that function add the following (this one is for when the player left the mission area via the roof, flight ceiling)
Another important thing is changes in the mission files, cause we added new fields in the code, and if you try loading the mission now it might not load, so check that your mission files has the following (for those that don't know, find your mission files in data/missions in fps, rw, or whatever path you are using). Open the .MIS (dot mis) files, in Tribal IDE or other text editor.
Look for something like this in there:
and change it like this:
Few notes:
This code will render a border for the mission's flight ceiling too, you can rip that out if not needed.
Explanation of the changes in your mission file:
normalTexture=...; is the texture to redner the mission area in (this can 64x64 png files with alpha values)
hitTexture=...; is the texture to show and fade when the player hits the border (this can be 64x64 png files with alpha values)
shakeFactor =0.3; is the force at which the field will shake, play with it.
bounce=50; is the force at which the player will be forced back when he hits the border.
There is a load of kewl things you could add, like start a particle effect when the player hit the border or play a sound effect, etc. I included a simple mission and some borders in the zip file.
Some notes on what I descovered while testing this:
* DTS shapes shows up correctly but any transparent objects in a DTS model will not show up behind the field - or the parts off the object it that is behind the field :/ (Not too big a problem - but might trouble people that wanna use pine trees that has translucency in the leaves
:(
* Normal INTERIORS sorts correct too
* so too an INTERIOR that makes use of transparent areas (i made a little wooden fence)
* A big one! The flash that appears when a player hits the field appear only on the client that hit it and on the server machine ... after some tests, like setting bounce=0 so a player could actually move beyond the field and thus have the flash appear constantly indicated that this actually does update on all client machines, in this case .. so there is some weird timing thing or something going on if the player is bounced back and not given enough time to stand in "out of mission area". ANY HELP ON THIS ONE WOULD BE MORE THAN WELCOME!!! (maybe someone that knows more about the sort types knows of a way to fix this?)
Well, hope ya like this one
in my previous Mission Area forcefield, the mission area was rendered in game.cc , there was some bad side effects like the forcefield showing up before translucent objects.
This new approach will rather cgange the missionArea class into a scene object rather than a simple net object it is currently, so that it can be put into the scene for rendering and thus sorted against other translucent objects.
In the included zip file you'll find replacement missionarea h and c files. im not gonna try explain all the changes in there as it's too much :) Credit should also go to Melv for his fxRednerObject that helped me understand what to do :)
Right, all this should render the mission area with some texture, don't run it yet, cause it won't work :b The follwing changes will add detection of the player leaving the mission area and then I''' show you some needed changes in the mission files. Now on to detecting the 'collision'. Open up player.h and find void checkMissionArea(); , and add, after it:
REMEMBER BEFORE REPLACING FILES OR MAKING HEAVY CHANGES YOU SHOULD BAK UP YOUR OLD FILES
void checkGhostMissionArea();
player.cc Find bool Player::updatePos(const F32 travelTime) and in there find:
if (!isGhost()) {
// Collisions are only queued on the server and can be
// generated by either updateMove or updatePos
notifyCollision();
// Do mission area callbacks on the server as well
checkMissionArea();
}and change it to look like this (added the else):
if (!isGhost()) {
// Collisions are only queued on the server and can be
// generated by either updateMove or updatePos
notifyCollision();
// Do mission area callbacks on the server as well
checkMissionArea();
} else
checkGhostMissionArea(); // leslie - mission areaNow find void Player::checkMissionArea() and change the function like this:
void Player::checkMissionArea()
{
// Checks to see if the player is in the Mission Area...
Point3F pos;
MissionArea * obj = dynamic_cast<MissionArea*>(Sim::findObject("MissionArea"));
const RectI &area = obj->getArea();
getTransform().getColumn(3, &pos);
// leslie - mission area - roof collision - start
F32 height;
height = obj->getFlightCeiling();
if (pos.z >= height) {
if(mInMissionArea) {
MissionArea::smWasHit = 1; // leslie : this will alow flash on server too
mInMissionArea = false;
Con::executef(mDataBlock,3,"onLeaveMissionAreaViaRoof",scriptThis());
}
} else
// leslie - end
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) {
MissionArea::smWasHit = 1; // leslie : this will allow flash on server too
mInMissionArea = false;
Con::executef(mDataBlock,3,"onLeaveMissionArea",scriptThis());
}
}
else if(!mInMissionArea)
{
mInMissionArea = true;
Con::executef(mDataBlock,3,"onEnterMissionArea",scriptThis());
}
}And add the following function after the previous one. This function will allow the flash to appear on the client's machine too, the above changes were not enough. The flash also appears on the other clients too.
//----------------------------------------------------------------------------
// leslie - mission area check - start
void Player::checkGhostMissionArea()
{
// - this is to make this client make a flash on it's own mission bounds
// - aa, this is soo cool, it also seems to be updating on other clients
// - and the server when a client hits the border
// - LESLIE : NOTE : if it seems not to be working it might be a timimg
// - problem, cause it does work if a player left te mission area.
// Checks to see if the player is in the Mission Area...
Point3F pos;
F32 height;
const RectI &area = MissionArea::smMissionArea;
getTransform().getColumn(3, &pos);
height = MissionArea::smFlightCeiling;
if (pos.z >= height) {
MissionArea::smWasHit = 1;
}
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)) {
MissionArea::smWasHit = 1;
}
}
// leslie - end
//----------------------------------------------------------------------------Compile, and hopefully I remembered to show you everything that need be changed 8D
Now for some scripts:
Open up player.cs from server/scipts:
Find function Armor::onLeaveMissionArea(%this, %obj) and change like this:
function Armor::onLeaveMissionArea(%this, %obj)
{
%obj.client.onLeaveMissionArea();
%force = MissionArea.bounce;
%min_x = getWord(MissionArea.area, 0);
%min_y = getWord(MissionArea.area, 1);
%max_x = %min_x + getWord(MissionArea.area, 2);
%max_y = %min_y + getWord(MissionArea.area, 3);
%x = getWord(%obj.getPosition(), 0);
%y = getWord(%obj.getPosition(), 1);
%vx = 0;%vy = 0;%vz = 0;
if (%x<(%min_x+10)) %vx = %force;
if (%y<(%min_y+10)) %vy = %force;
if (%x>(%max_x-10)) %vx = -%force;
if (%y>(%max_y-10)) %vy = -%force;
%vec = %vx @ " " @ %vy @ " " @ %vz;
%obj.setVelocity(%vec);
}and after that function add the following (this one is for when the player left the mission area via the roof, flight ceiling)
function Armor::onLeaveMissionAreaViaRoof(%this, %obj)
{
%obj.client.onLeaveMissionArea();
%force = MissionArea.bounce;
%min_x = getWord(MissionArea.area, 0);
%min_y = getWord(MissionArea.area, 1);
%max_x = %min_x + getWord(MissionArea.area, 2);
%max_y = %min_y + getWord(MissionArea.area, 3);
%x = getWord(%obj.getPosition(), 0);
%y = getWord(%obj.getPosition(), 1);
%vx = 0; %vy = 0; %vz = %force * -1;
if (%x<(%min_x+10)) %vx = %force;
if (%y<(%min_y+10)) %vy = %force;
if (%x>(%max_x-10)) %vx = -%force;
if (%y>(%max_y-10)) %vy = -%force;
%vec = %vx @ " " @ %vy @ " " @ %vz;
%obj.setVelocity(%vec);
}Another important thing is changes in the mission files, cause we added new fields in the code, and if you try loading the mission now it might not load, so check that your mission files has the following (for those that don't know, find your mission files in data/missions in fps, rw, or whatever path you are using). Open the .MIS (dot mis) files, in Tribal IDE or other text editor.
Look for something like this in there:
new MissionArea(MissionArea) {
area = "-256 -256 256 256";
flightCeiling = "300";
flightCeilingRange = "20";
locked = "true";
};and change it like this:
new MissionArea(MissionArea) {
area = "-256 -256 256 256";
flightCeiling = "300";
flightCeilingRange = "20";
shakeFactor = "0.3";
normalTexture = "mm/data/borders/border0";
hitTexture = "mm/data/borders/hit";
bounce = "50";
locked = "true";
};Few notes:
This code will render a border for the mission's flight ceiling too, you can rip that out if not needed.
Explanation of the changes in your mission file:
normalTexture=...; is the texture to redner the mission area in (this can 64x64 png files with alpha values)
hitTexture=...; is the texture to show and fade when the player hits the border (this can be 64x64 png files with alpha values)
shakeFactor =0.3; is the force at which the field will shake, play with it.
bounce=50; is the force at which the player will be forced back when he hits the border.
There is a load of kewl things you could add, like start a particle effect when the player hit the border or play a sound effect, etc. I included a simple mission and some borders in the zip file.
Some notes on what I descovered while testing this:
* DTS shapes shows up correctly but any transparent objects in a DTS model will not show up behind the field - or the parts off the object it that is behind the field :/ (Not too big a problem - but might trouble people that wanna use pine trees that has translucency in the leaves
:(
* Normal INTERIORS sorts correct too
* so too an INTERIOR that makes use of transparent areas (i made a little wooden fence)
* A big one! The flash that appears when a player hits the field appear only on the client that hit it and on the server machine ... after some tests, like setting bounce=0 so a player could actually move beyond the field and thus have the flash appear constantly indicated that this actually does update on all client machines, in this case .. so there is some weird timing thing or something going on if the player is bounced back and not given enough time to stand in "out of mission area". ANY HELP ON THIS ONE WOULD BE MORE THAN WELCOME!!! (maybe someone that knows more about the sort types knows of a way to fix this?)
Well, hope ya like this one
About the author
Recent Blogs
• TGEA GroundCover Terrain Surface Reference• Still around
• KBM update
• Finally some updates
• KBM.. More update
#2
For those who want some amusement out of this:
1. Make your mission area very small. (I used -30 -30 30 30)
2. Make your bouce factor really high. (I used 750)
3. Step into any mission area boundry.
4. Watch your player be flung from boundry to boundry.
5. See how long you can watch him before you get so dizzy that you pass out or vomit! My record is a magnificent 3 minutes 12 seconds. hehe :-)
06/29/2003 (4:28 pm)
Nice resource.For those who want some amusement out of this:
1. Make your mission area very small. (I used -30 -30 30 30)
2. Make your bouce factor really high. (I used 750)
3. Step into any mission area boundry.
4. Watch your player be flung from boundry to boundry.
5. See how long you can watch him before you get so dizzy that you pass out or vomit! My record is a magnificent 3 minutes 12 seconds. hehe :-)
#3
08/01/2003 (3:16 pm)
kewl :)
#4
03/21/2004 (10:50 pm)
Very cool. I can drive a vehicle through it though... I don't have time to fix it now, but when I do I will post the code. Or tell how I did it.
#5
In: bool MissionArea::prepRenderImage
Change,
04/23/2004 (6:11 am)
Picked up this code last night and got it working first time (so quodos Leslie), minus the render problem. Render probblem an easy fix tho. A simple one word change...In: bool MissionArea::prepRenderImage
Change,
image->sortType = SceneRenderImage::BeginSort;to
image->sortType = SceneRenderImage::EndSort;
#6
11/24/2004 (8:00 am)
Do you have a fix for vehicles driving thru the force field yet?
#7
11/24/2004 (2:47 pm)
Not yet, I had real life issues pop up and I'm just now getting back to it. It will be a bit before I'll tackle the force field issue again since I'm in the middle of making more character models. After I get them done and in the game I'll tackle the force field vehicle issue.
#8
http://sikosis.com/anon/Image1.png
http://sikosis.com/anon/Image2.png
I now also get an error message and torque won't start:-
Bad Object box!
engine\sim\sceneobject.cc @ 592
12/18/2004 (1:34 pm)
I think something is missing, I just added all the code above, I get the forcefield to appear and it turns yellow when the character hits it ... however, the character can still go right through it.http://sikosis.com/anon/Image1.png
http://sikosis.com/anon/Image2.png
I now also get an error message and torque won't start:-
Bad Object box!
engine\sim\sceneobject.cc @ 592
#9
Did anyone figure out how to make it so this works on vehicles as well? Especially flyer vehicle
01/23/2005 (11:53 am)
I just added this and it works great.Did anyone figure out how to make it so this works on vehicles as well? Especially flyer vehicle
#10
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=7051
01/25/2005 (11:11 am)
Here is the link for the resource I did for the vehicles:http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=7051
#11
03/12/2005 (10:56 am)
OMG This is very nice, and someone like myself who is a complete noob was able to understand it. GREAT JOB!!!!!!!!!
#12
04/25/2005 (2:59 am)
Excellent. We desperately needed something like this in our game and after trying this resource we found what we were looking for. Thanks for sharing!
#14
Only one thing, to work with new heads, change:
/* // OLD update for working with new heads 1.4.*
void MissionArea::consoleInit()
{
Con::addCommand("MissionArea", "getArea", cGetArea, "missionArea.getArea();", 2, 2);
Con::addCommand("MissionArea", "setArea", cSetArea, "missionArea.setArea(x, y, w, h);", 6, 6);
}
*/
//- WITH: ------
void MissionArea::consoleInit()
{
}
ConsoleMethod( MissionArea, getArea, const char *, 2, 2, "()"
"Returns 4 fields: starting x, starting y, extents x, extents y")
{
static char buf[48];
RectI area = object->getArea();
dSprintf(buf, sizeof(buf), "%d %d %d %d", area.point.x, area.point.y, area.extent.x, area.extent.y);
return(buf);
}
ConsoleMethod( MissionArea, setArea, void, 6, 6, "(int x, int y, int width, int height)")
{
if(object->isClientObject())
{
Con::errorf(ConsoleLogEntry::General, "MissionArea::cSetArea - cannot alter client object!");
return;
}
RectI rect;
rect.point.x = dAtoi(argv[2]);
rect.point.y = dAtoi(argv[3]);
rect.extent.x = dAtoi(argv[4]);
rect.extent.y = dAtoi(argv[5]);
object->setArea(rect);
}
03/07/2007 (10:05 pm)
This work Great!!!, Thanks Leslie!!!.Only one thing, to work with new heads, change:
/* // OLD update for working with new heads 1.4.*
void MissionArea::consoleInit()
{
Con::addCommand("MissionArea", "getArea", cGetArea, "missionArea.getArea();", 2, 2);
Con::addCommand("MissionArea", "setArea", cSetArea, "missionArea.setArea(x, y, w, h);", 6, 6);
}
*/
//- WITH: ------
void MissionArea::consoleInit()
{
}
ConsoleMethod( MissionArea, getArea, const char *, 2, 2, "()"
"Returns 4 fields: starting x, starting y, extents x, extents y")
{
static char buf[48];
RectI area = object->getArea();
dSprintf(buf, sizeof(buf), "%d %d %d %d", area.point.x, area.point.y, area.extent.x, area.extent.y);
return(buf);
}
ConsoleMethod( MissionArea, setArea, void, 6, 6, "(int x, int y, int width, int height)")
{
if(object->isClientObject())
{
Con::errorf(ConsoleLogEntry::General, "MissionArea::cSetArea - cannot alter client object!");
return;
}
RectI rect;
rect.point.x = dAtoi(argv[2]);
rect.point.y = dAtoi(argv[3]);
rect.extent.x = dAtoi(argv[4]);
rect.extent.y = dAtoi(argv[5]);
object->setArea(rect);
}

Torque Owner Jimomighty
Just also like to say the huts look cool! :D