uint64 CreatureObject::getNearestAttackingDefender(void) { uint64 defenederId = 0; float minLenght = FLT_MAX; ObjectIDList::iterator it = mDefenders.begin(); while(it != mDefenders.end()) { if((*it) != 0) { CreatureObject* defender = dynamic_cast<CreatureObject*>(gWorldManager->getObjectById((*it))); if (defender && !defender->isDead() && !defender->isIncapacitated()) { if ((defender->getCreoGroup() == CreoGroup_Player) || (defender->getCreoGroup() == CreoGroup_Creature)) { float len = glm::distance(this->mPosition, defender->mPosition); if (len < minLenght) { minLenght = len; defenederId = (*it); } } } } ++it; } return defenederId; }
void CellFactory::handleObjectReady(Object* object,DispatchClient* client) { InLoadingContainer* ilc = _getObject(object->getParentId()); if (! ilc) {//Crashbug fix: http://paste.swganh.org/viewp.php?id=20100627114151-8f7df7f74013af71c0d0b00bc240770d LOG(warning) << "Could not locate InLoadingContainer for object parent id [" << object->getParentId() << "]"; return; } CellObject* cell = dynamic_cast<CellObject*>(ilc->mObject); gWorldManager->addObject(object,true); switch(object->getType()) { case ObjType_NPC: case ObjType_Creature: { CreatureObject* creature = dynamic_cast<CreatureObject*>(object); if(creature->getCreoGroup() == CreoGroup_Shuttle) gWorldManager->addShuttle(dynamic_cast<Shuttle*>(creature)); } break; case ObjType_Tangible: { PlayerStructureTerminal* terminal = dynamic_cast<PlayerStructureTerminal*>(object); if(terminal) { terminal->setStructure(cell->getParentId()); } } break; case ObjType_Building: case ObjType_Cell: case ObjType_DraftSchematic: case ObjType_Structure: case ObjType_Intangible: case ObjType_Lair: case ObjType_Mission: case ObjType_None: case ObjType_NonPersistant: case ObjType_Player: case ObjType_Region: case ObjType_Waypoint: default: break; } auto permissions_objects_ = gObjectManager->GetPermissionsMap(); object->SetPermissions(permissions_objects_.find(swganh::object::DEFAULT_PERMISSION)->second.get());//CREATURE_PERMISSION gObjectManager->LoadSlotsForObject(object); cell->InitializeObject(object); cell->incLoad(); //LOG(info) << "cellFactory::handleObjectReady -> cell load stuff" << object->getId() << "for " << cell->getId(); //LOG(info) << "loadcount : " << cell->getLoadCount() << " : count : " << cell->getLoad(); if(cell->getLoadCount() == cell->getLoad()) { //LOG(info) << "cellFactory::handleObjectReady -> cell done " << cell->getId(); if(!(_removeFromObjectLoadMap(cell->getId()))) LOG(warning) << "Failed removing object from loadmap"; ilc->mOfCallback->handleObjectReady(cell,ilc->mClient); mILCPool.free(ilc); } }
void CellFactory::handleObjectReady(Object* object,DispatchClient* client) { InLoadingContainer* ilc = _getObject(object->getParentId()); if (! ilc) {//Crashbug fix: http://paste.swganh.org/viewp.php?id=20100627114151-8f7df7f74013af71c0d0b00bc240770d gLogger->log(LogManager::WARNING,"CellFactory::handleObjectReady could not locate ILC for objectParentId:%I64u",object->getParentId()); return; } CellObject* cell = dynamic_cast<CellObject*>(ilc->mObject); gWorldManager->addObject(object,true); switch(object->getType()) { case ObjType_NPC: case ObjType_Creature: { CreatureObject* creature = dynamic_cast<CreatureObject*>(object); if(creature->getCreoGroup() == CreoGroup_Shuttle) gWorldManager->addShuttle(dynamic_cast<Shuttle*>(creature)); } break; case ObjType_Tangible: { PlayerStructureTerminal* terminal = dynamic_cast<PlayerStructureTerminal*>(object); if(terminal) { terminal->setStructure(cell->getParentId()); } } break; case ObjType_Building: case ObjType_Cell: case ObjType_DraftSchematic: case ObjType_Structure: case ObjType_Intangible: case ObjType_Lair: case ObjType_Mission: case ObjType_None: case ObjType_NonPersistant: case ObjType_Player: case ObjType_Region: case ObjType_Waypoint: default: break; } cell->addObjectSecure(object); if(cell->getLoadCount() == cell->getObjects()->size()) { if(!(_removeFromObjectLoadMap(cell->getId()))) gLogger->log(LogManager::DEBUG,"CellFactory: Failed removing object from loadmap"); ilc->mOfCallback->handleObjectReady(cell,ilc->mClient); mILCPool.free(ilc); } }
bool WorldManager::addObject(Object* object,bool manual) { uint64 key = object->getId(); //make sure objects arnt added several times!!!! if(getObjectById(key)) { gLogger->logMsgF("WorldManager::addObject Object already existant added several times or ID messup ???",MSG_HIGH); return false; } mObjectMap.insert(key,object); // if we want to set the parent manually or the object is from the snapshots and not a building, return if(manual) { return true; } #if defined(_MSC_VER) if(object->getId() < 0x0000000100000000 && object->getType() != ObjType_Building) #else if(object->getId() < 0x0000000100000000LLU && object->getType() != ObjType_Building) #endif { // check if a crafting station - in that case add Item* item = dynamic_cast<Item*> (object); if(item) { if(!(item->getItemFamily() == ItemFamily_CraftingStations)) return true; } else { return true; } } switch(object->getType()) { // player, when a player enters a planet case ObjType_Player: { PlayerObject* player = dynamic_cast<PlayerObject*>(object); gLogger->logMsgF("New Player: %"PRIu64", Total Players on zone : %i",MSG_NORMAL,player->getId(),(getPlayerAccMap())->size() + 1); // insert into the player map mPlayerAccMap.insert(std::make_pair(player->getAccountId(),player)); // insert into cell if(player->getParentId()) { player->setSubZoneId(0); if(CellObject* cell = dynamic_cast<CellObject*>(getObjectById(player->getParentId()))) { cell->addObjectSecure(player); } else { gLogger->logMsgF("WorldManager::addObject: couldn't find cell %"PRIu64"",MSG_HIGH,player->getParentId()); } } // query the rtree for the qt region we are in else { if(QTRegion* region = mSpatialIndex->getQTRegion(player->mPosition.x,player->mPosition.z)) { player->setSubZoneId((uint32)region->getId()); region->mTree->addObject(player); } else { // we should never get here ! gLogger->logMsg("WorldManager::addObject: could not find zone region in map"); return false; } } // initialize initObjectsInRange(player); gMessageLib->sendCreatePlayer(player,player); // add ham to regeneration scheduler player->getHam()->updateRegenRates(); // ERU: Note sure if this is needed here. player->getHam()->checkForRegen(); // onPlayerEntered event, notify scripts string params; params.setLength(sprintf(params.getAnsi(),"%s %s %u",getPlanetNameThis(),player->getFirstName().getAnsi(),static_cast<uint32>(mPlayerAccMap.size()))); mWorldScriptsListener.handleScriptEvent("onPlayerEntered",params); // Start player world position update. Used when player don't get any events from client (player not moving). // addPlayerMovementUpdateTime(player, 1000); } break; case ObjType_Structure: { // HarvesterObject* harvester = dynamic_cast<HarvesterObject*>(object); mStructureList.push_back(object->getId()); mSpatialIndex->InsertPoint(key,object->mPosition.x,object->mPosition.z); } break; case ObjType_Building: { mStructureList.push_back(object->getId()); BuildingObject* building = dynamic_cast<BuildingObject*>(object); mSpatialIndex->InsertRegion(key,building->mPosition.x,building->mPosition.z,building->getWidth(),building->getHeight()); } break; case ObjType_Tangible: { uint64 parentId = object->getParentId(); if(parentId == 0) { mSpatialIndex->InsertPoint(key,object->mPosition.x,object->mPosition.z); } else { CellObject* cell = dynamic_cast<CellObject*>(getObjectById(parentId)); if(cell) cell->addObjectSecure(object); else gLogger->logMsgF("WorldManager::addObject couldn't find cell %"PRIu64"",MSG_NORMAL,parentId); } } break; // TODO: add moving creatures to qtregions case ObjType_NPC: case ObjType_Creature: case ObjType_Lair: { CreatureObject* creature = dynamic_cast<CreatureObject*>(object); if(creature->getCreoGroup() == CreoGroup_Shuttle) mShuttleList.push_back(dynamic_cast<Shuttle*>(creature)); uint64 parentId = creature->getParentId(); if(parentId) { CellObject* cell = dynamic_cast<CellObject*>(getObjectById(parentId)); if(cell) cell->addObjectSecure(creature); else gLogger->logMsgF("WorldManager::addObject: couldn't find cell %"PRIu64"",MSG_HIGH,parentId); } else { switch(creature->getCreoGroup()) { // moving creature, add to QT case CreoGroup_Vehicle : { if(QTRegion* region = mSpatialIndex->getQTRegion(creature->mPosition.x,creature->mPosition.z)) { creature->setSubZoneId((uint32)region->getId()); region->mTree->addObject(creature); } else { gLogger->logMsg("WorldManager::addObject: could not find zone region in map for creature"); return false; } } break; // still creature, add to SI default : { mSpatialIndex->InsertPoint(key,creature->mPosition.x,creature->mPosition.z); } } } } break; case ObjType_Region: { RegionObject* region = dynamic_cast<RegionObject*>(object); mRegionMap.insert(std::make_pair(key,region)); mSpatialIndex->InsertRegion(key,region->mPosition.x,region->mPosition.z,region->getWidth(),region->getHeight()); if(region->getActive()) addActiveRegion(region); } break; case ObjType_Intangible: { gLogger->logMsgF("Object of type ObjType_Intangible UNHANDLED in WorldManager::addObject:",MSG_HIGH); } break; default: { gLogger->logMsgF("Unhandled ObjectType in WorldManager::addObject: PRId32",MSG_HIGH,object->getType()); // Please, when adding new stufff, at least take the time to add a stub for that type. // Better fail always, than have random crashes. assert(false && "WorldManager::addObject Unhandled ObjectType"); } break; } return true; }
void WorldManager::destroyObject(Object* object) { switch(object->getType()) { case ObjType_Player: { //destroys knownObjects in the destructor PlayerObject* player = dynamic_cast<PlayerObject*>(object); // moved most of the code to the players destructor // onPlayerLeft event, notify scripts string params; params.setLength(sprintf(params.getAnsi(),"%s %s %u",getPlanetNameThis(),player->getFirstName().getAnsi(),static_cast<uint32>(mPlayerAccMap.size()))); mWorldScriptsListener.handleScriptEvent("onPlayerLeft",params); // gLogger->logMsg("WorldManager::destroyObject: Player Client set to NULL"); delete player->getClient(); player->setClient(NULL); player->setConnectionState(PlayerConnState_Destroying); } break; case ObjType_NPC: case ObjType_Creature: { CreatureObject* creature = dynamic_cast<CreatureObject*>(object); // remove any timers we got running removeCreatureHamToProcess(creature->getHam()->getTaskId()); // remove from cell / SI if (!object->getParentId()) { // Not all objects-creatures of this type are points. if(creature->getSubZoneId()) { if(QTRegion* region = getQTRegion(creature->getSubZoneId())) { creature->setSubZoneId(0); region->mTree->removeObject(creature); } } else { mSpatialIndex->RemovePoint(object->getId(),object->mPosition.x,object->mPosition.z); } } else { if(CellObject* cell = dynamic_cast<CellObject*>(getObjectById(object->getParentId()))) { cell->removeObject(object); } else { //gLogger->logMsgF("WorldManager::destroyObject: couldn't find cell %"PRIu64"",MSG_HIGH,object->getParentId()); } } // destroy known objects object->destroyKnownObjects(); // if its a shuttle, remove it from the shuttle list if(creature->getCreoGroup() == CreoGroup_Shuttle) { ShuttleList::iterator shuttleIt = mShuttleList.begin(); while(shuttleIt != mShuttleList.end()) { if((*shuttleIt)->getId() == creature->getId()) { mShuttleList.erase(shuttleIt); break; } ++shuttleIt; } } } break; case ObjType_Structure: { // cave what do we do with player cities ?? // then the parent Id should be the region object. shouldnt it???? if(object->getSubZoneId()) { if(QTRegion* region = getQTRegion(object->getSubZoneId())) { object->setSubZoneId(0); region->mTree->removeObject(object); } } else { mSpatialIndex->RemovePoint(object->getId(),object->mPosition.x,object->mPosition.z); } object->destroyKnownObjects(); //remove it out of the worldmanagers structurelist now that it is deleted ObjectIDList::iterator itStruct = mStructureList.begin(); while(itStruct != mStructureList.end()) { if((*itStruct)==object->getId()) itStruct = mStructureList.erase(itStruct); else itStruct++; } } break; case ObjType_Building: { BuildingObject* building = dynamic_cast<BuildingObject*>(object); if(building) { if(object->getSubZoneId()) { if(QTRegion* region = getQTRegion(object->getSubZoneId())) { object->setSubZoneId(0); region->mTree->removeObject(object); } } else { //mSpatialIndex->InsertRegion(key,building->mPosition.x,building->mPosition.z,building->getWidth(),building->getHeight()); mSpatialIndex->RemoveRegion(object->getId(),object->mPosition.x-building->getWidth(),object->mPosition.z-building->getHeight(),object->mPosition.x+building->getWidth(),object->mPosition.z+building->getHeight()); } //remove it out of the worldmanagers structurelist now that it is deleted ObjectIDList::iterator itStruct = mStructureList.begin(); while(itStruct != mStructureList.end()) { if((*itStruct)==object->getId()) itStruct = mStructureList.erase(itStruct); else itStruct++; } } else gLogger->logMsgF("WorldManager::destroyObject: nearly did not remove: %"PRIu64"s knownObjectList",MSG_HIGH,object->getId()); object->destroyKnownObjects(); } break; case ObjType_Cell: { //a cell shouldnt have knownobjects ... -that should be checked to make sure it is true object->destroyKnownObjects(); } break; case ObjType_Tangible: { if(TangibleObject* tangible = dynamic_cast<TangibleObject*>(object)) { uint64 parentId = tangible->getParentId(); if(parentId == 0) { mSpatialIndex->RemovePoint(tangible->getId(),tangible->mPosition.x,tangible->mPosition.z); } else { if(CellObject* cell = dynamic_cast<CellObject*>(getObjectById(parentId))) { cell->removeObject(object); } else { // Well, Tangible can have more kind of parents than just cells or SI. For example players or Inventory. // the tangible is owned by its containing object (please note exeption of inventory / player with equipped stuff) // however we should leave the object link in the worldmanagers Objectmap and only store references in the object // we will have great trouble finding items otherwise //gLogger->logMsgF("WorldManager::destroyObject couldn't find cell %"PRIu64"",MSG_NORMAL,parentId); } } } else { gLogger->logMsgF("WorldManager::destroyObject: error removing : %"PRIu64"",MSG_HIGH,object->getId()); } // destroy known objects object->destroyKnownObjects(); } break; case ObjType_Region: { RegionMap::iterator it = mRegionMap.find(object->getId()); if(it != mRegionMap.end()) { mRegionMap.erase(it); } else { gLogger->logMsgF("Worldmanager::destroyObject: Could not find region %"PRIu64"",MSG_NORMAL,object->getId()); } //camp regions are in here, too QTRegionMap::iterator itQ = mQTRegionMap.find(static_cast<uint32>(object->getId())); if(itQ != mQTRegionMap.end()) { mQTRegionMap.erase(itQ); gLogger->logMsgF("Worldmanager::destroyObject: qt region %"PRIu64"",MSG_HIGH,object->getId()); } object->destroyKnownObjects(); } break; case ObjType_Intangible: { gLogger->logMsgF("Object of type ObjType_Intangible almost UNHANDLED in WorldManager::destroyObject:",MSG_HIGH); // intangibles are controllers / pets in the datapad // they are NOT in the world //we really shouldnt have any of thoose object->destroyKnownObjects(); } break; default: { gLogger->logMsgF("Unhandled ObjectType in WorldManager::destroyObject: %u",MSG_HIGH,(uint32)(object->getType())); // Please, when adding new stufff, at least take the time to add a stub for that type. // Better fail always, than have random crashes. assert(false && "WorldManager::destroyObject Unhandled ObjectType"); } break; } object->destroyKnownObjects(); // finally delete it ObjectMap::iterator objMapIt = mObjectMap.find(object->getId()); if(objMapIt != mObjectMap.end()) { mObjectMap.erase(objMapIt); } else { gLogger->logMsgF("WorldManager::destroyObject: error removing from objectmap: %"PRIu64"",MSG_HIGH,object->getId()); } }