123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867 |
- #include "region_map_v1.h"
- #include "../../common/Log.h"
- #include "../client.h"
- #include "../Spawn.h"
- #include "../LuaInterface.h"
- #include "../World.h"
- #undef snprintf
- #include <boost/filesystem.hpp>
- extern LuaInterface* lua_interface;
- extern World world;
- RegionMapV1::RegionMapV1() {
- mVersion = 1;
- }
- RegionMapV1::~RegionMapV1() {
- std::unique_lock lock(MRegions);
- map<Region_Node*, ZBSP_Node*>::const_iterator itr;
- int region_num = 0;
- for (itr = Regions.begin(); itr != Regions.end();)
- {
- Region_Node* node = itr->first;
- ZBSP_Node* bsp_node = itr->second;
- map<Region_Node*, ZBSP_Node*>::const_iterator deleteItr = itr;
- itr++;
- Regions.erase(deleteItr);
- safe_delete(node);
- safe_delete_array(bsp_node);
- }
- Regions.clear();
- }
- WaterRegionType RegionMapV1::ReturnRegionType(const glm::vec3& location, int32 gridid) const {
- return BSPReturnRegionType(1, glm::vec3(location.x, location.y, location.z), gridid);
- }
- bool RegionMapV1::InWater(const glm::vec3& location, int32 gridid) const {
- return ReturnRegionType(location, gridid) == RegionTypeWater;
- }
- bool RegionMapV1::InLava(const glm::vec3& location, int32 gridid) const {
- return ReturnRegionType(location, gridid) == RegionTypeLava;
- }
- bool RegionMapV1::InLiquid(const glm::vec3& location) const {
- return InWater(location) || InLava(location);
- }
- bool RegionMapV1::InPvP(const glm::vec3& location) const {
- return ReturnRegionType(location) == RegionTypePVP;
- }
- bool RegionMapV1::InZoneLine(const glm::vec3& location) const {
- return ReturnRegionType(location) == RegionTypeZoneLine;
- }
- std::string RegionMapV1::TestFile(std::string testFile)
- {
- std::string tmpStr(testFile);
- std::size_t pos = tmpStr.find(".");
- if ( pos != testFile.npos )
- tmpStr = testFile.substr (0, pos);
-
- string tmpScript("RegionScripts/");
- tmpScript.append(mZoneNameLower);
- tmpScript.append("/" + tmpStr + ".lua");
- std::ifstream f(tmpScript.c_str());
- return f.good() ? tmpScript : string("");
- }
- bool RegionMapV1::Load(FILE* fp, std::string inZoneNameLwr, int32 version) {
- mZoneNameLower = string(inZoneNameLwr.c_str());
-
- uint32 region_size;
- if (fread(®ion_size, sizeof(uint32), 1, fp) != 1) {
- return false;
- }
- LogWrite(REGION__DEBUG, 0, "RegionMap", "region count = %u", region_size);
- for (int i = 0; i < region_size; i++)
- {
- uint32 region_num;
- if (fread(®ion_num, sizeof(uint32), 1, fp) != 1) {
- return false;
- }
- uint32 region_type;
- if (fread(®ion_type, sizeof(uint32), 1, fp) != 1) {
- return false;
- }
- float x, y, z, dist;
- if (fread(&x, sizeof(float), 1, fp) != 1) {
- return false;
- }
- if (fread(&y, sizeof(float), 1, fp) != 1) {
- return false;
- }
- if (fread(&z, sizeof(float), 1, fp) != 1) {
- return false;
- }
- if (fread(&dist, sizeof(float), 1, fp) != 1) {
- return false;
- }
- int8 strSize;
- char envName[256] = {""};
- char regionName[256] = {""};
- uint32 grid_id = 0;
- if ( version > 1 )
- {
- fread(&strSize, sizeof(int8), 1, fp);
- LogWrite(REGION__DEBUG, 7, "Region", "Region environment strSize = %u", strSize);
- if(strSize)
- {
- size_t len = fread(&envName, sizeof(char), strSize, fp);
- envName[len] = '\0';
- }
- LogWrite(REGION__DEBUG, 7, "Region", "Region environment file name = %s", envName);
- fread(&strSize, sizeof(int8), 1, fp);
- LogWrite(REGION__DEBUG, 7, "Region", "Region name strSize = %u", strSize);
- if(strSize)
- {
- size_t len = fread(®ionName, sizeof(char), strSize, fp);
- regionName[len] = '\0';
- }
-
- LogWrite(REGION__DEBUG, 7, "Region", "Region name file name = %s", regionName);
- if (fread(&grid_id, sizeof(uint32), 1, fp) != 1) {
- return false;
- }
- }
- int32 bsp_tree_size;
- if (fread(&bsp_tree_size, sizeof(int32), 1, fp) != 1) {
- return false;
- }
- LogWrite(REGION__DEBUG, 7, "Region", "region x,y,z,dist = %f, %f, %f, %f, region bsp tree size: %i\n", x, y, z, dist, bsp_tree_size);
- ZBSP_Node* BSP_Root = new ZBSP_Node[bsp_tree_size];
- if (fread(BSP_Root, sizeof(ZBSP_Node), bsp_tree_size, fp) != bsp_tree_size) {
- LogWrite(REGION__ERROR, 0, "RegionMap", "Failed to load region.");
- return false;
- }
- Region_Node* tmpNode = new Region_Node;
- tmpNode->x = x;
- tmpNode->y = y;
- tmpNode->z = z;
- tmpNode->dist = dist;
- tmpNode->region_type = region_type;
- tmpNode->regionName = string(regionName);
- tmpNode->regionEnvFileName = string(envName);
- tmpNode->grid_id = grid_id;
- tmpNode->regionScriptName = string("");
-
- tmpNode->regionScriptName = TestFile(regionName);
-
- if ( tmpNode->regionScriptName.size() < 1 )
- {
- tmpNode->regionScriptName = TestFile(envName);
- }
- if ( tmpNode->regionScriptName.size() < 1 )
- {
- tmpNode->regionScriptName = TestFile("default");
- }
-
- tmpNode->vert_count = bsp_tree_size;
-
- MRegions.lock();
- Regions.insert(make_pair(tmpNode, BSP_Root));
- MRegions.unlock();
- }
- fclose(fp);
- LogWrite(REGION__DEBUG, 0, "RegionMap", "completed load!");
- return true;
- }
- void RegionMapV1::IdentifyRegionsInGrid(Client *client, const glm::vec3 &location) const
- {
- std::shared_lock lock(MRegions);
- map<Region_Node*, ZBSP_Node*>::const_iterator itr;
- int region_num = 0;
- int32 grid = 0;
- int32 widget_id = 0;
- float x =0.0f,y = 0.0f,z = 0.0f;
- if (client->GetPlayer()->GetMap() != nullptr && client->GetPlayer()->GetMap()->IsMapLoaded())
- {
- auto loc = glm::vec3(location.x, location.z, location.y);
- float new_z = client->GetPlayer()->GetMap()->FindBestZ(loc, nullptr, &grid, &widget_id);
-
- std::map<int32, glm::vec3>::iterator itr = client->GetPlayer()->GetMap()->widget_map.find(widget_id);
- if(itr != client->GetPlayer()->GetMap()->widget_map.end()) {
- x = itr->second.x;
- y = itr->second.y;
- z = itr->second.z;
- }
- }
- else
- client->SimpleMessage(CHANNEL_COLOR_RED, "No map to establish grid id, using grid id 0 (attempt match all).");
- client->Message(2, "Region check against location %f / %f / %f. Grid to try: %u, player grid is %u, widget id is %u. Widget location is %f %f %f.", location.x, location.y, location.z, grid, client->GetPlayer()->appearance.pos.grid_id, widget_id, x, y, z);
- for (itr = Regions.begin(); itr != Regions.end(); itr++)
- {
- Region_Node *node = itr->first;
- ZBSP_Node *BSP_Root = itr->second;
- if (grid == 0 || node->grid_id == grid)
- {
- float x1 = node->x - location.x;
- float y1 = node->y - location.y;
- float z1 = node->z - location.z;
- float dist = sqrt(x1 *x1 + y1 *y1 + z1 *z1);
- glm::vec3 testLoc(location.x, location.y, location.z);
- if(!BSP_Root) {
- if(client)
- client->Message(CHANNEL_COLOR_YELLOW, "[%s] Region %i, GridID: %u, RegionName: %s, RegionEnvFileName: %s, Script: %s. X: %f, Y: %f, Z: %f, Distance: %f, Widget ID Marker: %u", (widget_id == node->trigger_widget_id) ? "IN REGION" : "WIDGET MARKER", region_num,
- node->grid_id, node->regionName.c_str(), node->regionEnvFileName.c_str(), node->regionScriptName.c_str(), node->x, node->y, node->z, node->dist, node->trigger_widget_id);
- }
- else if (dist <= node->dist)
- {
- WaterRegionType regionType = RegionTypeUntagged;
- if (node->region_type == ClassWaterRegion)
- regionType = BSPReturnRegionWaterRegion(node, BSP_Root, 1, testLoc, dist);
- else
- regionType = BSPReturnRegionTypeNode(node, BSP_Root, 1, testLoc, dist);
- if (regionType != RegionTypeNormal)
- {
- client->Message(CHANNEL_COLOR_YELLOW, "[DETECTED IN REGION %i] Region %i, GridID: %u, RegionName: %s, RegionEnvFileName: %s, distance: %f, X/Y/Z: %f / %f / %f. Script: %s", regionType, region_num, node->grid_id, node->regionName.c_str(), node->regionEnvFileName.c_str(),
- node->dist, node->x, node->y, node->z, node->regionScriptName.c_str());
- }
- else
- {
- client->Message(CHANNEL_COLOR_RED, "[IN DIST RANGE] Region %i, GridID: %u, RegionName: %s, RegionEnvFileName: %s, distance: %f, X/Y/Z: %f / %f / %f. Script: %s", region_num, node->grid_id, node->regionName.c_str(), node->regionEnvFileName.c_str(),
- node->dist, node->x, node->y, node->z, node->regionScriptName.c_str());
- }
- }
- else
- client->Message(CHANNEL_COLOR_RED, "[OUT OF RANGE] Region %i, GridID: %u, RegionName: %s, RegionEnvFileName: %s, distance: %f, X/Y/Z: %f / %f / %f. Script: %s", region_num, node->grid_id, node->regionName.c_str(), node->regionEnvFileName.c_str(),
- node->dist, node->x, node->y, node->z, node->regionScriptName.c_str());
- }
- else
- client->Message(CHANNEL_COLOR_RED, "[OUT OF GRID] Region %i, GridID: %u, RegionName: %s, RegionEnvFileName: %s, distance: %f, X/Y/Z: %f / %f / %f. Script: %s", region_num, node->grid_id, node->regionName.c_str(), node->regionEnvFileName.c_str(),
- node->dist, node->x, node->y, node->z, node->regionScriptName.c_str());
- region_num++;
- }
- }
- void RegionMapV1::MapRegionsNearSpawn(Spawn *spawn, Client *client) const
- {
- std::shared_lock lock(MRegions);
- map<Region_Node*, ZBSP_Node*>::const_iterator itr;
- int region_num = 0;
- spawn->RegionMutex.writelock();
- glm::vec3 testLoc(spawn->GetX(), spawn->GetY(), spawn->GetZ());
- for (itr = Regions.begin(); itr != Regions.end(); itr++)
- {
- Region_Node *node = itr->first;
- ZBSP_Node *BSP_Root = itr->second;
- if (node->regionScriptName.size() < 1) // only track ones that are used with LUA scripting
- continue;
- if(!BSP_Root) {
- int32 currentGridID = spawn->appearance.pos.grid_id;
- bool inRegion = false;
- if(!(inRegion = spawn->InRegion(node, nullptr)) && currentGridID == node->grid_id &&
- ( node->trigger_widget_id == spawn->trigger_widget_id || (node->dist > 0.0f && spawn->GetDistance(node->x, node->y, node->z) < node->dist)) ) {
- int32 returnValue = spawn->InsertRegionToSpawn(node, nullptr, RegionTypeUntagged);
- if (client)
- client->Message(CHANNEL_COLOR_YELLOW, "[ENTER REGION %i %u] Region %i, GridID: %u, RegionName: %s, RegionEnvFileName: %s, distance: %f, X/Y/Z: %f / %f / %f. Script: %s", RegionTypeUntagged, returnValue, region_num, node->grid_id, node->regionName.c_str(), node->regionEnvFileName.c_str(),
- node->dist, node->x, node->y, node->z, node->regionScriptName.c_str());
- }
- continue;
- }
-
- float x1 = node->x - testLoc.x;
- float y1 = node->y - testLoc.y;
- float z1 = node->z - testLoc.z;
- float dist = sqrt(x1 *x1 + y1 *y1 + z1 *z1);
- if (dist <= node->dist)
- {
- WaterRegionType regionType = RegionTypeUntagged;
- if (node->region_type == ClassWaterRegion)
- regionType = BSPReturnRegionWaterRegion(node, BSP_Root, 1, testLoc, dist);
- else
- regionType = BSPReturnRegionTypeNode(node, BSP_Root, 1, testLoc, dist);
- if (regionType != RegionTypeNormal)
- {
- if (!spawn->InRegion(node, BSP_Root))
- {
- spawn->DeleteRegion(node, BSP_Root);
- int32 returnValue = spawn->InsertRegionToSpawn(node, BSP_Root, regionType);
- if (client)
- client->Message(CHANNEL_COLOR_YELLOW, "[ENTER REGION %i %u] Region %i, GridID: %u, RegionName: %s, RegionEnvFileName: %s, distance: %f, X/Y/Z: %f / %f / %f. Script: %s", regionType, returnValue, region_num, node->grid_id, node->regionName.c_str(), node->regionEnvFileName.c_str(),
- node->dist, node->x, node->y, node->z, node->regionScriptName.c_str());
- }
- }
- else
- {
- if(spawn->HasRegionTracked(node, BSP_Root, false)) {
- continue;
- } // UpdateRegionsNearSpawn will capture it for nodes that have BSP_Root's
- if (spawn->InRegion(node, BSP_Root))
- {
- if (client)
- client->Message(CHANNEL_COLOR_RED, "[LEAVE REGION] Region %i, GridID: %u, RegionName: %s, RegionEnvFileName: %s, distance: %f, X/Y/Z: %f / %f / %f. Script: %s", region_num, node->grid_id, node->regionName.c_str(), node->regionEnvFileName.c_str(),
- node->dist, node->x, node->y, node->z, node->regionScriptName.c_str());
- WaterRegionType whatWasRegionType = (WaterRegionType) spawn->GetRegionType(node, BSP_Root);
- lua_interface->RunRegionScript(node->regionScriptName, "LeaveRegion", spawn->GetZone(), spawn, whatWasRegionType);
- }
- spawn->DeleteRegion(node, BSP_Root);
- spawn->InsertRegionToSpawn(node, BSP_Root, RegionTypeNormal, false);
- if (client)
- client->Message(CHANNEL_COLOR_RED, "[NEAR REGION] Region %i, GridID: %u, RegionName: %s, RegionEnvFileName: %s, distance: %f, X/Y/Z: %f / %f / %f. Script: %s", region_num, node->grid_id, node->regionName.c_str(), node->regionEnvFileName.c_str(),
- node->dist, node->x, node->y, node->z, node->regionScriptName.c_str());
- }
- }
- region_num++;
- }
- spawn->RegionMutex.releasewritelock();
- }
- void RegionMapV1::UpdateRegionsNearSpawn(Spawn *spawn, Client *client) const
- {
- std::shared_lock lock(MRegions);
- map<map<Region_Node*, ZBSP_Node*>, Region_Status>::iterator testitr;
- int region_num = 0;
- spawn->RegionMutex.writelock();
- glm::vec3 testLoc(spawn->GetX(), spawn->GetY(), spawn->GetZ());
- map<Region_Node*, ZBSP_Node*> deleteNodes;
- for (testitr = spawn->Regions.begin(); testitr != spawn->Regions.end(); testitr++)
- {
- map<Region_Node*, ZBSP_Node*>::const_iterator actualItr = testitr->first.begin();
- Region_Node *node = actualItr->first;
- ZBSP_Node *BSP_Root = actualItr->second;
- std::map<Region_Node*, bool>::const_iterator dead_itr = dead_nodes.find(node);
- if(dead_itr != dead_nodes.end()) {
- deleteNodes.insert(make_pair(node, BSP_Root));
- continue;
- }
- if(!BSP_Root) {
- continue;
- }
-
- float x1 = node->x - testLoc.x;
- float y1 = node->y - testLoc.y;
- float z1 = node->z - testLoc.z;
- float dist = sqrt(x1 *x1 + y1 *y1 + z1 *z1);
- if (dist <= node->dist)
- {
- WaterRegionType regionType = RegionTypeUntagged;
- if (node->region_type == ClassWaterRegion)
- regionType = BSPReturnRegionWaterRegion(node, BSP_Root, 1, testLoc, dist);
- else
- regionType = BSPReturnRegionTypeNode(node, BSP_Root, 1, testLoc, dist);
- if (regionType != RegionTypeNormal)
- {
- if (!testitr->second.inRegion)
- {
- testitr->second.inRegion = true;
- int32 returnValue = 0;
- lua_interface->RunRegionScript(node->regionScriptName, "EnterRegion", spawn->GetZone(), spawn, regionType, &returnValue);
- if (client)
- client->Message(CHANNEL_COLOR_YELLOW, "[ENTER RANGE %i %u] Region %i, GridID: %u, RegionName: %s, RegionEnvFileName: %s, distance: %f, X/Y/Z: %f / %f / %f. Script: %s", regionType, returnValue, region_num, node->grid_id, node->regionName.c_str(), node->regionEnvFileName.c_str(),
- node->dist, node->x, node->y, node->z, node->regionScriptName.c_str());
- testitr->second.timerTic = returnValue;
- testitr->second.lastTimerTic = returnValue ? Timer::GetCurrentTime2() : 0;
- }
- }
- else
- {
- if (testitr->second.inRegion)
- {
- testitr->second.inRegion = false;
- testitr->second.timerTic = 0;
- testitr->second.lastTimerTic = 0;
- if (client)
- client->Message(CHANNEL_COLOR_RED, "[LEAVE RANGE] Region %i, GridID: %u, RegionName: %s, RegionEnvFileName: %s, distance: %f, X/Y/Z: %f / %f / %f. Script: %s", region_num, node->grid_id, node->regionName.c_str(), node->regionEnvFileName.c_str(),
- node->dist, node->x, node->y, node->z, node->regionScriptName.c_str());
- WaterRegionType whatWasRegionType = (WaterRegionType) spawn->GetRegionType(node, BSP_Root);
- lua_interface->RunRegionScript(node->regionScriptName, "LeaveRegion", spawn->GetZone(), spawn, whatWasRegionType);
- }
- }
- }
- else
- {
- if (client)
- client->Message(CHANNEL_COLOR_RED, "[LEAVE RANGE - OOR] Region %i, GridID: %u, RegionName: %s, RegionEnvFileName: %s, distance: %f, X/Y/Z: %f / %f / %f. Script: %s", region_num, node->grid_id, node->regionName.c_str(), node->regionEnvFileName.c_str(),
- node->dist, node->x, node->y, node->z, node->regionScriptName.c_str());
- deleteNodes.insert(make_pair(node, BSP_Root));
- }
- region_num++;
- }
- map<Region_Node*, ZBSP_Node*>::const_iterator deleteItr;
- for (deleteItr = deleteNodes.begin(); deleteItr != deleteNodes.end(); deleteItr++)
- {
- Region_Node *tmpNode = deleteItr->first;
- ZBSP_Node *bspNode = deleteItr->second;
- spawn->DeleteRegion(tmpNode, bspNode);
- }
- spawn->RegionMutex.releasewritelock();
- }
- void RegionMapV1::TicRegionsNearSpawn(Spawn *spawn, Client *client) const
- {
- std::shared_lock lock(MRegions);
- map<map<Region_Node*, ZBSP_Node*>, Region_Status>::iterator testitr;
- int region_num = 0;
- spawn->RegionMutex.writelock();
- for (testitr = spawn->Regions.begin(); testitr != spawn->Regions.end();)
- {
- map<Region_Node*, ZBSP_Node*>::const_iterator actualItr = testitr->first.begin();
-
- if(actualItr == testitr->first.end()) {
- testitr++;
- continue;
- }
-
- Region_Node *node = actualItr->first;
- ZBSP_Node *BSP_Root = actualItr->second;
- std::map<Region_Node*, bool>::const_iterator dead_itr = dead_nodes.find(node);
- if(dead_itr != dead_nodes.end()) {
- testitr++;
- continue;
- }
-
- if(!BSP_Root) {
- bool passDistCheck = false;
- int32 currentGridID = spawn->appearance.pos.grid_id;
- if(testitr->second.timerTic && currentGridID == node->grid_id && (node->trigger_widget_id == spawn->trigger_widget_id || (node->dist > 0.0f && spawn->GetDistance(node->x, node->y, node->z) <= node->dist && (passDistCheck = true)))
- && Timer::GetCurrentTime2() >= (testitr->second.lastTimerTic + testitr->second.timerTic)) {
- testitr->second.lastTimerTic = Timer::GetCurrentTime2();
- if (client)
- client->Message(CHANNEL_COLOR_RED, "[TICK] Region %i, GridID: %u, RegionName: %s, RegionEnvFileName: %s, distance: %f, X/Y/Z: %f / %f / %f. Script: %s", region_num, node->grid_id, node->regionName.c_str(), node->regionEnvFileName.c_str(),
- node->dist, node->x, node->y, node->z, node->regionScriptName.c_str());
- int32 returnValue = 0;
- lua_interface->RunRegionScript(node->regionScriptName, "Tick", spawn->GetZone(), spawn, RegionTypeUntagged, &returnValue);
- if (returnValue == 1)
- {
- testitr->second.lastTimerTic = 0;
- testitr->second.timerTic = 0;
- }
- }
- else if(currentGridID != node->grid_id || (node->trigger_widget_id != spawn->trigger_widget_id && !passDistCheck)) {
- if (client)
- client->Message(CHANNEL_COLOR_RED, "[LEAVE REGION] Region %i, GridID: %u, RegionName: %s, RegionEnvFileName: %s, distance: %f, X/Y/Z: %f / %f / %f. Script: %s", region_num, node->grid_id, node->regionName.c_str(), node->regionEnvFileName.c_str(),
- node->dist, node->x, node->y, node->z, node->regionScriptName.c_str());
- lua_interface->RunRegionScript(node->regionScriptName, "LeaveRegion", spawn->GetZone(), spawn, RegionTypeUntagged);
- map<map<Region_Node*, ZBSP_Node*>, Region_Status>::iterator endItr = testitr;
- endItr++;
- spawn->DeleteRegion(node, nullptr);
- if(endItr == spawn->Regions.end()) {
- break;
- }
- else {
- testitr++;
- continue;
- }
-
- }
- }
- else if (testitr->second.timerTic && testitr->second.inRegion && Timer::GetCurrentTime2() >= (testitr->second.lastTimerTic + testitr->second.timerTic))
- {
- testitr->second.lastTimerTic = Timer::GetCurrentTime2();
- if (client)
- client->Message(CHANNEL_COLOR_RED, "[TICK] Region %i, GridID: %u, RegionName: %s, RegionEnvFileName: %s, distance: %f, X/Y/Z: %f / %f / %f. Script: %s", region_num, node->grid_id, node->regionName.c_str(), node->regionEnvFileName.c_str(),
- node->dist, node->x, node->y, node->z, node->regionScriptName.c_str());
- WaterRegionType whatWasRegionType = RegionTypeNormal; // default will be 0
- if (BSP_Root->special == SPECIAL_REGION_LAVA_OR_DEATH)
- whatWasRegionType = RegionTypeLava; // 2
- else if (BSP_Root->special == SPECIAL_REGION_WATER)
- whatWasRegionType = RegionTypeWater; // 1
- int32 returnValue = 0;
- lua_interface->RunRegionScript(node->regionScriptName, "Tick", spawn->GetZone(), spawn, whatWasRegionType, &returnValue);
- if (returnValue == 1)
- {
- testitr->second.lastTimerTic = 0;
- testitr->second.timerTic = 0;
- }
- }
- region_num++;
- testitr++;
- }
- spawn->RegionMutex.releasewritelock();
- }
- WaterRegionType RegionMapV1::BSPReturnRegionType(int32 node_number, const glm::vec3& location, int32 gridid) const {
- std::shared_lock lock(MRegions);
- map<Region_Node*, ZBSP_Node*>::const_iterator itr;
- int region_num = 0;
- for (itr = Regions.begin(); itr != Regions.end(); itr++)
- {
- Region_Node* node = itr->first;
- // did not match grid id of current region, skip
- //if ( gridid > 0 && gridid != node->grid_id)
- // continue;
- ZBSP_Node* BSP_Root = itr->second;
- float x1 = node->x - location.x;
- float y1 = node->y - location.y;
- float z1 = node->z - location.z;
- float dist = sqrt(x1 * x1 + y1 * y1 + z1 * z1);
- #ifdef REGIONDEBUG
- printf("Region %i (%i) dist %f / node dist %f. NodeXYZ: %f %f %f, XYZ: %f %f %f.\n", region_num, node->region_type, dist, node->dist, node->x, node->y, node->z, location.x, location.y, location.z);
- #endif
- if (dist <= node->dist)
- {
- ZBSP_Node* BSP_Root = itr->second;
- WaterRegionType regionType = RegionTypeUntagged;
- if (node->region_type == ClassWaterRegion)
- regionType = BSPReturnRegionWaterRegion(node, BSP_Root, node_number, location, dist);
- else
- regionType = BSPReturnRegionTypeNode(node, BSP_Root, node_number, location, dist);
- if (regionType != RegionTypeNormal)
- return regionType;
- }
- region_num++;
- }
- return(RegionTypeNormal);
- }
- WaterRegionType RegionMapV1::BSPReturnRegionTypeNode(const Region_Node* region_node, const ZBSP_Node* BSP_Root, int32 node_number, const glm::vec3& location, float distToNode) const {
- if(node_number > region_node->vert_count)
- {
- LogWrite(REGION__DEBUG, 0, "Region", "Region %s grid %u (%s) - Node %u is out of range for region max vert count of %i. Hit at location %f %f %f.",
- region_node->regionName.c_str(), region_node->grid_id, region_node->regionScriptName.c_str(), node_number, region_node->vert_count,
- location.x, location.y, location.z);
- return (RegionTypeWater);
- }
-
- const ZBSP_Node* current_node = &BSP_Root[node_number - 1];
- float distance;
- #ifdef REGIONDEBUG
- printf("left = %u, right %u (Size: %i)\n", current_node->left, current_node->right, region_node->vert_count);
- #endif
- if (region_node->region_type == ClassWaterRegion2)
- {
- distance = (location.x * current_node->normal[0]) +
- (location.y * current_node->normal[1]) +
- (location.z * current_node->normal[2]) +
- current_node->splitdistance;
- }
- else {
- distance = (location.x * current_node->normal[0]) +
- (location.y * current_node->normal[1]) +
- (location.z * current_node->normal[2]) -
- current_node->splitdistance;
- }
- float absDistance = distance;
- if (absDistance < 0.0f)
- absDistance *= -1.0f;
- float absSplitDist = current_node->splitdistance;
- if (absSplitDist < 0.0f)
- absSplitDist *= -1.0f;
- #ifdef REGIONDEBUG
- printf("distance = %f, normals: %f %f %f, location: %f %f %f, split distance: %f\n", distance, current_node->left, current_node->right, current_node->normal[0], current_node->normal[1], current_node->normal[2],
- location.x, location.y, location.z, current_node->splitdistance);
- #endif
- if ((current_node->left == -2) &&
- (current_node->right == -1 || current_node->right == -2)) {
- if (region_node->region_type == ClassWaterOcean || region_node->region_type == ClassWaterOcean2)
- {
- if ( region_node->region_type == ClassWaterOcean && current_node->right == -1 &&
- current_node->normal[1] >= 0.9f && distance > 0 )
- return RegionTypeWater;
- else
- return EstablishDistanceAtAngle(region_node, current_node, distance, absDistance, absSplitDist, true);
- }
- else
- {
- if (distance > 0)
- return(RegionTypeWater);
- else
- return RegionTypeNormal;
- }
- }
- else if ((region_node->region_type == ClassWaterOcean || region_node->region_type == ClassWaterOcean2) && current_node->normal[1] != 1.0f && current_node->normal[1] != -1.0f)
- {
- float fraction = abs(current_node->normal[0] * current_node->normal[2]);
- float diff = distToNode / region_node->dist;
- if (distance > 0)
- diff = distance * diff;
- #ifdef REGIONDEBUG
- printf("Diff: %f (%f + %f), fraction %f\n", diff, distToNode, distance, fraction);
- #endif
- if ((abs(diff) / 2.0f) > (absSplitDist * (1.0f / fraction)) * 2.0f)
- return RegionTypeNormal;
- }
- if (distance == 0.0f) {
- return(RegionTypeNormal);
- }
- if (distance > 0.0f) {
- #ifdef REGIONDEBUG
- printf("to left node %i\n", current_node->left);
- #endif
- if (current_node->left == -2)
- {
- switch(region_node->region_type)
- {
- case ClassWaterVolume:
- case ClassWaterOcean:
- return RegionTypeWater;
- break;
-
- case ClassWaterOcean2:
- return EstablishDistanceAtAngle(region_node, current_node, distance, absDistance, absSplitDist, false);
- break;
-
- case ClassWaterCavern:
- return EstablishDistanceAtAngle(region_node, current_node, distance, absDistance, absSplitDist, true);
- break;
-
- default:
- return RegionTypeNormal;
- break;
- }
- }
- else if (current_node->left == -1) {
- return(RegionTypeNormal);
- }
- return BSPReturnRegionTypeNode(region_node, BSP_Root, current_node->left + 1, location, distToNode);
- }
- #ifdef REGIONDEBUG
- printf("to right node %i, sign bit %i\n", current_node->right, signbit(current_node->normal[1]));
- #endif
- if (current_node->right == -1) {
- if (region_node->region_type == ClassWaterOcean2 && signbit(current_node->normal[1]) == 0 && absDistance < absSplitDist)
- return RegionTypeWater;
- else if ((region_node->region_type == ClassWaterOcean || region_node->region_type == ClassWaterOcean2) &&
- (current_node->normal[1] > 0.0f && distance < 0.0f && absDistance < absSplitDist))
- {
- return(RegionTypeWater);
- }
- return(RegionTypeNormal);
- }
- return BSPReturnRegionTypeNode(region_node, BSP_Root, current_node->right + 1, location, distToNode);
- }
- WaterRegionType RegionMapV1::BSPReturnRegionWaterRegion(const Region_Node* region_node, const ZBSP_Node* BSP_Root, int32 node_number, const glm::vec3& location, float distToNode) const {
- if(node_number > region_node->vert_count)
- {
- LogWrite(REGION__DEBUG, 0, "Region", "Region %s grid %u (%s) - Node %u is out of range for region max vert count of %i. Hit at location %f %f %f.",
- region_node->regionName.c_str(), region_node->grid_id, region_node->regionScriptName.c_str(), node_number, region_node->vert_count,
- location.x, location.y, location.z);
- return (RegionTypeNormal);
- }
- const ZBSP_Node* current_node = &BSP_Root[node_number - 1];
- float distance;
- #ifdef REGIONDEBUG
- printf("left = %u, right %u\n", current_node->left, current_node->right);
- #endif
- distance = (location.x * current_node->normal[0]) +
- (location.y * current_node->normal[1]) +
- (location.z * current_node->normal[2]) -
- current_node->splitdistance;
- #ifdef REGIONDEBUG
- printf("distance = %f, normals: %f %f %f, location: %f %f %f, split distance: %f\n", distance, current_node->left, current_node->right, current_node->normal[0], current_node->normal[1], current_node->normal[2],
- location.x, location.y, location.z, current_node->splitdistance);
- #endif
- if (distance > 0.0f) {
- #ifdef REGIONDEBUG
- printf("to left node %i\n", current_node->left);
- #endif
- if (current_node->left == -1) {
- return(RegionTypeNormal);
- }
- else if (current_node->left == -2) {
- switch(current_node->special)
- {
- case SPECIAL_REGION_LAVA_OR_DEATH:
- return(RegionTypeLava);
- break;
- case SPECIAL_REGION_WATER:
- return(RegionTypeWater);
- break;
- default:
- return(RegionTypeUntagged);
- break;
- }
- }
- return BSPReturnRegionWaterRegion(region_node, BSP_Root, current_node->left + 1, location, distToNode);
- }
- #ifdef REGIONDEBUG
- printf("to right node %i, sign bit %i\n", current_node->right, signbit(current_node->normal[1]));
- #endif
- if (current_node->right == -1) {
- return(RegionTypeNormal);
- }
- return BSPReturnRegionWaterRegion(region_node, BSP_Root, current_node->right + 1, location, distToNode);
- }
- WaterRegionType RegionMapV1::EstablishDistanceAtAngle(const Region_Node* region_node, const ZBSP_Node* current_node, float distance, float absDistance, float absSplitDist, bool checkEdgedAngle) const {
- float fraction = abs(current_node->normal[0] * current_node->normal[2]);
- #ifdef REGIONDEBUG
- printf("Distcheck: %f < %f\n", absDistance, absSplitDist);
- #endif
- if (absDistance < absSplitDist &&
- (current_node->normal[0] >= 1.0f || current_node->normal[0] <= -1.0f ||
- (current_node->normal[1] >= .9f && distance < 0.0f) ||
- (current_node->normal[1] <= -.9f && distance > 0.0f)))
- {
- return RegionTypeWater;
- }
- else if (fraction > 0.0f && (region_node->region_type == ClassWaterOcean2 || checkEdgedAngle))
- {
- if (current_node->normal[2] >= 1.0f || current_node->normal[2] <= -1.0f)
- return RegionTypeNormal;
- else if (current_node->normal[1] == 0.0f && (current_node->normal[0] < -0.5f || current_node->normal[0] > 0.5f) &&
- ((abs(absDistance * current_node->normal[0]) / 2.0f) < ((abs(absSplitDist * (1.0f / fraction))))))
- {
- return RegionTypeWater;
- }
- else if (current_node->normal[1] == 0.0f && (current_node->normal[2] < -0.5f || current_node->normal[2] > 0.5f) &&
- ((abs(absDistance * current_node->normal[2]) / 2.0f) < ((abs(absSplitDist * (1.0f / fraction))))))
- {
- return RegionTypeWater;
- }
- }
- return RegionTypeNormal;
- }
- void RegionMapV1::InsertRegionNode(ZoneServer* zone, int32 version, std::string regionName, std::string envName, uint32 gridID, uint32 triggerWidgetID, float dist)
- {
- Region_Node* tmpNode = new Region_Node;
-
- tmpNode->x = 0.0f;
- tmpNode->y = 0.0f;
- tmpNode->z = 0.0f;
-
- if(!zone)
- return;
-
- Map* current_map = world.GetMap(std::string(zone->GetZoneFile()), version);
- if(current_map) {
- std::map<int32, glm::vec3>::iterator itr = current_map->widget_map.find(triggerWidgetID);
- if(itr != current_map->widget_map.end()) {
- tmpNode->x = itr->second.x;
- tmpNode->y = itr->second.y;
- tmpNode->z = itr->second.z;
- }
- }
-
- tmpNode->dist = dist;
- tmpNode->region_type = RegionTypeUntagged;
- tmpNode->regionName = string(regionName);
- tmpNode->regionEnvFileName = string(envName);
- tmpNode->grid_id = gridID;
- tmpNode->regionScriptName = string("");
- tmpNode->trigger_widget_id = triggerWidgetID;
-
- tmpNode->regionScriptName = TestFile(regionName);
-
- if ( tmpNode->regionScriptName.size() < 1 )
- {
- tmpNode->regionScriptName = TestFile(envName);
- }
- if ( tmpNode->regionScriptName.size() < 1 )
- {
- tmpNode->regionScriptName = TestFile("default");
- }
-
- tmpNode->vert_count = 0;
- ZBSP_Node* BSP_Root = nullptr;
-
- MRegions.lock();
- Regions.insert(make_pair(tmpNode, BSP_Root));
- MRegions.unlock();
- }
- void RegionMapV1::RemoveRegionNode(std::string name) {
-
- std::unique_lock lock(MRegions);
- map<Region_Node*, ZBSP_Node*>::const_iterator itr;
- for (itr = Regions.begin(); itr != Regions.end();)
- {
- Region_Node *node = itr->first;
- ZBSP_Node *BSP_Root = itr->second;
- if(node->regionName.find(name) != node->regionName.npos) {
- itr = Regions.erase(itr);
- dead_nodes.insert(make_pair(node, true));
- safe_delete(node);
- safe_delete_array(BSP_Root);
- }
- else {
- itr++;
- }
- }
- }
|