void TRoomDB::buildAreas() { QTime _time; _time.start(); QMapIterator<int, TRoom *> it( rooms ); while( it.hasNext() ) { it.next(); int id = it.key(); TRoom * pR = getRoom(id); if( !pR ) continue; TArea * pA = getArea(pR->getArea()); if( !pA ) { areas[pR->getArea()] = new TArea( mpMap, this ); } } // if the area has been created without any rooms add the area ID QMapIterator<int, QString> it2( areaNamesMap ); while( it2.hasNext() ) { it2.next(); int id = it2.key(); if( ! areas.contains( id ) ) { areas[id] = new TArea( mpMap, this ); } } qDebug()<<"BUILD AREAS run time:"<<_time.elapsed(); }
QList<int> TMap::detectRoomCollisions( int id ) { TRoom * pR = mpRoomDB->getRoom( id ); if( !pR ) { QList<int> l; return l; } int _areaId = pR->getAreaId(); int _x = pR->x; int _y = pR->y; int _z = pR->z; QList<int> collList; TArea * pA = mpRoomDB->getArea( _areaId ); if( !pA ) { QList<int> l; return l; } for( int i=0; i< pA->rooms.size(); i++ ) { pR = mpRoomDB->getRoom( pA->rooms[i] ); if( !pR ) continue; if( pR->x == _x && pR->y == _y && pR->z == _z ) { collList.push_back( pA->rooms[i] ); } } return collList; }
void TRoomDB::auditRooms() { QTime t; t.start(); // rooms konsolidieren QMapIterator<int, TRoom* > itRooms( rooms ); while( itRooms.hasNext() ) { itRooms.next(); TRoom * pR = itRooms.value(); pR->auditExits(); } qDebug()<<"audit map: runtime:"<<t.elapsed(); }
void TMap::setRoomArea( int id, int areaId ) { TRoom * pR = mpRoomDB->getRoom( id ); if( !pR ) { QString msg = QString("roomID=%1 does not exist, can't set area=%2 of nonexisting room").arg(id).arg(areaId); logError(msg); return; } pR->setAreaId( areaId ); mMapGraphNeedsUpdate = true; }
// Reconstruct the area exit data in a format that actually makes sense - only // needed until the TRoom & TArea classes can be restructured to store exits // using the exit direction as a key and the to room as a value instead of vice-versa const QMultiMap<int, QPair<QString, int>> TArea::getAreaExitRoomData() const { QMultiMap<int, QPair<QString, int>> results; QSet<int> roomsWithOtherAreaSpecialExits; QMapIterator<int, QPair<int, int>> itAreaExit = exits; // First parse the normal exits and also find the rooms where there is at // least one special area exit while (itAreaExit.hasNext()) { itAreaExit.next(); QPair<QString, int> exitData; exitData.second = itAreaExit.value().first; switch (itAreaExit.value().second) { case DIR_NORTH: exitData.first = QString("north"); break; case DIR_NORTHEAST: exitData.first = QString("northeast"); break; case DIR_NORTHWEST: exitData.first = QString("northwest"); break; case DIR_SOUTH: exitData.first = QString("south"); break; case DIR_WEST: exitData.first = QString("west"); break; case DIR_EAST: exitData.first = QString("east"); break; case DIR_SOUTHEAST: exitData.first = QString("southeast"); break; case DIR_SOUTHWEST: exitData.first = QString("southwest"); break; case DIR_UP: exitData.first = QString("up"); break; case DIR_DOWN: exitData.first = QString("down"); break; case DIR_IN: exitData.first = QString("in"); break; case DIR_OUT: exitData.first = QString("out"); break; case DIR_OTHER: roomsWithOtherAreaSpecialExits.insert(itAreaExit.key()); break; default: qWarning("TArea::getAreaExitRoomData() Warning: unrecognised exit code %i found for exit from room %i to room %i.", itAreaExit.value().second, itAreaExit.key(), itAreaExit.value().first); } if (!exitData.first.isEmpty()) { results.insert(itAreaExit.key(), exitData); } } // Now have to find the special area exits in the rooms where we know there // IS one QSetIterator<int> itRoomWithOtherAreaSpecialExit = roomsWithOtherAreaSpecialExits; while (itRoomWithOtherAreaSpecialExit.hasNext()) { int fromRoomId = itRoomWithOtherAreaSpecialExit.next(); TRoom* pFromRoom = mpRoomDB->getRoom(fromRoomId); if (pFromRoom) { QMapIterator<int, QString> itOtherExit = pFromRoom->getOtherMap(); while (itOtherExit.hasNext()) { itOtherExit.next(); QPair<QString, int> exitData; exitData.second = itOtherExit.key(); TRoom* pToRoom = mpRoomDB->getRoom(exitData.second); if (pToRoom && mpRoomDB->getArea(pToRoom->getArea()) != this) { // Note that pToRoom->getArea() is misnamed, should be getAreaId() ! if (itOtherExit.value().mid(0, 1) == QStringLiteral("0") || itOtherExit.value().mid(0, 1) == QStringLiteral("1")) { exitData.first = itOtherExit.value().mid(1); } else { exitData.first = itOtherExit.value(); } if (!exitData.first.isEmpty()) { results.insert(fromRoomId, exitData); } } } } } return results; }
void TArea::determineAreaExits() { exits.clear(); QSetIterator<int> itRoom(rooms); while (itRoom.hasNext()) { int id = itRoom.next(); TRoom* pR = mpRoomDB->getRoom(id); if (!pR) { continue; } int exitId = pR->getNorth(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_NORTH); exits.insertMulti(id, p); } exitId = pR->getNortheast(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_NORTHEAST); exits.insertMulti(id, p); } exitId = pR->getEast(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_EAST); exits.insertMulti(id, p); } exitId = pR->getSoutheast(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_SOUTHEAST); exits.insertMulti(id, p); } exitId = pR->getSouth(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_SOUTH); exits.insertMulti(id, p); } exitId = pR->getSouthwest(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_SOUTHWEST); exits.insertMulti(id, p); } exitId = pR->getWest(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_WEST); exits.insertMulti(id, p); } exitId = pR->getNorthwest(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_NORTHWEST); exits.insertMulti(id, p); } exitId = pR->getUp(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_UP); exits.insertMulti(id, p); } exitId = pR->getDown(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_DOWN); exits.insertMulti(id, p); } exitId = pR->getIn(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_IN); exits.insertMulti(id, p); } exitId = pR->getOut(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_OUT); exits.insertMulti(id, p); } const QMap<int, QString> otherMap = pR->getOtherMap(); QMapIterator<int, QString> it(otherMap); while (it.hasNext()) { it.next(); int _exit = it.key(); TRoom* pO = mpRoomDB->getRoom(_exit); if (pO) { if (pO->getArea() != getAreaID()) { QPair<int, int> p = QPair<int, int>(pO->getId(), DIR_OTHER); exits.insertMulti(id, p); } } } } }
void TArea::determineAreaExitsOfRoom(int id) { if (!mpRoomDB) { return; } TRoom* pR = mpRoomDB->getRoom(id); if (!pR) { return; } exits.remove(id); int exitId = pR->getNorth(); // The second term in the ifs below looks for exit room id in TArea // instance's own list of rooms which will fail (with a -1 if it is NOT in // the list and hence the area. if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_NORTH); exits.insertMulti(id, p); } exitId = pR->getNortheast(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_NORTHEAST); exits.insertMulti(id, p); } exitId = pR->getEast(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_EAST); exits.insertMulti(id, p); } exitId = pR->getSoutheast(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_SOUTHEAST); exits.insertMulti(id, p); } exitId = pR->getSouth(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_SOUTH); exits.insertMulti(id, p); } exitId = pR->getSouthwest(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_SOUTHWEST); exits.insertMulti(id, p); } exitId = pR->getWest(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_WEST); exits.insertMulti(id, p); } exitId = pR->getNorthwest(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_NORTHWEST); exits.insertMulti(id, p); } exitId = pR->getUp(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_UP); exits.insertMulti(id, p); } exitId = pR->getDown(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_DOWN); exits.insertMulti(id, p); } exitId = pR->getIn(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_IN); exits.insertMulti(id, p); } exitId = pR->getOut(); if (exitId > 0 && !rooms.contains(exitId)) { QPair<int, int> p = QPair<int, int>(exitId, DIR_OUT); exits.insertMulti(id, p); } const QMap<int, QString> otherMap = pR->getOtherMap(); QMapIterator<int, QString> it(otherMap); while (it.hasNext()) { it.next(); int _exit = it.key(); TRoom* pO = mpRoomDB->getRoom(_exit); if (pO) { if (pO->getArea() != getAreaID()) { QPair<int, int> p = QPair<int, int>(pO->getId(), DIR_OTHER); exits.insertMulti(id, p); } } } }
bool TMap::serialize( QDataStream & ofs ) { version = CURRENT_MAP_VERSION; ofs << version; ofs << envColors; ofs << mpRoomDB->getAreaNamesMap(); ofs << customEnvColors; ofs << mpRoomDB->hashTable; ofs << mpRoomDB->getAreaMap().size(); // serialize area table QMapIterator<int, TArea *> itAreaList(mpRoomDB->getAreaMap()); while( itAreaList.hasNext() ) { itAreaList.next(); int areaId = itAreaList.key(); TArea * pA = itAreaList.value(); ofs << areaId; ofs << pA->rooms; ofs << pA->ebenen; ofs << pA->exits; ofs << pA->gridMode; ofs << pA->max_x; ofs << pA->max_y; ofs << pA->max_z; ofs << pA->min_x; ofs << pA->min_y; ofs << pA->min_z; ofs << pA->span; ofs << pA->xmaxEbene; ofs << pA->ymaxEbene; ofs << pA->zmaxEbene; ofs << pA->xminEbene; ofs << pA->yminEbene; ofs << pA->zminEbene; ofs << pA->pos; ofs << pA->isZone; ofs << pA->zoneAreaRef; } if (mRoomId) ofs << mRoomId; else{ mRoomId = 0; ofs << mRoomId; } ofs << mapLabels.size(); //anzahl der areas QMapIterator<int, QMap<int, TMapLabel> > itL1(mapLabels); while( itL1.hasNext() ) { itL1.next(); int i = itL1.key(); ofs << itL1.value().size();//anzahl der labels pro area ofs << itL1.key(); //area id QMapIterator<int, TMapLabel> itL2(mapLabels[i]); while( itL2.hasNext() ) { itL2.next(); // N/U: int ii = itL2.key(); ofs << itL2.key();//label ID TMapLabel label = itL2.value(); ofs << label.pos; ofs << label.pointer; ofs << label.size; ofs << label.text; ofs << label.fgColor; ofs << label.bgColor; ofs << label.pix; ofs << label.noScaling; ofs << label.showOnTop; } } QMapIterator<int, TRoom *> it( mpRoomDB->getRoomMap() ); while( it.hasNext() ) { it.next(); // N/U: int i = it.key(); TRoom * pR = it.value(); ofs << pR->getId(); ofs << pR->getAreaId(); ofs << pR->x; ofs << pR->y; ofs << pR->z; ofs << pR->getNorth(); ofs << pR->getNortheast(); ofs << pR->getEast(); ofs << pR->getSoutheast(); ofs << pR->getSouth(); ofs << pR->getSouthwest(); ofs << pR->getWest(); ofs << pR->getNorthwest(); ofs << pR->getUp(); ofs << pR->getDown(); ofs << pR->getIn(); ofs << pR->getOut(); ofs << pR->environment; ofs << pR->getWeight(); // ofs << rooms[i]->xRot; // ofs << rooms[i]->yRot; // ofs << rooms[i]->zRot; // ofs << rooms[i]->zoom; ofs << pR->name; ofs << pR->isLocked; ofs << pR->getOtherMap(); ofs << pR->c; ofs << pR->userData; ofs << pR->customLines; ofs << pR->customLinesArrow; ofs << pR->customLinesColor; ofs << pR->customLinesStyle; ofs << pR->exitLocks; ofs << pR->exitStubs; ofs << pR->getExitWeights(); ofs << pR->doors; } return true; }
bool TMap::findPath( int from, int to ) { if( mMapGraphNeedsUpdate ) { initGraph(); } //vertex start = from;//mRoomId; //vertex goal = to;//mTargetID; TRoom * pFrom = mpRoomDB->getRoom( from ); TRoom * pTo = mpRoomDB->getRoom( to ); if( !pFrom || !pTo ) { return false; } vertex start = roomidToIndex[from]; vertex goal = roomidToIndex[to]; vector<mygraph_t::vertex_descriptor> p(num_vertices(g)); vector<cost> d(num_vertices(g)); QTime t; t.start(); try { astar_search( g, start, distance_heuristic<mygraph_t, cost, std::vector<location> >(locations, goal), predecessor_map(&p[0]).distance_map(&d[0]). visitor(astar_goal_visitor<vertex>(goal)) ); } catch( found_goal fg ) { qDebug("TMap::findPath(%i,%i) time elapsed in astar:%imSec", from, to, t.elapsed() ); t.restart(); list<vertex> shortest_path; for(vertex v = goal; ; v = p[v]) { //cout << "assembling path: v="<<v<<endl; qDebug("TMap::findPath(...) assembling path: v=%i", v); int nextRoom = indexToRoomid[v]; if( ! mpRoomDB->getRoom( nextRoom ) ) { qDebug("TMap::findPath(%i,%i) ERROR path assembly: path room not in map!", from, to); return false; } shortest_path.push_front(nextRoom); if(p[v] == v) break; } TRoom * pRD1 = mpRoomDB->getRoom(from); TRoom * pRD2 = mpRoomDB->getRoom(to); if( !pRD1 || !pRD2 ) return false; qDebug("Shortest path from %i to %i:", pRD1->getId(), pRD2->getId()); list<vertex>::iterator spi = shortest_path.begin(); qDebug() << pRD1->getId(); mPathList.clear(); mDirList.clear(); int curRoom = from; for( ++spi; spi != shortest_path.end(); ++spi ) { TRoom * pRcurRoom = mpRoomDB->getRoom( curRoom ); TRoom * pRPath = mpRoomDB->getRoom( *spi ); if( !pRcurRoom || !pRPath ) { // cout << "ERROR: path not possible. curRoom not in map!" << endl; qDebug("TMap::findPath(%i,%i) ERROR path not possible. curRoom not in map!", from, to); mPathList.clear(); mDirList.clear(); return false; } // cout <<" spi:"<<*spi<<" curRoom:"<< curRoom << endl;//" -> "; qDebug(" spi:%i curRoom:%i", *spi, curRoom); mPathList.push_back( *spi ); if( pRcurRoom->getNorth() == pRPath->getId() ) { mDirList.push_back("n"); } else if( pRcurRoom->getNortheast() == pRPath->getId() ) { mDirList.push_back("ne"); } else if( pRcurRoom->getNorthwest() == pRPath->getId() ) { mDirList.push_back("nw"); } else if( pRcurRoom->getSoutheast() == pRPath->getId() ) { mDirList.push_back("se"); } else if( pRcurRoom->getSouthwest() == pRPath->getId() ) { mDirList.push_back("sw"); } else if( pRcurRoom->getSouth() == pRPath->getId() ) { mDirList.push_back("s"); } else if( pRcurRoom->getEast() == pRPath->getId() ) { mDirList.push_back("e"); } else if( pRcurRoom->getWest() == pRPath->getId() ) { mDirList.push_back("w"); } else if( pRcurRoom->getUp() == pRPath->getId() ) { mDirList.push_back("up"); } else if( pRcurRoom->getDown() == pRPath->getId() ) { mDirList.push_back("down"); } else if( pRcurRoom->getIn() == pRPath->getId() ) { mDirList.push_back("in"); } else if( pRcurRoom->getOut() == pRPath->getId() ) { mDirList.push_back("out"); } else if( pRcurRoom->getOtherMap().size() > 0 ) { QMapIterator<int, QString> it( pRcurRoom->getOtherMap() ); while( it.hasNext() ) { it.next(); if( it.key() == pRPath->getId() ) { QString _cmd = it.value(); if( _cmd.size() > 0 ) { if(_cmd.startsWith('0')) { _cmd = _cmd.mid(1); mDirList.push_back( _cmd ); qDebug(" adding special exit: roomID:%i OPEN special exit:%s", pRcurRoom->getId(), qPrintable(_cmd) ); } else if( _cmd.startsWith('1')) { _cmd = _cmd.mid(1); qDebug(" NOT adding roomID:%i LOCKED special exit:%s", pRcurRoom->getId(), qPrintable(_cmd)); } else { qWarning("ERROR adding roomID:%i UNPATCHED special exit found:%s", pRcurRoom->getId(), qPrintable(_cmd)); } } else qWarning("ERROR adding roomID:%i NULL command special exit found.", pRcurRoom->getId()); } } } qDebug(" added to DirList:%s", qPrintable( mDirList.back() ) ); curRoom = *spi; } qDebug("TMap::findPath(%i,%i) time elapsed building path:%imSec", from, to, t.elapsed() ); return true; } return false; }
void TMap::initGraph() { QTime _time; _time.start(); locations.clear(); roomidToIndex.clear(); g.clear(); g = mygraph_t(); weightmap = get(edge_weight, g); QList<TRoom*> roomList = mpRoomDB->getRoomPtrList(); int roomCount=0; int edgeCount=0; for( int _k=0; _k<roomList.size(); _k++ ) { TRoom * pR = roomList[_k]; int i = pR->getId(); if( pR->isLocked || i < 1 ) { continue; } roomCount++; // int roomExits = edgeCount; location l; l.x = pR->x; l.y = pR->y; l.z = pR->z; l.id = pR->getId(); l.area = pR->getAreaId(); locations.push_back( l ); } for(unsigned int i=0;i<locations.size();i++){ roomidToIndex[locations[i].id] = i; indexToRoomid[i] = locations[i].id; } for( int _k=0; _k<roomList.size(); _k++ ){ TRoom * pR = roomList[_k]; if( pR->isLocked || !roomidToIndex.contains(pR->getId()) ) { continue; } int roomIndex = roomidToIndex[pR->getId()]; TRoom * pN = mpRoomDB->getRoom( pR->getNorth() ); TRoom * pNW = mpRoomDB->getRoom( pR->getNorthwest() ); TRoom * pNE = mpRoomDB->getRoom( pR->getNortheast() ); TRoom * pS = mpRoomDB->getRoom( pR->getSouth() ); TRoom * pSW = mpRoomDB->getRoom( pR->getSouthwest() ); TRoom * pSE = mpRoomDB->getRoom( pR->getSoutheast() ); TRoom * pW = mpRoomDB->getRoom( pR->getWest() ); TRoom * pE = mpRoomDB->getRoom( pR->getEast() ); TRoom * pUP = mpRoomDB->getRoom( pR->getUp() ); TRoom * pDOWN = mpRoomDB->getRoom( pR->getDown() ); TRoom * pIN = mpRoomDB->getRoom( pR->getIn() ); TRoom * pOUT = mpRoomDB->getRoom( pR->getOut() ); QMap<QString, int> exitWeights = pR->getExitWeights(); if( pN && !pN->isLocked ) { if( !pR->hasExitLock( DIR_NORTH ) ) { //edgeCount++; edge_descriptor e; bool inserted; tie(e, inserted) = add_edge( roomIndex, roomidToIndex[pR->getNorth()], g ); if( exitWeights.contains("n")) weightmap[e] = pR->getExitWeight("n"); else weightmap[e] = pN->getWeight(); } } if( pS && !pS->isLocked ) { if( !pR->hasExitLock( DIR_SOUTH ) ) { //edgeCount++; edge_descriptor e; bool inserted; tie(e, inserted) = add_edge( roomIndex, roomidToIndex[pR->getSouth()], g ); if( exitWeights.contains("s")) weightmap[e] = pR->getExitWeight("s"); else weightmap[e] = pS->getWeight(); } } if( pNE && !pNE->isLocked ) { if( !pR->hasExitLock( DIR_NORTHEAST ) ) { // edgeCount++; edge_descriptor e; bool inserted; tie(e, inserted) = add_edge( roomIndex, roomidToIndex[pR->getNortheast()], g ); if( exitWeights.contains("ne")) weightmap[e] = pR->getExitWeight("ne"); else weightmap[e] = pNE->getWeight(); } } if( pE && !pE->isLocked ) { if( !pR->hasExitLock( DIR_EAST ) ) { //edgeCount++; edge_descriptor e; bool inserted; tie(e, inserted) = add_edge( roomIndex, roomidToIndex[pR->getEast()], g ); if( exitWeights.contains("e")) weightmap[e] = pR->getExitWeight("e"); else weightmap[e] = pE->getWeight(); } } if( pW && !pW->isLocked ) { if( !pR->hasExitLock( DIR_WEST ) ) { // edgeCount++; edge_descriptor e; bool inserted; tie(e, inserted) = add_edge( roomIndex, roomidToIndex[pR->getWest()], g ); if( exitWeights.contains("w")) weightmap[e] = pR->getExitWeight("w"); else weightmap[e] = pW->getWeight(); } } if( pSW && !pSW->isLocked ) { if( !pR->hasExitLock( DIR_SOUTHWEST ) ) { // edgeCount++; edge_descriptor e; bool inserted; tie(e, inserted) = add_edge( roomIndex, roomidToIndex[pR->getSouthwest()], g ); if( exitWeights.contains("sw")) weightmap[e] = pR->getExitWeight("sw"); else weightmap[e] = pSW->getWeight(); } } if( pSE && !pSE->isLocked ) { if( !pR->hasExitLock( DIR_SOUTHEAST ) ) { // edgeCount++; edge_descriptor e; bool inserted; tie(e, inserted) = add_edge( roomIndex, roomidToIndex[pR->getSoutheast()], g ); if( exitWeights.contains("se")) weightmap[e] = pR->getExitWeight("se"); else weightmap[e] = pSE->getWeight(); } } if( pNW && !pNW->isLocked ) { if( !pR->hasExitLock( DIR_NORTHWEST ) ) { // edgeCount++; edge_descriptor e; bool inserted; tie(e, inserted) = add_edge( roomIndex, roomidToIndex[pR->getNorthwest()], g ); if( exitWeights.contains("nw")) weightmap[e] = pR->getExitWeight("nw"); else weightmap[e] = pNW->getWeight(); } } if( pUP && !pUP->isLocked ) { if( !pR->hasExitLock( DIR_UP ) ) { // edgeCount++; edge_descriptor e; bool inserted; tie(e, inserted) = add_edge( roomIndex, roomidToIndex[pR->getUp()], g ); if( exitWeights.contains("up")) weightmap[e] = pR->getExitWeight("up"); else weightmap[e] = pUP->getWeight(); } } if( pDOWN && !pDOWN->isLocked ) { if( !pR->hasExitLock( DIR_DOWN ) ) { // edgeCount++; edge_descriptor e; bool inserted; tie(e, inserted) = add_edge( roomIndex, roomidToIndex[pR->getDown()], g ); if( exitWeights.contains("down")) weightmap[e] = pR->getExitWeight("down"); else weightmap[e] = pDOWN->getWeight(); } } if( pIN && !pIN->isLocked ) { if( !pR->hasExitLock( DIR_IN ) ) { // edgeCount++; edge_descriptor e; bool inserted; tie(e, inserted) = add_edge( roomIndex, roomidToIndex[pR->getIn()], g ); if( exitWeights.contains("in")) weightmap[e] = pR->getExitWeight("in"); else weightmap[e] = pIN->getWeight(); } } if( pOUT && !pOUT->isLocked ) { if( !pR->hasExitLock( DIR_OUT ) ) { // edgeCount++; edge_descriptor e; bool inserted; tie(e, inserted) = add_edge( roomIndex, roomidToIndex[pR->getOut()], g ); if( exitWeights.contains("out")) weightmap[e] = pR->getExitWeight("out"); else weightmap[e] = pOUT->getWeight(); } } if( pR->getOtherMap().size() > 0 ) { QMapIterator<int, QString> it( pR->getOtherMap() ); while( it.hasNext() ) { it.next(); int _id = it.key(); QString _cmd = it.value(); if( _cmd.size()>0 ) _cmd.remove(0,1);//strip special exit lock information TRoom * pSpecial = mpRoomDB->getRoom( _id ); if( !pSpecial || pR->hasSpecialExitLock( _id, _cmd ) || pSpecial->isLocked) continue; else { // edgeCount++; edge_descriptor e; bool inserted; tie(e, inserted) = add_edge( roomIndex, roomidToIndex[pSpecial->getId()], g ); if( exitWeights.contains(_cmd)) { weightmap[e] = pR->getExitWeight(_cmd); } else { weightmap[e] = pSpecial->getWeight(); } } } } // if( roomExits == edgeCount ) locations.pop_back(); } mMapGraphNeedsUpdate = false; qDebug("TMap::initGraph(): nodes/room Counts: %i / %i edges: %i run time: %imSec.", locations.size(), roomCount, edgeCount, _time.elapsed()); }
bool TMap::setExit( int from, int to, int dir ) { TRoom * pR = mpRoomDB->getRoom( from ); TRoom * pR_to = mpRoomDB->getRoom( to ); if( !pR ) return false; if( !pR_to && to > 0 ) return false; if( to < 1 ) to = -1; mPlausaOptOut = 0; bool ret = true; switch( dir ) { case DIR_NORTH: pR->setNorth(to); break; case DIR_NORTHEAST: pR->setNortheast(to); break; case DIR_NORTHWEST: pR->setNorthwest(to); break; case DIR_EAST: pR->setEast(to); break; case DIR_WEST: pR->setWest(to); break; case DIR_SOUTH: pR->setSouth(to); break; case DIR_SOUTHEAST: pR->setSoutheast(to); break; case DIR_SOUTHWEST: pR->setSouthwest(to); break; case DIR_UP: pR->setUp(to); break; case DIR_DOWN: pR->setDown(to); break; case DIR_IN: pR->setIn(to); break; case DIR_OUT: pR->setOut(to); break; default: ret = false; } pR->setExitStub(dir, 0); mMapGraphNeedsUpdate = true; TArea * pA = mpRoomDB->getArea( pR->getAreaId() ); pA->fast_ausgaengeBestimmen(pR->getId()); return ret; }
void TMap::connectExitStub(int roomId, int dirType) { TRoom * pR = mpRoomDB->getRoom( roomId ); if( !pR ) return; int areaId = pR->getAreaId(); int minDistance = 999999; int minDistanceRoom=0, meanSquareDistance=0; if( !unitVectors.contains( dirType ) ) return; QVector3D unitVector = unitVectors[dirType]; int ux = unitVector.x(), uy = unitVector.y(), uz = unitVector.z(); int rx = pR->x, ry = pR->y, rz = pR->z; int dx=0,dy=0,dz=0; TArea * pA = mpRoomDB->getArea(areaId); if( !pA ) return; for( int i=0; i< pA->rooms.size(); i++ ) { pR = mpRoomDB->getRoom( pA->rooms[i] ); if( !pR ) continue; if( pR->getId() == roomId ) continue; if(uz) { dz = (int)pR->z-rz; if(!compSign(dz,uz) || !dz) continue; } else { //to avoid lower/upper floors from stealing stubs if((int)pR->z != rz) continue; } if(ux) { dx = (int)pR->x-rx; if (!compSign(dx,ux) || !dx) //we do !dx to make sure we have a component in the desired direction continue; } else { //to avoid rooms on same plane from stealing stubs if((int)pR->x != rx) continue; } if(uy) { dy = (int)pR->y-ry; //if the sign is the SAME here we keep it b/c we flip our y coordinate. if (compSign(dy,uy) || !dy) continue; } else { //to avoid rooms on same plane from stealing stubs if((int)pR->y != ry) continue; } meanSquareDistance=dx*dx+dy*dy+dz*dz; if(meanSquareDistance < minDistance) { minDistanceRoom=pR->getId(); minDistance=meanSquareDistance; } } if(minDistanceRoom) { pR = mpRoomDB->getRoom(minDistanceRoom); if( !pR ) return; if(pR->exitStubs.contains(reverseDirections[dirType])) { setExit( roomId, minDistanceRoom, dirType); setExit( minDistanceRoom, roomId, reverseDirections[dirType]); } } }
// this is call by TRoom destructor only bool TRoomDB::__removeRoom( int id ) { if( rooms.contains(id ) && id > 0 ) { TRoom * pR = getRoom( id ); if( !pR ) return false; QMapIterator<int, TRoom *> it( rooms ); while( it.hasNext() ) { it.next(); TRoom * r = it.value(); if( r->getNorth() == id ) r->setNorth(-1); if( r->getNortheast() == id ) r->setNortheast(-1); if( r->getNorthwest() == id ) r->setNorthwest(-1); if( r->getEast() == id ) r->setEast(-1); if( r->getWest() == id ) r->setWest(-1); if( r->getSouth() == id ) r->setSouth(-1); if( r->getSoutheast() == id ) r->setSoutheast(-1); if( r->getSouthwest() == id ) r->setSouthwest(-1); if( r->getUp() == id ) r->setUp(-1); if( r->getDown() == id ) r->setDown(-1); if( r->getIn() == id ) r->setIn(-1); if( r->getOut() == id ) r->setOut(-1); r->removeAllSpecialExitsToRoom( id ); } int areaID = pR->getArea(); TArea * pA = getArea( areaID ); if( !pA ) return false; pA->rooms.removeAll( id ); pA->exits.remove( id ); //note: this removes *all* keys=id mpMap->mMapGraphNeedsUpdate = true; } QList<QString> keyList = hashTable.keys(); QList<int> valueList = hashTable.values(); for( int i=0; i<valueList.size(); i++ ) { if( valueList[i] == id ) { hashTable.remove( keyList[i] ); } } return true; }
void dlgRoomExits::save() { mpHost->mpMap->mMapGraphNeedsUpdate = true; TRoom * pR = mpHost->mpMap->mpRoomDB->getRoom(mRoomID); if( !pR ) return; pR->clearSpecialExits(); for( int i=0; i<specialExits->topLevelItemCount(); i++ ) { QTreeWidgetItem * pI = specialExits->topLevelItem(i); int key = pI->text(1).toInt(); QString value = pI->text(2); //qDebug()<<"key="<<key<<" value=<"<<value<<">"; if( value != "<command or Lua script>" && key != 0 ) { if( pI->checkState( 0 ) == Qt::Unchecked ) value = value.prepend( '0' ); else value = value.prepend( '1' ); //qDebug()<<"setting: key="<<key<<" val="<<value; pR->addSpecialExit( key, value ); } } int id = pR->getId(); mpHost->mpMap->setExit(id, n->text().toInt(), DIR_NORTH ); mpHost->mpMap->setExit(id, nw->text().toInt(), DIR_NORTHWEST ); mpHost->mpMap->setExit(id, ne->text().toInt(), DIR_NORTHEAST ); mpHost->mpMap->setExit(id, s->text().toInt(), DIR_SOUTH ); mpHost->mpMap->setExit(id, sw->text().toInt(), DIR_SOUTHWEST ); mpHost->mpMap->setExit(id, se->text().toInt(), DIR_SOUTHEAST ); mpHost->mpMap->setExit(id, e->text().toInt(), DIR_EAST ); mpHost->mpMap->setExit(id, w->text().toInt(), DIR_WEST ); mpHost->mpMap->setExit(id, up->text().toInt(), DIR_UP ); mpHost->mpMap->setExit(id, down->text().toInt(), DIR_DOWN ); mpHost->mpMap->setExit(id, in->text().toInt(), DIR_IN ); mpHost->mpMap->setExit(id, out->text().toInt(), DIR_OUT ); if( !n->isEnabled() ) pR->setExitLock(DIR_NORTH, true); else pR->setExitLock(DIR_NORTH, false); if( !ne->isEnabled() ) pR->setExitLock(DIR_NORTHEAST, true); else pR->setExitLock(DIR_NORTHEAST, false); if( !nw->isEnabled() ) pR->setExitLock(DIR_NORTHWEST, true); else pR->setExitLock(DIR_NORTHWEST, false); if( !w->isEnabled() ) pR->setExitLock(DIR_WEST, true); else pR->setExitLock(DIR_WEST, false); if( !e->isEnabled() ) pR->setExitLock(DIR_EAST, true); else pR->setExitLock(DIR_EAST, false); if( !s->isEnabled() ) pR->setExitLock(DIR_SOUTH, true); else pR->setExitLock(DIR_SOUTH, false); if( !se->isEnabled() ) pR->setExitLock(DIR_SOUTHEAST, true); else pR->setExitLock(DIR_SOUTHEAST, false); if( !sw->isEnabled() ) pR->setExitLock(DIR_SOUTHWEST, true); else pR->setExitLock(DIR_SOUTHWEST, false); if( !up->isEnabled() ) pR->setExitLock(DIR_UP, true); else pR->setExitLock(DIR_UP, false); if( !down->isEnabled() ) pR->setExitLock(DIR_DOWN, true); else pR->setExitLock(DIR_DOWN, false); if( !in->isEnabled() ) pR->setExitLock(DIR_IN, true); else pR->setExitLock(DIR_IN, false); if( !out->isEnabled() ) pR->setExitLock(DIR_OUT, true); else pR->setExitLock(DIR_OUT, false); mpHost->mpMap->mMapGraphNeedsUpdate = true; close(); }
void dlgRoomExits::init( int id ) { TRoom * pR = mpHost->mpMap->mpRoomDB->getRoom( id ); if( !pR ) return; if( pR->hasExitLock(DIR_NORTH) ) { n->setDisabled(true); ln->setChecked(true); } else { n->setDisabled(false); ln->setChecked(false); } if( pR->hasExitLock(DIR_NORTHEAST) ) { ne->setDisabled(true); lne->setChecked(true); } else { ne->setDisabled(false); le->setChecked(false); } if( pR->hasExitLock(DIR_NORTHWEST) ) { nw->setDisabled(true); lnw->setChecked(true); } else { nw->setDisabled(false); lnw->setChecked(false); } if( pR->hasExitLock(DIR_SOUTH) ) { s->setDisabled(true); ls->setChecked(true); } else { s->setDisabled(false); ls->setChecked(false); } if( pR->hasExitLock(DIR_SOUTHEAST) ) { se->setDisabled(true); lse->setChecked(true); } else { se->setDisabled(false); lse->setChecked(false); } if( pR->hasExitLock(DIR_SOUTHWEST) ) { sw->setDisabled(true); lsw->setChecked(true); } else { sw->setDisabled(false); lsw->setChecked(false); } if( pR->hasExitLock(DIR_WEST) ) { w->setDisabled(true); lw->setChecked(true); } else { w->setDisabled(false); lw->setChecked(false); } if( pR->hasExitLock(DIR_EAST) ) { e->setDisabled(true); le->setChecked(true); } else { e->setDisabled(false); le->setChecked(false); } if( pR->hasExitLock(DIR_UP) ) { up->setDisabled(true); lup->setChecked(true); } else { up->setDisabled(false); lup->setChecked(false); } if( pR->hasExitLock(DIR_DOWN) ) { down->setDisabled(true); ldown->setChecked(true); } else { down->setDisabled(false); ldown->setChecked(false); } if( pR->hasExitLock(DIR_IN) ) { in->setDisabled(true); lin->setChecked(true); } else { in->setDisabled(false); lin->setChecked(false); } if( pR->hasExitLock(DIR_OUT) ) { out->setDisabled(true); lout->setChecked(true); } else { out->setDisabled(false); lout->setChecked(false); } if( pR->getNorth() > 0 ) n->setText(QString::number(pR->getNorth())); if( pR->getSouth() > 0 ) s->setText(QString::number(pR->getSouth())); if( pR->getWest() > 0 ) w->setText(QString::number(pR->getWest())); if( pR->getEast() > 0 ) e->setText(QString::number(pR->getEast())); if( pR->getNorthwest() > 0 ) nw->setText(QString::number(pR->getNorthwest())); if( pR->getNortheast() > 0 ) ne->setText(QString::number(pR->getNortheast())); if( pR->getSouthwest() > 0 ) sw->setText(QString::number(pR->getSouthwest())); if( pR->getSoutheast() > 0 ) se->setText(QString::number(pR->getSoutheast())); if( pR->getUp() > 0 ) up->setText(QString::number(pR->getUp())); if( pR->getDown() > 0 ) down->setText(QString::number(pR->getDown())); if( pR->getIn() > 0 ) in->setText(QString::number(pR->getIn())); if( pR->getOut() > 0 ) out->setText(QString::number(pR->getOut())); QMapIterator<int, QString> it(pR->getOtherMap()); while( it.hasNext() ) { it.next(); int id_to = it.key(); QString dir = it.value(); if( dir.size() < 1 ) continue; QTreeWidgetItem * pI = new QTreeWidgetItem(specialExits); if( pR->hasSpecialExitLock( id_to, dir ) ) pI->setCheckState( 0, Qt::Checked ); else pI->setCheckState( 0, Qt::Unchecked ); pI->setText( 1, QString::number(id_to) ); qDebug()<<"dir="<<dir; if( dir.startsWith('0') || dir.startsWith('1') ) dir = dir.mid(1); pI->setText( 2, dir ); } mRoomID = id; }