Allow me to rephrase my previous response.
function Zone::GetCenterPos(%zonenum) does not return the center pos of the zone, because the math is all wrong. If you want to get the center point of a zone, you must first define the boundaries, then subtract the smaller numbers from the larger, divide by 2, and add the smaller number back (for each axis)... This function adds them together, then divides by 2, and that's all it does... This may result in a coordinate between the other coordinates, but not if the coordinates are the ones that you are using.
I'm not sure what the fuck function Zone::GetMeanDistance(%zonenum) does, but it has very little to do with the name of the function, as it's math is all wrong, too.
function Zone::SpawnCreature(%zonenum) also has some funky math shit going on... Frankly, I would delete all of this code and start from scratch, if I was you.
Here's some helpful functions I've written, that might be useful to you.
Code: Select all
// Defines the boundaries of a zone, one marker at a time.
function PathMarker::addToZone(%this)
{
%p = GameBase::getPosition(%this));
%x = getWord(%p, 0);
%y = getWord(%p, 1);
%z = getGroup(%this);
%z.east = getWord(%z.east @" "@ %x, %z.east < %x);
%z.north = getWord(%z.north @" "@ %y, %z.north < %y);
%z.south = getWord(%z.south @" "@ %y, %y < %z.south);
%z.west = getWord(%z.west @" "@ %x, %x < %z.west);
}
// Feeds all of the markers to the function that defines the zone boundaries.
Group::iterateRecurisve(MissionGroup, GameBase::virtual, "addToZone");
This code will define the boundaries of a zone, by saving the smallest and largest numbers on each axis (x and y only) in a variable array as properties of the marker's group.
Code: Select all
// Returns true (1) if the object is inside the zone, false (0) if not. What you do with that information is up to you.
function Zone::isInside(%this, %object)
{
%p = GameBase::getPosition(%object);
%x = getWord(%p, 0);
%y = getWord(%p, 1);
return (%this.West < %x && %x < %this.East && %this.South < %y && %y < %this.North);
}
This function determines if an object is inside or outside of a zone. You can choose to destroy, teleport, bounce, or whatever you want, with this info.
Code: Select all
// Terrain Elevation Detail, returns a position on top of the terrain, building, and other objects...
function ted(%pos)
{
if(getLOSInfo(Vector::add(%pos, "0 0 10000"), Vector::sub(%pos, "0 0 10000"), 1))
return $LOS::Position;
else
return %pos;
}
I wrote this function a long time ago, and have used it for many applications. I've used it for spawning zombies that pop out of the terrain, teleporting flags used as waypoints in race missions, marking boundaries on the terrain with beacons, etc...
Code: Select all
// Generates a random coordinate on top of terrain, buildings, and other objects...
function Zone::getRandomPos(%this)
{
return ted(%this.west + floor(getRandom() * (%this.east - %this.west)) @" "@ %this.south + floor(getRandom() * (%this.north - %this.south)) @" 0");
}
This function gets a random position inside a zone, which would be useful for spawning your burly bots.
Code: Select all
// Periodically instructs the bot to go to a random coordinate within it's zone.
function AI::periodicWaypoint(%aiName)
{
AI::directiveWaypoint(%aiName, Zone::getRandomPos(AI::getID(%aiName).zone), 1);
}
You'll need to set AI::getID(%aiName).zone to equal the group ID of the markers that define the zone, to make this work.