//====================================================================================================================== // // Handle npc conversations that has expired. // bool WorldManager::_handleNpcConversionTimers(uint64 callTime,void* ref) { NpcConversionTimers::iterator it = mNpcConversionTimers.begin(); while (it != mNpcConversionTimers.end()) { // gLogger->log(LogManager::DEBUG,"WorldManager::_handleNpcConversionTimers: Checking callTime %"PRIu64" againts %"PRIu64"", callTime, (*it).second); // Npc timer has expired? if (callTime >= ((*it).second)->mInterval) { // gLogger->log(LogManager::DEBUG,"Calling restorePosition()"); // Yes, rotate npc back to original position. if (PlayerObject* player = dynamic_cast<PlayerObject*>(getObjectById(((*it).second)->mTargetId))) { if (NPCObject* npc = dynamic_cast<NPCObject*>(getObjectById((*it).first))) { npc->restorePosition(player); } } // Remove npc from list. // gLogger->log(LogManager::DEBUG,"\nActivated and deleted %"PRIu64"", ((*it).second)->mTargetId); delete ((*it).second); it = mNpcConversionTimers.erase(it); continue; } ++it; } return (true); }
bool WorldManager::_handleGeneralObjectTimers(uint64 callTime, void* ref) { CreatureObjectDeletionMap::iterator it = mCreatureObjectDeletionMap.begin(); while (it != mCreatureObjectDeletionMap.end()) { // The timer has expired? if (callTime >= ((*it).second)) { // Is it a valid object? CreatureObject* creature = dynamic_cast<CreatureObject*>(getObjectById((*it).first)); if (creature) { // Yes, handle it. We may put up a copy of this npc... NpcManager::Instance()->handleExpiredCreature((*it).first); this->destroyObject(creature); mCreatureObjectDeletionMap.erase(it++); } else { // Remove the invalid object...from this list. mCreatureObjectDeletionMap.erase(it++); } } else { ++it; } } PlayerObjectReviveMap::iterator reviveIt = mPlayerObjectReviveMap.begin(); while (reviveIt != mPlayerObjectReviveMap.end()) { // The timer has expired? if (callTime >= ((*reviveIt).second)) { PlayerObject* player = dynamic_cast<PlayerObject*>(getObjectById((*reviveIt).first)); if (player) { // Yes, handle it. // Send the player to closest cloning facility. player->cloneAtNearestCloningFacility(); // The cloning request removes itself from here, have to restart the iteration. reviveIt = mPlayerObjectReviveMap.begin(); } else { // Remove the invalid object... mPlayerObjectReviveMap.erase(reviveIt++); } } else { ++reviveIt; } } return (true); }
void WorldManager::initPlayersInRange(Object* object,PlayerObject* player) { // we still query for players here, cause they are found through the buildings and arent kept in a qtree ObjectSet inRangeObjects; mSpatialIndex->getObjectsInRange(object,&inRangeObjects,(ObjType_Player),gWorldConfig->getPlayerViewingRange()); // query the according qtree, if we are in one if(object->getSubZoneId()) { if(QTRegion* region = getQTRegion(object->getSubZoneId())) { float viewingRange = _GetMessageHeapLoadViewingRange(); //float viewingRange = (float)gWorldConfig->getPlayerViewingRange(); Anh_Math::Rectangle qRect; if(!object->getParentId()) { qRect = Anh_Math::Rectangle(object->mPosition.x - viewingRange,object->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2); } else { CellObject* cell = dynamic_cast<CellObject*>(getObjectById(object->getParentId())); BuildingObject* building = dynamic_cast<BuildingObject*>(getObjectById(cell->getParentId())); qRect = Anh_Math::Rectangle(building->mPosition.x - viewingRange,building->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2); } region->mTree->getObjectsInRange(object,&inRangeObjects,ObjType_Player,&qRect); } } // iterate through the results ObjectSet::iterator it = inRangeObjects.begin(); while(it != inRangeObjects.end()) { PlayerObject* pObject = dynamic_cast<PlayerObject*>(*it); if(pObject) { if(pObject != player) { gMessageLib->sendCreateObject(object,pObject); pObject->addKnownObjectSafe(object); object->addKnownObjectSafe(pObject); } } ++it; } }
/** * Attempt to move the player as instructed * * @param dungeon A pointer to the dungeon * @param move The move to make * * @return RESULT_WIN if the player has won the game * RESULT_DIE if the player has died in the game * INVALID_MOVE if the move is invalid * else 0 */ int makeMove(Dungeon* dungeon, char move) { Object *player; int result=0; int len; if(!dungeon->moveList) { dungeon->moveList = malloc(EXTEND_MOVE*4+1); bzero(dungeon->moveList, EXTEND_MOVE*4+1); } len = cgc_strlen(dungeon->moveList); sprintf(&dungeon->moveList[len], "!H", (unsigned char) move); if(!(player = getObjectById(dungeon->start, PLAYER_NUM))) _terminate(OBJECT_NOT_FOUND_ERROR); if(move == dungeon->moveTypes.left) { player->direction->x = 0; if((result = moveLeft(dungeon, player))) return result; if((result = moveEnemies(dungeon, player->moves))) return result; sendCurrentDungeonView(dungeon->start); if((result = checkFloor(dungeon, player))) return result; } else if(move == dungeon->moveTypes.right) { player->direction->x = 0; if((result = moveRight(dungeon, player))) return result; if((result = moveEnemies(dungeon, player->moves))) return result; sendCurrentDungeonView(dungeon->start); if((result = checkFloor(dungeon, player))) return result; } else if(move == dungeon->moveTypes.jump) return jump(dungeon, player); else if (move == dungeon->moveTypes.jumpleft) return jumpLeft(dungeon, player); else if (move == dungeon->moveTypes.jumpright) return jumpRight(dungeon, player); else if (move == dungeon->moveTypes.wait) { addMove(dungeon, player, dungeon->moveTypes.wait); if((result = moveEnemies(dungeon, player->moves))) return result; sendCurrentDungeonView(dungeon->start); return 0; } else return INVALID_MOVE; return 0; }
//============================================================================= bool Inventory::itemExist(uint32 familyId, uint32 typeId) { bool found = false; ObjectIDList::iterator invObjectIt = getObjects()->begin(); // Items inside inventory and child objects. while (invObjectIt != getObjects()->end()) { Object* object = getObjectById(*invObjectIt); Item* item = dynamic_cast<Item*>(object); if (item) { if ((item->getItemFamily() == familyId) && (item->getItemType() == typeId)) { found = true; break; } } invObjectIt++; } if (!found) { // Items equipped by the player. PlayerObject* player = dynamic_cast<PlayerObject*>(gWorldManager->getObjectById(this->getParentId())); if(!player) return found; ObjectList* objList = player->getEquipManager()->getEquippedObjects(); ObjectList::iterator equippedObjectIt = objList->begin(); while (equippedObjectIt != objList->end()) { Object* object = (*equippedObjectIt); Item* item = dynamic_cast<Item*>(object); if (item) { if ((item->getItemFamily() == familyId) && (item->getItemType() == typeId)) { found = true; break; } } equippedObjectIt++; } delete objList; } return found; }
/** * Let the player know they have died * * @param dungeon A pointer to the dungeon and game info * * @return None */ void playerDied(Dungeon dungeon) { char buffer[1024]; Object* player; size_t len; bzero(buffer, 1024); if(!(player = getObjectById(dungeon.start, PLAYER_NUM))) _terminate(OBJECT_NOT_FOUND_ERROR); sprintf(buffer, " at position x:!U y:!U after !U moves\n", player->position->x, player->position->y, player->moves); len = cgc_strlen(buffer); if(transmit_all(STDOUT, buffer, len)) _terminate(TRANSMIT_ERROR); }
bool WorldManager::_handlePlayerMovementUpdateTimers(uint64 callTime, void* ref) { PlayerMovementUpdateMap::iterator it = mPlayerMovementUpdateMap.begin(); while (it != mPlayerMovementUpdateMap.end()) { PlayerObject* player = dynamic_cast<PlayerObject*>(getObjectById((*it).first)); if (player) { if (player->isConnected()) { // The timer has expired? if (callTime >= ((*it).second)) { // Yes, handle it. ObjectController* ObjCtl = player->getController(); uint64 next = ObjCtl->playerWorldUpdate(false); mPlayerMovementUpdateMap.erase(it++); if (next) { // Add next scheduled update. addPlayerMovementUpdateTime(player, next); } } else { ++it; } } else { // Remove the disconnected... mPlayerMovementUpdateMap.erase(it++); } } else { // Remove the disconnected... mPlayerMovementUpdateMap.erase(it++); } } return (true); }
/** * pick.c * * Handles the picking an object. */ int handlePicking() { renderMode = GL_SELECT; glRenderMode(renderMode); glInitNames(); glPushName(-1); displayFunction(); renderMode = GL_RENDER; hits = glRenderMode(renderMode); fprintf(stdout, "# pick hits = %d\n", hits); if(hits > 0) { int choose = pickBuffer[3]; int depth = pickBuffer[1]; int loop; for (loop = 1; loop < hits; loop++) { // select the closest object if (pickBuffer[loop*4+1] < (GLuint)depth) { choose = pickBuffer[loop*4+3]; depth = pickBuffer[loop*4+1]; } } printf("Selected item id => %d\n\n", choose); object *selectedObject = getObjectById(choose); if(selectedObject->data->selected) { selectedObject->data->selected = 0; selectedObjectId = 0; } else { selectedObject->data->selected = 1; selectedObjectId = choose; } return 0; } return 1; }
/** * Let the player know they have won and record score * * @param dungeon A pointer to the dungeon and game info * * @return None */ void playerWon(Dungeon* dungeon) { char buffer[1024]; char* ml_buffer; Object* player; size_t len; bzero(buffer, 1024); if(!(player = getObjectById(dungeon->start, PLAYER_NUM))) _terminate(OBJECT_NOT_FOUND_ERROR); sprintf(buffer, "You found the treasure at position x:!U y:!U after !U moves\n", player->position->x, player->position->y, player->moves); len = cgc_strlen(buffer); if(transmit_all(STDOUT, buffer, len)) _terminate(TRANSMIT_ERROR); len = cgc_strlen(MOVELIST_HDR); len += cgc_strlen(dungeon->moveList); len += cgc_strlen("\n"); if(!(ml_buffer = malloc(len+1))) { _terminate(ALLOCATE_ERROR); } bzero(ml_buffer, len+1); sprintf(ml_buffer, "!X!X\n", MOVELIST_HDR, dungeon->moveList); if(transmit_all(STDOUT, ml_buffer, len)) _terminate(TRANSMIT_ERROR); bzero(ml_buffer, len+1); free(ml_buffer); addHighScore(dungeon, player->moves); }
/** * Send the current Dungeon view * NOTE: The current view will only show a partial view of the dungeon * based on the players current position. * * @param start A pointer to the first room in the dungeon * * @return None */ void sendCurrentDungeonView(Room* start) { Object* player; char view[VIEW_WIDTH]; int center_x, center_y; int height_diff, width_diff; int room_idx; size_t bytes; if(!(player = getObjectById(start, PLAYER_NUM))) _terminate(OBJECT_NOT_FOUND_ERROR); center_x = player->position->x; center_y = player->position->y; height_diff = (VIEW_HEIGHT - 1)/2; width_diff = (VIEW_WIDTH - 1)/2; room_idx = center_x / (ROOM_WIDTH - 1); int i; for(i=height_diff*(-1); i<=height_diff; i++) { bzero(view, VIEW_WIDTH); for(int j=width_diff*(-1); j<=width_diff; j++) { if(i+center_y < ROOM_HEIGHT && i+center_y >= 0) { if(j+center_x < room_idx*ROOM_WIDTH + ROOM_WIDTH && j+center_x >= room_idx*ROOM_WIDTH) { Room* room; if(!(room = getRoom(start, room_idx))) view[j+width_diff] = ' '; else view[j+width_diff] = room->contents[i+center_y][(j+center_x)%ROOM_WIDTH]->symbol; } else if(j+center_x >= room_idx*ROOM_WIDTH + ROOM_WIDTH) { Room* next_room; if(!(next_room = getRoom(start, room_idx+1))) view[j+width_diff] = ' '; else { view[j+width_diff] = next_room->contents[i+center_y][(j+center_x)%ROOM_WIDTH]->symbol; } } else if(j+center_x < room_idx*ROOM_WIDTH) { Room* prev_room; if(!(prev_room = getRoom(start, room_idx-1))) view[j+width_diff] = ' '; else { view[j+width_diff] = prev_room->contents[i+center_y][(j+center_x)%ROOM_WIDTH]->symbol; } } } else view[j+width_diff] = ' '; } #ifdef DEBUG if(transmit_all(STDOUT, &view, VIEW_WIDTH)) _terminate(TRANSMIT_ERROR); if(transmit_all(STDOUT, "\n", cgc_strlen("\n"))) _terminate(TRANSMIT_ERROR); #endif } }
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::initObjectsInRange(PlayerObject* playerObject) { float viewingRange = _GetMessageHeapLoadViewingRange(); //if we are in a playerbuilding create the playerbuilding first //otherwise our items will not show when they are created before the cell if(CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(playerObject->getParentId()))) { if(HouseObject* playerHouse = dynamic_cast<HouseObject*>(gWorldManager->getObjectById(cell->getParentId()))) { //gLogger->logMsgF("create playerbuilding",MSG_HIGH); gMessageLib->sendCreateObject(playerHouse,playerObject); playerHouse->addKnownObjectSafe(playerObject); playerObject->addKnownObjectSafe(playerHouse); } } // we still query for players here, cause they are found through the buildings and arent kept in a qtree ObjectSet inRangeObjects; mSpatialIndex->getObjectsInRange(playerObject,&inRangeObjects,(ObjType_Player | ObjType_Tangible | ObjType_NPC | ObjType_Creature | ObjType_Building | ObjType_Structure ),viewingRange); // query the according qtree, if we are in one if(playerObject->getSubZoneId()) { if(QTRegion* region = getQTRegion(playerObject->getSubZoneId())) { Anh_Math::Rectangle qRect; if(!playerObject->getParentId()) { qRect = Anh_Math::Rectangle(playerObject->mPosition.x - viewingRange,playerObject->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2); } else { CellObject* cell = dynamic_cast<CellObject*>(getObjectById(playerObject->getParentId())); if(BuildingObject* house = dynamic_cast<BuildingObject*>(getObjectById(cell->getParentId()))) { qRect = Anh_Math::Rectangle(house->mPosition.x - viewingRange,house->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2); } } region->mTree->getObjectsInRange(playerObject,&inRangeObjects,ObjType_Player,&qRect); } } // iterate through the results ObjectSet::iterator it = inRangeObjects.begin(); while(it != inRangeObjects.end()) { Object* object = (*it); // send create for the type of object if (object->getPrivateOwner()) //what is this about ?? does it concern instances ???? { if (object->isOwnedBy(playerObject)) { gMessageLib->sendCreateObject(object,playerObject); object->addKnownObjectSafe(playerObject); playerObject->addKnownObjectSafe(object); } } else { gMessageLib->sendCreateObject(object,playerObject); object->addKnownObjectSafe(playerObject); playerObject->addKnownObjectSafe(object); } ++it; } }
void WorldManager::warpPlanet(PlayerObject* playerObject, const glm::vec3& destination, uint64 parentId, const glm::quat& direction) { removePlayerMovementUpdateTime(playerObject); // remove player from objects in his range. playerObject->destroyKnownObjects(); // remove from cell / SI if(playerObject->getParentId()) { if(CellObject* cell = dynamic_cast<CellObject*>(getObjectById(playerObject->getParentId()))) { cell->removeObject(playerObject); } else { DLOG(INFO) << "WorldManager::removePlayer: couldn't find cell " << playerObject->getParentId(); } } else { if(playerObject->getSubZoneId()) { if(QTRegion* region = getQTRegion(playerObject->getSubZoneId())) { playerObject->setSubZoneId(0); region->mTree->removeObject(playerObject); } } } // remove any timers running //why remove that ? //removeObjControllerToProcess(playerObject->getController()->getTaskId()); //playerObject->getController()->clearQueues(); //playerObject->getController()->setTaskId(0); //why remove that ? removeCreatureHamToProcess(playerObject->getHam()->getTaskId()); removeCreatureStomachToProcess(playerObject->getStomach()->mDrinkTaskId); removeCreatureStomachToProcess(playerObject->getStomach()->mFoodTaskId); //we've removed the taskId, now lets reset the Id playerObject->getHam()->setTaskId(0); // reset player properties playerObject->resetProperties(); playerObject->setParentId(parentId); playerObject->mPosition = destination; playerObject->mDirection = direction; // start the new scene gMessageLib->sendStartScene(mZoneId,playerObject); gMessageLib->sendServerTime(gWorldManager->getServerTime(),playerObject->getClient()); // add us to cell / SI if(parentId) { if(CellObject* cell = dynamic_cast<CellObject*>(getObjectById(parentId))) { cell->addObjectSecure(playerObject); } else { DLOG(INFO) << "WorldManager::warpPlanet: couldn't find cell " << parentId; } } else { if(QTRegion* region = mSpatialIndex->getQTRegion(playerObject->mPosition.x,playerObject->mPosition.z)) { playerObject->setSubZoneId((uint32)region->getId()); region->mTree->addObject(playerObject); } else { // we should never get here ! return; } } // initialize objects in range initObjectsInRange(playerObject); // initialize at new position gMessageLib->sendCreatePlayer(playerObject,playerObject); // initialize ham regeneration playerObject->getHam()->checkForRegen(); playerObject->getStomach()->checkForRegen(); }
void WorldManager::createObjectinWorld(Object* object) { float viewingRange = _GetMessageHeapLoadViewingRange(); ObjectSet inRangeObjects; mSpatialIndex->getObjectsInRange(object,&inRangeObjects,(ObjType_Player),viewingRange); // query the according qtree, if we are in one if(object->getSubZoneId()) { if(QTRegion* region = getQTRegion(object->getSubZoneId())) { Anh_Math::Rectangle qRect; if(!object->getParentId()) { qRect = Anh_Math::Rectangle(object->mPosition.x - viewingRange,object->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2); } else { CellObject* cell = dynamic_cast<CellObject*>(getObjectById(object->getParentId())); if(BuildingObject* house = dynamic_cast<BuildingObject*>(getObjectById(cell->getParentId()))) { qRect = Anh_Math::Rectangle(house->mPosition.x - viewingRange,house->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2); } } region->mTree->getObjectsInRange(object,&inRangeObjects,ObjType_Player,&qRect); } } // iterate through the results ObjectSet::iterator it = inRangeObjects.begin(); while(it != inRangeObjects.end()) { PlayerObject* player = dynamic_cast<PlayerObject*> (*it); if(player) { // send create for the type of object if (object->getPrivateOwner()) //what is this about ?? does it concern instances ???? { if (object->isOwnedBy(player)) { gMessageLib->sendCreateObject(object,player); object->addKnownObjectSafe(player); player->addKnownObjectSafe(object); } } else { gMessageLib->sendCreateObject(object,player); object->addKnownObjectSafe(player); player->addKnownObjectSafe(object); } } ++it; } }
void WorldManager::addNpcConversation(uint64 interval, NPCObject* npc) { // Remove npc if already in list, we use the interval from last player that invoked conversation. NpcConversionTime* target = new NpcConversionTime; target->mNpc = npc; target->mTargetId = npc->getLastConversationTarget(); target->mGroupId = 0; if (PlayerObject* player = dynamic_cast<PlayerObject*>(getObjectById(npc->getLastConversationTarget()))) { target->mGroupId = player->GetCreature()->getGroupId(); } if (gWorldConfig->isInstance()) { // We are running in an instance. NpcConversionTimers::iterator it = mNpcConversionTimers.begin(); while (it != mNpcConversionTimers.end()) { // Only erase if it's same player/group that updates AND when running zone as an instance. // gLogger->log(LogManager::DEBUG,"Comp NPC %"PRIu64" and %"PRIu64"", ((*it).first), npc); if (((*it).first) == npc->getId()) { if (target->mGroupId) { // We belong to a group. if (target->mGroupId == ((*it).second)->mGroupId) { // gLogger->log(LogManager::DEBUG,"Delete (group) %"PRIu64"", ((*it).second)->mTargetId); delete ((*it).second); it = mNpcConversionTimers.erase(it); continue; } } else { if (target->mTargetId == ((*it).second)->mTargetId) { delete ((*it).second); it = mNpcConversionTimers.erase(it); continue; } else { // It may be a new instance using this object. // gLogger->log(LogManager::DEBUG,"Unknown target."); } } } ++it; } } else { // gLogger->log(LogManager::DEBUG,"Not instanced."); NpcConversionTimers::iterator it = mNpcConversionTimers.begin(); while (it != mNpcConversionTimers.end()) { if (((*it).first) == npc->getId()) { // gLogger->log(LogManager::DEBUG,"Delete %"PRIu64"", ((*it).second)->mTargetId); delete ((*it).second); mNpcConversionTimers.erase(it); break; } ++it; } } uint64 expireTime = Anh_Utils::Clock::getSingleton()->getLocalTime(); target->mInterval = expireTime + interval; mNpcConversionTimers.push_back(std::make_pair(npc->getId(), target)); }
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()); } }
void WorldManager::addDisconnectedPlayer(PlayerObject* playerObject) { uint32 timeOut = gWorldConfig->getConfiguration<uint32>("Zone_Player_Logout",300); // Halt the tutorial scripts, if running. playerObject->stopTutorial(); Datapad* datapad = playerObject->getDataPad(); if(playerObject->getMount() && datapad) { if(VehicleController* datapad_pet = dynamic_cast<VehicleController*>(datapad->getDataById(playerObject->getMount()->controller()))) { datapad_pet->Store(); } } // Delete private owned spawned objects, like npc's in the Tutorial. uint64 privateOwnedObjectId = ScriptSupport::Instance()->getObjectOwnedBy(playerObject->getId()); while (privateOwnedObjectId != 0) { // Delete the object ref from script support. ScriptSupport::Instance()->eraseObject(privateOwnedObjectId); // We did have a private npc. Let us delete him/her/that. if (Object* object = getObjectById(privateOwnedObjectId)) { // But first, remove npc from our defender list. playerObject->removeDefenderAndUpdateList(object->getId()); destroyObject(object); // gLogger->log(LogManager::DEBUG,"WorldManager::addDisconnectedPlayer Deleted object with id %"PRIu64"",privateOwnedObjectId); } privateOwnedObjectId = ScriptSupport::Instance()->getObjectOwnedBy(playerObject->getId()); } removeObjControllerToProcess(playerObject->getController()->getTaskId()); removeCreatureHamToProcess(playerObject->getHam()->getTaskId()); removeCreatureStomachToProcess(playerObject->getStomach()->mDrinkTaskId); removeCreatureStomachToProcess(playerObject->getStomach()->mFoodTaskId); removeEntertainerToProcess(playerObject->getEntertainerTaskId()); gCraftingSessionFactory->destroySession(playerObject->getCraftingSession()); playerObject->setCraftingSession(NULL); gStateManager.removeActionState(playerObject, CreatureState_Crafting); //despawn camps ??? - every reference is over id though playerObject->getController()->setTaskId(0); playerObject->getHam()->setTaskId(0); playerObject->setSurveyState(false); playerObject->setSamplingState(false); playerObject->togglePlayerFlagOn(PlayerFlag_LinkDead); playerObject->setConnectionState(PlayerConnState_LinkDead); playerObject->setDisconnectTime(timeOut); //add to the disconnect list addPlayerToDisconnectedList(playerObject); gMessageLib->sendUpdatePlayerFlags(playerObject); }