Index: core3/trunk/MMOCoreORB/src/server/zone/ZoneImplementation.cpp =================================================================== diff -u -N -r3360 -r5681 --- core3/trunk/MMOCoreORB/src/server/zone/ZoneImplementation.cpp (.../ZoneImplementation.cpp) (revision 3360) +++ core3/trunk/MMOCoreORB/src/server/zone/ZoneImplementation.cpp (.../ZoneImplementation.cpp) (revision 5681) @@ -47,21 +47,23 @@ #include "ZoneProcessServer.h" #include "objects/scene/SceneObject.h" #include "server/zone/managers/structure/StructureManager.h" -#include "server/zone/managers/city/CityManager.h" #include "server/zone/managers/planet/PlanetManager.h" #include "server/zone/managers/creature/CreatureManager.h" #include "server/zone/managers/components/ComponentManager.h" #include "server/zone/managers/objectcontroller/ObjectController.h" #include "server/zone/templates/SharedObjectTemplate.h" #include "server/zone/packets/player/GetMapLocationsResponseMessage.h" -#include "server/zone/objects/building/cloning/CloningBuildingObject.h" #include "server/zone/objects/cell/CellObject.h" +#include "server/zone/objects/building/BuildingObject.h" #include "server/zone/templates/SharedObjectTemplate.h" #include "server/zone/templates/appearance/PortalLayout.h" #include "server/zone/templates/appearance/FloorMesh.h" #include "server/zone/templates/appearance/PathGraph.h" +#include "managers/minigames/FishingManager.h" +#include "managers/minigames/GamblingManager.h" +#include "managers/minigames/ForageManager.h" ZoneImplementation::ZoneImplementation(ZoneProcessServer* serv, const String& name) { processor = serv; @@ -84,23 +86,22 @@ planetManager = NULL; structureManager = NULL; - cityManager = NULL; + + setLoggingName("Zone " + name); } void ZoneImplementation::createContainerComponent() { containerComponent = ComponentManager::instance()->getComponent("ZoneContainerComponent"); } void ZoneImplementation::initializePrivateData() { - planetManager = new PlanetManager(_this, processor); + planetManager = new PlanetManager(_this.get(), processor); - structureManager = new StructureManager(_this, processor); + structureManager = new StructureManager(_this.get(), processor); - creatureManager = new CreatureManager(_this); + creatureManager = new CreatureManager(_this.get()); creatureManager->deploy("CreatureManager " + zoneName); creatureManager->setZoneProcessor(processor); - - cityManager = new CityManager(_this); } void ZoneImplementation::finalize() { @@ -123,19 +124,16 @@ } void ZoneImplementation::startManagers() { - //if (zoneID > 45) //TODO: Change back to 9 sometimes. We use Zone 10 (Space Corellia) as a "prison" for the CSRs sending bad players there - // return; - - //heightMap->load("planets/" + planetName + "/" + planetName + ".hmap"); - planetManager->initialize(); structureManager->initialize(); creatureManager->initialize(); - cityManager->loadLuaConfig(); + updateCityRegions(); + planetManager->loadShuttleTicketCollectors(); + ObjectDatabaseManager::instance()->commitLocalTransaction(); managersStarted = true; @@ -161,7 +159,7 @@ } /*void ZoneImplementation::registerObject(SceneObject* obj) { - server->addObject(obj); + server->transferObject(obj); } SceneObject* ZoneImplementation::lookupObject(uint64 oid) { @@ -183,95 +181,215 @@ float ZoneImplementation::getHeight(float x, float y) { if (heightMap->isLoaded()) return heightMap->getHeight(x, y); - else - return planetManager->getTerrainManager()->getHeight(x, y); + + if (planetManager != NULL) { + TerrainManager* manager = planetManager->getTerrainManager(); + + if (manager != NULL) + return manager->getHeight(x, y); + } + + return 0; } void ZoneImplementation::insert(QuadTreeEntry* entry) { - Locker locker(_this); + Locker locker(_this.get()); quadTree->insert(entry); } void ZoneImplementation::remove(QuadTreeEntry* entry) { - Locker locker(_this); + Locker locker(_this.get()); if (entry->isInQuadTree()) quadTree->remove(entry); } void ZoneImplementation::update(QuadTreeEntry* entry) { - Locker locker(_this); + Locker locker(_this.get()); quadTree->update(entry); } void ZoneImplementation::inRange(QuadTreeEntry* entry, float range) { - Locker locker(_this); - - quadTree->inRange(entry, range); + quadTree->safeInRange(entry, range); } -int ZoneImplementation::getInRangeObjects(float x, float y, float range, SortedVector >* objects) { - Locker locker(_this); +int ZoneImplementation::getInRangeObjects(float x, float y, float range, SortedVector >* objects, bool readLockZone) { + //Locker locker(_this.get()); - SortedVector entryObjects; + bool readlock = readLockZone && !_this.get()->isLockedByCurrentThread(); - quadTree->inRange(x, y, range, entryObjects); + Vector > buildingObjects; - for (int i = 0; i < entryObjects.size(); ++i) { - SceneObject* obj = dynamic_cast(entryObjects.get(i)); - objects->put(obj); +// _this.get()->rlock(readlock); + + try { + _this.getReferenceUnsafeStaticCast()->rlock(readlock); + + quadTree->inRange(x, y, range, *objects); + + _this.getReferenceUnsafeStaticCast()->runlock(readlock); + } catch (...) { + _this.getReferenceUnsafeStaticCast()->runlock(readlock); } + for (int i = 0; i < objects->size(); ++i) { + SceneObject* sceneObject = cast(objects->get(i).get()); + BuildingObject* building = dynamic_cast(sceneObject); + + if (building != NULL) { + for (int j = 1; j <= building->getMapCellSize(); ++j) { + CellObject* cell = building->getCell(j); + + if (cell != NULL) { + try { + for (int h = 0; h < cell->getContainerObjectsSize(); ++h) { + ManagedReference obj = cell->getContainerObject(h); + + if (obj != NULL) + buildingObjects.add(obj); + } + + } catch (...) { + } + } + } + } else if (sceneObject != NULL && sceneObject->isVehicleObject()) { + ManagedReference rider = sceneObject->getSlottedObject("rider"); + + if (rider != NULL) + buildingObjects.add(rider); + } + } + + //_this.get()->runlock(readlock); + + for (int i = 0; i < buildingObjects.size(); ++i) + objects->put(buildingObjects.get(i)); + return objects->size(); } -int ZoneImplementation::getInRangeActiveAreas(float x, float y, float range, SortedVector >* objects) { - Locker locker(_this); +int ZoneImplementation::getInRangeActiveAreas(float x, float y, SortedVector >* objects, bool readLockZone) { + //Locker locker(_this.get()); - SortedVector entryObjects; + bool readlock = readLockZone && !_this.get()->isLockedByCurrentThread(); - regionTree->inRange(x, y, range, entryObjects); + //_this.get()->rlock(readlock); + + Zone* thisZone = _this.getReferenceUnsafeStaticCast(); - for (int i = 0; i < entryObjects.size(); ++i) { - ActiveArea* obj = dynamic_cast(entryObjects.get(i)); - objects->put(obj); + try { + thisZone->rlock(readlock); + + SortedVector > entryObjects; + + regionTree->inRange(x, y, entryObjects); + + thisZone->runlock(readlock); + + for (int i = 0; i < entryObjects.size(); ++i) { + ActiveArea* obj = dynamic_cast(entryObjects.get(i).get()); + objects->put(obj); + } + }catch (...) { +// _this.get()->runlock(readlock); + + throw; } +// _this.get()->runlock(readlock); + return objects->size(); } void ZoneImplementation::updateActiveAreas(SceneObject* object) { + //Locker locker(_this.get()); + SortedVector > areas = *dynamic_cast >* >(object->getActiveAreas()); Vector3 worldPos = object->getWorldPosition(); - SortedVector entryObjects; + SortedVector > entryObjects; - regionTree->inRange(worldPos.getX(), worldPos.getY(), 512, entryObjects); + Zone* managedRef = _this.getReferenceUnsafeStaticCast(); - // update old ones - for (int i = 0; i < areas.size(); ++i) { - ManagedReference area = areas.get(i); + bool readlock = !managedRef->isLockedByCurrentThread(); - if (!area->containsPoint(worldPos.getX(), worldPos.getY())) { - object->dropActiveArea(area); - area->enqueueExitEvent(object); - } + managedRef->rlock(readlock); + + try { + regionTree->inRange(worldPos.getX(), worldPos.getY(), entryObjects); + } catch (...) { + error("unexpeted error caught in void ZoneImplementation::updateActiveAreas(SceneObject* object) {"); } - // we update the ones in quadtree. - for (int i = 0; i < entryObjects.size(); ++i) { - //update in new ones - ActiveArea* activeArea = dynamic_cast(entryObjects.get(i)); + managedRef->runlock(readlock); - if (!object->hasActiveArea(activeArea) && activeArea->containsPoint(worldPos.getX(), worldPos.getY())) { - object->addActiveArea(activeArea); - activeArea->enqueueEnterEvent(object); + //locker.release(); + + + managedRef->unlock(!readlock); + + try { + + // update old ones + for (int i = 0; i < areas.size(); ++i) { + ManagedReference area = areas.get(i); +// Locker lockerO(object); + +// Locker locker(area, object); + + if (!area->containsPoint(worldPos.getX(), worldPos.getY())) { + object->dropActiveArea(area); + area->enqueueExitEvent(object); +// area->notifyExit(object); + } else { + area->notifyPositionUpdate(object); + } } + + // we update the ones in quadtree. + for (int i = 0; i < entryObjects.size(); ++i) { + //update in new ones + ActiveArea* activeArea = dynamic_cast(entryObjects.get(i).get()); + + if (!object->hasActiveArea(activeArea) && activeArea->containsPoint(worldPos.getX(), worldPos.getY())) { + //Locker lockerO(object); + + //Locker locker(activeArea, object); + + object->addActiveArea(activeArea); + activeArea->enqueueEnterEvent(object); + //activeArea->notifyEnter(object); + } + } + + // update world areas + Vector >* worldAreas = creatureManager->getWorldSpawnAreas(); + + for (int i = 0; i < worldAreas->size(); ++i) { + ActiveArea* activeArea = worldAreas->get(i); + Locker lockerO(object); + +// Locker locker(activeArea, object); + + if (!object->hasActiveArea(activeArea)) { + object->addActiveArea(activeArea); + //activeArea->enqueueEnterEvent(object); + activeArea->notifyEnter(object); + } else { + activeArea->notifyPositionUpdate(object); + } + } + } catch (...) { + error("unexpected exception caught in void ZoneImplementation::updateActiveAreas(SceneObject* object) {"); + managedRef->wlock(!readlock); + throw; } + managedRef->wlock(!readlock); } void ZoneImplementation::addSceneObject(SceneObject* object) { @@ -284,7 +402,7 @@ #ifndef WITH_STM Locker locker(mapLocations); #endif - mapLocations->addObject(object); + mapLocations->transferObject(object); } void ZoneImplementation::unregisterObjectWithPlanetaryMap(SceneObject* object) { @@ -304,91 +422,31 @@ player->sendMessage(gmlr); } -CloningBuildingObject* ZoneImplementation::getNearestCloningBuilding(CreatureObject* creature) { - ManagedReference cloning = NULL; +SceneObject* ZoneImplementation::getNearestPlanetaryObject(SceneObject* object, const String& mapObjectLocationType) { + ManagedReference planetaryObject = NULL; #ifndef WITH_STM mapLocations->rlock(); #endif - try { - //cloning type 5 - int index = mapLocations->findLocation("cloningfacility"); + SortedVector& sortedVector = mapLocations->getLocation(mapObjectLocationType); - float distance = 16000.f; - - if (index != -1) { - SortedVector& sortedVector = mapLocations->get(index); - - for (int i = 0; i < sortedVector.size(); ++i) { - SceneObject* object = sortedVector.get(i).getObject(); - - if (object->isCloningBuildingObject()) { - float objDistance = object->getDistanceTo(creature); - - if (objDistance < distance) { - cloning = cast( object); - distance = objDistance; - } - } - } - - } - } catch (...) { #ifndef WITH_STM - mapLocations->runlock(); -#endif - - throw; - } - -#ifndef WITH_STM mapLocations->runlock(); #endif - return cloning.get(); -} + float distance = 16000.f; -SceneObject* ZoneImplementation::getNearestPlanetaryObject(SceneObject* object, const String& mapObjectLocationType) { - ManagedReference planetaryObject = NULL; + for (int i = 0; i < sortedVector.size(); ++i) { + SceneObject* obj = sortedVector.get(i).getObject(); -#ifndef WITH_STM - mapLocations->rlock(); -#endif + float objDistance = object->getDistanceTo(obj); - try { - //cloning type 5 - - int index = mapLocations->findLocation(mapObjectLocationType); - - float distance = 16000.f; - - if (index != -1) { - SortedVector& sortedVector = mapLocations->get(index); - - for (int i = 0; i < sortedVector.size(); ++i) { - SceneObject* vectorObject = sortedVector.get(i).getObject(); - - float objDistance = vectorObject->getDistanceTo(object); - - if (objDistance < distance) { - planetaryObject = vectorObject; - distance = objDistance; - } - } - + if (objDistance < distance) { + planetaryObject = obj; + distance = objDistance; } - } catch (...) { -#ifndef WITH_STM - mapLocations->runlock(); -#endif - - throw; } - -#ifndef WITH_STM - mapLocations->runlock(); -#endif return planetaryObject.get(); } @@ -433,3 +491,43 @@ float ZoneImplementation::getMaxY() { return planetManager->getTerrainManager()->getMax(); } + +void ZoneImplementation::updateCityRegions() { + info("updating " + String::valueOf(cityRegionUpdateVector.size()) + " cities", true); + + for (int i = 0; i < cityRegionUpdateVector.size(); ++i) { + CityRegion* city = cityRegionUpdateVector.get(i); + + Time* nextUpdateTime = city->getNextUpdateTime(); + int seconds = -1 * round(nextUpdateTime->miliDifference() / 1000.f); + + if (seconds < 0) //If the update occurred in the past, force an immediate update. + seconds = 0; + + city->setLoaded(); + + city->rescheduleUpdateEvent(seconds); + } + + cityRegionUpdateVector.removeAll(); +} + +bool ZoneImplementation::isWithinBoundaries(const Vector3& position) { + //Remove 1/16th of the size to match client limits. NOTE: it has not been verified to work like this in the client. + //Normal zone size is 8192, 1/16th of that is 512 resulting in 7680 as the boundary value. + float maxX = getMaxX() * 15 / 16; + float minX = getMinX() * 15 / 16; + float maxY = getMaxY() * 15 / 16; + float minY = getMinY() * 15 / 16; + + if (maxX >= position.getX() && minX <= position.getX() && + maxY >= position.getY() && minY <= position.getY()) { + return true; + } else { + return false; + } +} + +float ZoneImplementation::getBoundingRadius() { + return planetManager->getTerrainManager()->getMax(); +}