What does this all mean? Before this, plugins like FlagStay, KOTH, and WWZone all had their own logic for handling custom zones separately and were limited with how they worked; a plug-in author had to write the logic for checking if a player was inside a zone and storing all the information about a zone's size and location and that's what this class is intended to do.
I will be using the CustomZoneSample plug-in, that is now part of the project and will be included in the next distribution, as an example.
Creating a Zone object
In this part of the code, I'm creating a class that will represent a single zone. Each zone will contain data about a flag and contain a message to be sent to players.
Code: Select all
// Our zone will be extending the class from the API
class MsgZone : public bz_CustomZoneObject
{
public:
// Our custom constructor will call the parent constructor so we can setup default positions
// for the zone
MsgZone() : bz_CustomZoneObject()
{
message = "";
flag = "US";
}
// Custom fields that are unique to our zone so we can build on top of the class we're extending
std::string message;
std::string flag;
};
I'll store all of our zone instances in a vector for easy access. You may use an array, list, etc.
Code: Select all
std::vector<MsgZone> msgZones;
In the MapObject() function that we'll be overloading, we're going to use the bz_CustomZoneObject's handleDefaultOptions() function to handle the following information:
For rectangular zones:
- position
- size
- rotation
- position
- height
- radius
Code: Select all
bool CustomZoneSample::MapObject (bz_ApiString object, bz_CustomMapObjectInfo *data)
{
// We'll ignore any map object that isn't a MSGZONE
if (object != "MSGZONE" || !data)
return false;
// The new zone we just found and we'll be storing in our vector of zones
MsgZone newZone;
newZone.handleDefaultOptions(data);
// Loop through the object data and pull out the "message" and "flag" fields
for (unsigned int i = 0; i < data->data.size(); i++)
{
std::string line = data->data.get(i).c_str();
bz_APIStringList *nubs = bz_newStringList();
nubs->tokenize(line.c_str(), " ", 0, true);
if (nubs->size() > 0)
{
std::string key = bz_toupper(nubs->get(0).c_str());
// These are our custom fields in the MsgZone class
if (key == "MESSAGE" && nubs->size() > 1)
{
newZone.message = nubs->get(1).c_str();
}
else if (key == "FLAG" && nubs->size() > 1)
{
newZone.flag = nubs->get(1).c_str();
}
}
bz_deleteStringList(nubs);
}
msgZones.push_back(newZone);
return true;
}
What does this mean for plugin developers? You only have to worry about extra information about zones, no need to worry about the math involved in calculating what the rotation of a zone is, or the height, or if a player is in the zone, etc.
Read more about the new syntax here.
How do I use this?
Simply call the pointInZone(float pos[3]) function in the bz_ePlayerUpdateEvent event with a float array.
Code: Select all
case bz_ePlayerUpdateEvent: // This event is called each time a player sends an update to the server
{
bz_PlayerUpdateEventData_V1* updateData = (bz_PlayerUpdateEventData_V1*)eventData;
// Loop through all of our custom zones
for (unsigned int i = 0; i < msgZones.size(); i++)
{
if (msgZones[i].pointInZone(updateData->state.pos))
{
// Do something here, the player is in the zone
}
}
}
For more examples, take a look at the flagStay and wwzone plug-ins as examples since they are already using this new API in the latest 2.4.x branch. There's also KOTH, but that's a nightmare.
Feel free to ask any questions or ask for clarification with anything I discussed.