mirror of
https://github.com/Mudlet/Mudlet
synced 2026-08-13 18:26:27 -04:00
Enhance: store current player location in map file on a per profile basis
It is possible to copy a saved map from one profile to another - even if that other profile is in use. However this will lose the details of where the (other) player is located in THAT profile. This commit aims to correct that by sneaking a look at where the other player is and storing that in the file that is both copied for this profile before it is copied and to the file that is copied over. This data was stored in (int) TMap::mRoomId which has now become a: (QHash<QString, int>) TMap::mRoomIdHash with the profile name as the key and the Value being the equivalent of mRoomId in the new code. This has required an increment in the Map file format version from 17 to 18. The default - that will be used unless the developer or tester changes it in the Profile Preferences dialog remains at 16. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
This commit is contained in:
parent
275a712fa9
commit
94dd41bfb7
10 changed files with 448 additions and 85 deletions
|
|
@ -467,7 +467,7 @@ void T2DMap::paintEvent( QPaintEvent * e )
|
|||
int px,py;
|
||||
QList<int> exitList;
|
||||
QList<int> oneWayExits;
|
||||
TRoom * pPlayerRoom = mpMap->mpRoomDB->getRoom( mpMap->mRoomId );
|
||||
TRoom * pPlayerRoom = mpMap->mpRoomDB->getRoom( mpMap->mRoomIdHash.value( mpHost->getName() ) );
|
||||
if( !pPlayerRoom )
|
||||
{
|
||||
p.drawText(_w/2,_h/2,"No map or no valid position.");
|
||||
|
|
@ -476,7 +476,7 @@ void T2DMap::paintEvent( QPaintEvent * e )
|
|||
}
|
||||
|
||||
int ox, oy; // N/U: oz;
|
||||
if( mRID != mpMap->mRoomId && mShiftMode ) mShiftMode = false;
|
||||
if( mRID != mpMap->mRoomIdHash.value( mpHost->getName() ) && mShiftMode )
|
||||
{
|
||||
mShiftMode = false;
|
||||
}
|
||||
|
|
@ -492,7 +492,7 @@ void T2DMap::paintEvent( QPaintEvent * e )
|
|||
{
|
||||
return;
|
||||
}
|
||||
mRID = mpMap->mRoomId;
|
||||
mRID = mpMap->mRoomIdHash.value( mpHost->getName() );
|
||||
pRID = mpMap->mpRoomDB->getRoom( mRID );
|
||||
mAID = pRID->getArea();
|
||||
pAID = mpMap->mpRoomDB->getArea( mAID );
|
||||
|
|
@ -1423,9 +1423,9 @@ void T2DMap::paintEvent( QPaintEvent * e )
|
|||
if( mpMap->mpRoomDB->getRoom(mTarget) )
|
||||
{
|
||||
mpMap->mTargetID = mTarget;
|
||||
if( mpMap->findPath( mpMap->mRoomId, mpMap->mTargetID) )
|
||||
if( mpMap->findPath( mpMap->mRoomIdHash.value( mpHost->getName() ), mpMap->mTargetID) )
|
||||
{
|
||||
mpMap->mpHost->startSpeedWalk();
|
||||
mpHost->startSpeedWalk();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1504,7 +1504,7 @@ void T2DMap::paintEvent( QPaintEvent * e )
|
|||
p.setPen(__pen);
|
||||
}
|
||||
|
||||
if( mShiftMode && currentAreaRoom == mpMap->mRoomId )
|
||||
if( mShiftMode && currentAreaRoom == mpMap->mRoomIdHash.value( mpHost->getName() ) )
|
||||
{
|
||||
float _radius = (1.2*tx)/2;
|
||||
QPointF _center = QPointF(rx,ry);
|
||||
|
|
@ -1654,9 +1654,9 @@ void T2DMap::paintEvent( QPaintEvent * e )
|
|||
if( mpMap->mpRoomDB->getRoom(mTarget) )
|
||||
{
|
||||
mpMap->mTargetID = mTarget;
|
||||
if( mpMap->findPath( mpMap->mRoomId, mpMap->mTargetID) )
|
||||
if( mpMap->findPath( mpMap->mRoomIdHash.value( mpHost->getName() ), mpMap->mTargetID) )
|
||||
{
|
||||
mpMap->mpHost->startSpeedWalk();
|
||||
mpHost->startSpeedWalk();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1702,7 +1702,7 @@ void T2DMap::paintEvent( QPaintEvent * e )
|
|||
if( mpMap->mpRoomDB->getRoom(mTarget) )
|
||||
{
|
||||
mpMap->mTargetID = mTarget;
|
||||
if( mpMap->findPath( mpMap->mRoomId, mpMap->mTargetID) )
|
||||
if( mpMap->findPath( mpMap->mRoomIdHash.value( mpHost->getName() ), mpMap->mTargetID) )
|
||||
{
|
||||
mpMap->mpHost->startSpeedWalk();
|
||||
}
|
||||
|
|
@ -3023,7 +3023,7 @@ void T2DMap::slot_setPlayerLocation()
|
|||
int _newRoomId = *( mMultiSelectionSet.constBegin() );
|
||||
if( mpMap->mpRoomDB->getRoom( _newRoomId ) ) {
|
||||
// No need to check it is a DIFFERENT room - that is taken care of by en/dis-abling the control
|
||||
mpMap->mRoomId = _newRoomId;
|
||||
mpMap->mRoomIdHash[ mpHost->getName() ] = _newRoomId;
|
||||
mpMap->mNewMove = true;
|
||||
TEvent manualSetEvent;
|
||||
manualSetEvent.mArgumentList.append( QStringLiteral( "sysManualLocationSetEvent" ) );
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ class TArea
|
|||
|
||||
friend bool TMap::serialize( QDataStream & );
|
||||
friend bool TMap::restore( QString );
|
||||
friend const bool TMap::retrieveMapFileStats( QString , QString *, int *, int *, int *, int * );
|
||||
|
||||
public:
|
||||
TArea(TMap*, TRoomDB*);
|
||||
|
|
|
|||
|
|
@ -1129,7 +1129,7 @@ int TLuaInterpreter::centerview( lua_State * L )
|
|||
Host * pHost = TLuaInterpreter::luaInterpreterMap[L];
|
||||
if( pHost->mpMap && pHost->mpMap->mpRoomDB->getRoom( roomid ) )
|
||||
{
|
||||
pHost->mpMap->mRoomId = roomid;
|
||||
pHost->mpMap->mRoomIdHash[ pHost->getName() ] = roomid;
|
||||
pHost->mpMap->mNewMove = true;
|
||||
if( pHost->mpMap->mpM )
|
||||
{
|
||||
|
|
@ -4448,7 +4448,7 @@ int TLuaInterpreter::getRoomWeight( lua_State *L )
|
|||
}
|
||||
else
|
||||
{
|
||||
roomId = pHost->mpMap->mRoomId;
|
||||
roomId = pHost->mpMap->mRoomIdHash.value( pHost->getName() );
|
||||
}
|
||||
|
||||
TRoom * pR = pHost->mpMap->mpRoomDB->getRoom( roomId );
|
||||
|
|
|
|||
294
src/TMap.cpp
294
src/TMap.cpp
|
|
@ -52,15 +52,19 @@ TMap::TMap( Host * pH )
|
|||
// THIS, mMinVersion AND mMaxVersion SHOULD BE
|
||||
// REVISED WHEN WE SWITCH FROM A PREVIEW TO A RELEASE VERSION!
|
||||
// Currently:
|
||||
// TLuaInterpreter::setAreaUserData()
|
||||
// TLuaInterpreter::setMapUserData() need 17
|
||||
// + TLuaInterpreter::setAreaUserData()
|
||||
// + TLuaInterpreter::setMapUserData() need 17
|
||||
// (for persistant storage of data)
|
||||
// + TArea::rooms as QSet<int> needs 18,
|
||||
// is/was QList<int> in prior versions
|
||||
// + TMap::mRoomIdHash as QHash<QString, int> needs 18, is/was
|
||||
// a single mRoomId in prior versions
|
||||
, mSaveVersion( mDefaultVersion ) // This needs to be set (for when writing new
|
||||
// map files) as it triggers some version features
|
||||
// that NEED a new map file format to be usable, it
|
||||
// can be changed by control in last tab of profile
|
||||
// preference dialog.
|
||||
, mMaxVersion( 17 ) // CHECKME: Allow 17 ( mDefaultVersion + 1 ) for testing
|
||||
, mMaxVersion( 18 ) // CHECKME: Allow 18 ( mDefaultVersion + 2 ) for testing
|
||||
, mMinVersion( mDefaultVersion ) // CHECKME: Allow 16 ( mDefaultVersion )
|
||||
{
|
||||
mVersion = mDefaultVersion; // This is overwritten during a map restore and
|
||||
|
|
@ -115,7 +119,7 @@ TMap::~TMap() {
|
|||
void TMap::mapClear()
|
||||
{
|
||||
mpRoomDB->clearMapDB();
|
||||
mRoomId = 0;
|
||||
mRoomIdHash.clear();
|
||||
pixNameTable.clear();
|
||||
pixTable.clear();
|
||||
envColors.clear();
|
||||
|
|
@ -536,7 +540,7 @@ void TMap::getConnectedNodesSmallerThanY( int id, int min )
|
|||
bool TMap::gotoRoom( int r )
|
||||
{
|
||||
mTargetID = r;
|
||||
return findPath( mRoomId, r );
|
||||
return findPath( mRoomIdHash.value( mpHost->getName() ), r );
|
||||
}
|
||||
|
||||
// As can be seen this only sets the target and start point for a path find
|
||||
|
|
@ -1037,7 +1041,14 @@ bool TMap::serialize( QDataStream & ofs )
|
|||
int areaID = itAreaList.key();
|
||||
TArea * pA = itAreaList.value();
|
||||
ofs << areaID;
|
||||
ofs << pA->rooms;
|
||||
if( mSaveVersion >= 18 ) {
|
||||
ofs << pA->rooms;
|
||||
}
|
||||
else {
|
||||
// Switched to a (faster) QSet<int> from a QList<int> in version 18
|
||||
QList<int> _oldList = pA->rooms.toList();
|
||||
ofs << _oldList;
|
||||
}
|
||||
ofs << pA->ebenen;
|
||||
ofs << pA->exits;
|
||||
ofs << pA->gridMode;
|
||||
|
|
@ -1101,7 +1112,15 @@ bool TMap::serialize( QDataStream & ofs )
|
|||
}
|
||||
// End of TODO
|
||||
|
||||
ofs << mRoomId;
|
||||
if( mSaveVersion >= 18 ) {
|
||||
// Revised in version 18 to store mRoomId as a per profile case so that
|
||||
// sharing/copying between profiles respects each profile's player
|
||||
// location
|
||||
ofs << mRoomIdHash;
|
||||
}
|
||||
else {
|
||||
ofs << mRoomIdHash.value( mpHost->getName() );
|
||||
}
|
||||
|
||||
ofs << mapLabels.size(); //anzahl der areas
|
||||
QMapIterator<int, QMap<int, TMapLabel> > itL1(mapLabels);
|
||||
|
|
@ -1275,6 +1294,10 @@ bool TMap::restore(QString location)
|
|||
"beware that this file may not be usable by the current release version\n"
|
||||
"of Mudlet that you or others with whom you might share it have!" );
|
||||
mpHost->postMessage( infoMsg );
|
||||
mSaveVersion = mVersion; // Make the save version default to the loaded one
|
||||
// this means that each session using a particular
|
||||
// map file version will continue to use it unless
|
||||
// the user intervenes.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1289,12 +1312,15 @@ bool TMap::restore(QString location)
|
|||
"be better off starting again..." );
|
||||
mpHost->postMessage( infoMsg );
|
||||
canRestore = false;
|
||||
mSaveVersion = mVersion; // Make the save version the default one - unless the user intervenes
|
||||
}
|
||||
else {
|
||||
// Less than (but not less than 4) or equal to default version
|
||||
QString infoMsg = tr( "[ INFO ] - Reading map file: \"%1\", format version:%2, please wait..." )
|
||||
.arg( file.fileName() )
|
||||
.arg( mVersion );
|
||||
mpHost->postMessage( infoMsg );
|
||||
mSaveVersion = mVersion; // Make the save version the default one - unless the user intervenes
|
||||
}
|
||||
|
||||
// As all but the room reading have version checks the fact that sub-4
|
||||
|
|
@ -1320,7 +1346,16 @@ bool TMap::restore(QString location)
|
|||
TArea * pA = new TArea( this, mpRoomDB );
|
||||
int areaID;
|
||||
ifs >> areaID;
|
||||
ifs >> pA->rooms;
|
||||
if( mVersion >= 18 ) {
|
||||
// In version 18 changed from QList<int> to QSet<int> as the later is
|
||||
// faster in many of the cases where we use it.
|
||||
ifs >> pA->rooms;
|
||||
}
|
||||
else {
|
||||
QList<int> oldRoomsList;
|
||||
ifs >> oldRoomsList;
|
||||
pA->rooms = oldRoomsList.toSet();
|
||||
}
|
||||
// Can be useful when analysing suspect map files!
|
||||
// qDebug() << "TMap::restore(...)" << "Area:" << areaID;
|
||||
// qDebug() << "Rooms:" << pA->rooms;
|
||||
|
|
@ -1359,8 +1394,16 @@ bool TMap::restore(QString location)
|
|||
}
|
||||
}
|
||||
|
||||
if( mVersion >= 12 ) {
|
||||
ifs >> mRoomId;
|
||||
if( mVersion >= 18 ) {
|
||||
// In version 18 we changed to store the "userRoom" for each profile
|
||||
// so that when copied/shared between profiles they do not interfere
|
||||
// with each other's saved value
|
||||
ifs >> mRoomIdHash;
|
||||
}
|
||||
else if( mVersion >= 12 ) {
|
||||
int oldRoomId;
|
||||
ifs >> oldRoomId;
|
||||
mRoomIdHash[ mpHost->getName() ] = oldRoomId;
|
||||
}
|
||||
|
||||
if( mVersion >= 11 ) {
|
||||
|
|
@ -1466,6 +1509,237 @@ bool TMap::restore(QString location)
|
|||
return canRestore;//FIXME
|
||||
}
|
||||
|
||||
// Reads the newest map file from the profile and retrieves some stats and data,
|
||||
// including the current player room - was mRoomId in 12 to pre-18 map files and
|
||||
// is in mRoomIdHash since then so that it can be reinserted into a map that is
|
||||
// copied across (if the room STILL exists! This is to avoid a replacement map
|
||||
// (copied/shared) from one profile to another from repositioning the other
|
||||
// player location. Though this is written as a member function it is intended
|
||||
// also for use to retrieve details from maps from OTHER profiles, importantly
|
||||
// it does (or should) NOT interact with this TMap instance...!
|
||||
const bool TMap::retrieveMapFileStats( QString profile, QString * latestFileName = 0, int * fileVersion = 0, int * roomId = 0, int * areaCount = 0, int * roomCount = 0 )
|
||||
{
|
||||
if( profile.isEmpty() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString folder;
|
||||
QStringList entries;
|
||||
folder = QStringLiteral( "%1/.config/mudlet/profiles/%2/map/" )
|
||||
.arg( QDir::homePath() )
|
||||
.arg( profile );
|
||||
QDir dir( folder );
|
||||
dir.setSorting( QDir::Time );
|
||||
entries = dir.entryList( QDir::Files|QDir::NoDotAndDotDot, QDir::Time );
|
||||
|
||||
// As the files are sorted by time this gets the latest one
|
||||
QFile file( QStringLiteral( "%1%2" ).arg( folder ).arg( entries.at( 0 ) ) );
|
||||
|
||||
if( ! file.open( QFile::ReadOnly ) ) {
|
||||
QString errMsg = tr( "[ ERROR ] - Unable to open (for reading) map file: \"%1\"!" )
|
||||
.arg( file.fileName() );
|
||||
mpHost->postMessage( errMsg );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( latestFileName ) {
|
||||
*latestFileName = file.fileName();
|
||||
}
|
||||
int otherProfileVersion = 0;
|
||||
QDataStream ifs( & file );
|
||||
ifs >> otherProfileVersion;
|
||||
|
||||
QString infoMsg = tr( "[ INFO ] - Checking map file: \"%1\", format version:%2, please wait..." )
|
||||
.arg( file.fileName() )
|
||||
.arg( otherProfileVersion );
|
||||
mpHost->postMessage( infoMsg );
|
||||
|
||||
if( otherProfileVersion > mDefaultVersion ) {
|
||||
if( QByteArray( APP_BUILD ).isEmpty() ) {
|
||||
// This is a release version - should not support any map file versions higher that it was built for
|
||||
if( fileVersion ) {
|
||||
* fileVersion = otherProfileVersion;
|
||||
}
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// Is a development version so check against mMaxVersion
|
||||
if( otherProfileVersion > mMaxVersion ) {
|
||||
// Oh dear, can't handle THIS
|
||||
if( fileVersion ) {
|
||||
* fileVersion = otherProfileVersion;
|
||||
}
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if( fileVersion ) {
|
||||
* fileVersion = otherProfileVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if( fileVersion ) {
|
||||
* fileVersion = otherProfileVersion;
|
||||
}
|
||||
}
|
||||
|
||||
if( otherProfileVersion >= 4 ) {
|
||||
// envColorMap
|
||||
QMap<int, int> _dummyQMapIntInt;
|
||||
ifs >> _dummyQMapIntInt;
|
||||
|
||||
// AreaNamesMap
|
||||
QMap<int, QString> _dummyQMapIntQString;
|
||||
ifs >> _dummyQMapIntQString;
|
||||
}
|
||||
|
||||
if( otherProfileVersion >= 5 ) {
|
||||
// customEnvColors
|
||||
QMap<int, QColor> _dummyQMapIntQColor;
|
||||
ifs >> _dummyQMapIntQColor;
|
||||
}
|
||||
|
||||
if( otherProfileVersion >= 7 ) {
|
||||
// hashTable
|
||||
QHash<QString, int> _dummyQHashQStringInt;
|
||||
ifs >> _dummyQHashQStringInt;
|
||||
}
|
||||
|
||||
if( otherProfileVersion >= 17 ) {
|
||||
// userMapData
|
||||
QMap<QString, QString> _dummyQMapQStringQString;
|
||||
ifs >> _dummyQMapQStringQString;
|
||||
}
|
||||
|
||||
if( otherProfileVersion >= 14 ) {
|
||||
int areaSize;
|
||||
ifs >> areaSize;
|
||||
if( areaCount ) {
|
||||
* areaCount = areaSize;
|
||||
}
|
||||
// read each area
|
||||
for( int i = 0; i < areaSize; i++ ) {
|
||||
TArea * pA = new TArea( 0, 0 );
|
||||
int areaID;
|
||||
ifs >> areaID;
|
||||
ifs >> pA->rooms;
|
||||
ifs >> pA->ebenen;
|
||||
ifs >> pA->exits;
|
||||
ifs >> pA->gridMode;
|
||||
ifs >> pA->max_x;
|
||||
ifs >> pA->max_y;
|
||||
ifs >> pA->max_z;
|
||||
ifs >> pA->min_x;
|
||||
ifs >> pA->min_y;
|
||||
ifs >> pA->min_z;
|
||||
ifs >> pA->span;
|
||||
if( otherProfileVersion >= 17 ) {
|
||||
ifs >> pA->xmaxEbene;
|
||||
ifs >> pA->ymaxEbene;
|
||||
ifs >> pA->xminEbene;
|
||||
ifs >> pA->yminEbene;
|
||||
}
|
||||
else {
|
||||
QMap<int, int> dummyMinMaxEbene;
|
||||
ifs >> pA->xmaxEbene;
|
||||
ifs >> pA->ymaxEbene;
|
||||
ifs >> dummyMinMaxEbene;
|
||||
ifs >> pA->xminEbene;
|
||||
ifs >> pA->yminEbene;
|
||||
ifs >> dummyMinMaxEbene;
|
||||
}
|
||||
ifs >> pA->pos;
|
||||
ifs >> pA->isZone;
|
||||
ifs >> pA->zoneAreaRef;
|
||||
if( otherProfileVersion >= 17 ) {
|
||||
ifs >> pA->mUserData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( otherProfileVersion >= 18 ) {
|
||||
// In version 18 we changed to store the "userRoom" for each profile
|
||||
// so that when copied/shared between profiles they do not interfere
|
||||
// with each other's saved value
|
||||
QHash<QString, int> _dummyQHashQStringInt;
|
||||
ifs >> _dummyQHashQStringInt;
|
||||
if( roomId ) {
|
||||
*roomId = _dummyQHashQStringInt.value( profile );
|
||||
}
|
||||
}
|
||||
else if( otherProfileVersion >= 12 ) {
|
||||
int oldRoomId;
|
||||
ifs >> oldRoomId;
|
||||
if( roomId ) {
|
||||
*roomId = oldRoomId;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if( roomId ) {
|
||||
*roomId = -1; // Not found value
|
||||
}
|
||||
}
|
||||
|
||||
if( otherProfileVersion >= 11 ) {
|
||||
int size;
|
||||
ifs >> size; //size of mapLabels
|
||||
int areaLabelCount = 0;
|
||||
while( ! ifs.atEnd() && areaLabelCount < size ) {
|
||||
int areaID;
|
||||
int size_labels;
|
||||
ifs >> size_labels;
|
||||
ifs >> areaID;
|
||||
int labelCount = 0;
|
||||
while( ! ifs.atEnd() && labelCount < size_labels ) {
|
||||
int labelID;
|
||||
ifs >> labelID;
|
||||
TMapLabel label;
|
||||
if( otherProfileVersion >= 12 ) {
|
||||
ifs >> label.pos;
|
||||
}
|
||||
else {
|
||||
QPointF __label_pos;
|
||||
ifs >> __label_pos;
|
||||
label.pos = QVector3D(__label_pos.x(), __label_pos.y(), 0);
|
||||
}
|
||||
ifs >> label.pointer;
|
||||
ifs >> label.size;
|
||||
ifs >> label.text;
|
||||
ifs >> label.fgColor;
|
||||
ifs >> label.bgColor;
|
||||
ifs >> label.pix;
|
||||
if( otherProfileVersion >= 15 ) {
|
||||
ifs >> label.noScaling;
|
||||
ifs >> label.showOnTop;
|
||||
}
|
||||
labelCount++;
|
||||
}
|
||||
areaLabelCount++;
|
||||
}
|
||||
}
|
||||
|
||||
TRoom * _pT = new TRoom( 0 );
|
||||
QSet<int> _dummyRoomIdSet;
|
||||
while( ! ifs.atEnd() ) {
|
||||
int i;
|
||||
ifs >> i;
|
||||
_pT->restore( ifs, i, otherProfileVersion );
|
||||
// Can't do mpRoomDB->restoreSingleRoom( ifs, i, pT ) as it would mess up
|
||||
// this TMap::mpRoomDB
|
||||
// So emulate using _dummyRoomIdSet
|
||||
if( i > 0 && ! _dummyRoomIdSet.contains( i ) ) {
|
||||
_dummyRoomIdSet.insert( i );
|
||||
}
|
||||
}
|
||||
if( roomCount ) {
|
||||
*roomCount = _dummyRoomIdSet.count();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int TMap::createMapLabel(int area, QString text, float x, float y, float z, QColor fg, QColor bg, bool showOnTop, bool noScaling, qreal zoom, int fontSize )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -101,7 +101,8 @@ public:
|
|||
bool gotoRoom( int, int );
|
||||
void setView( float, float, float, float );
|
||||
bool serialize( QDataStream & );
|
||||
bool restore(QString location);
|
||||
bool restore( QString );
|
||||
const bool retrieveMapFileStats( QString, QString *, int *, int *, int *, int * );
|
||||
void initGraph();
|
||||
void exportMapToDatabase();
|
||||
void importMapFromDatabase();
|
||||
|
|
@ -112,7 +113,9 @@ public:
|
|||
QMap<int, int> envColors;
|
||||
QVector3D span;
|
||||
QPointer<Host> mpHost;
|
||||
int mRoomId;
|
||||
// Was a single int mRoomId but that breaks things when maps are
|
||||
// copied/shared between profiles - so now we track the profile name
|
||||
QHash<QString, int> mRoomIdHash;
|
||||
bool m2DPanMode;
|
||||
bool mLeftDown;
|
||||
bool mRightDown;
|
||||
|
|
|
|||
|
|
@ -279,8 +279,13 @@ bool TRoomDB::__removeRoom( int id )
|
|||
bool TRoomDB::removeRoom( int id )
|
||||
{
|
||||
if( rooms.contains( id ) && id > 0 ) {
|
||||
if( mpMap->mRoomId == id ) {
|
||||
mpMap->mRoomId = 0;
|
||||
if( mpMap->mRoomIdHash.value( mpMap->mpHost->getName() ) == id ) {
|
||||
// Now we store mRoomId for each profile, we must remove any where
|
||||
// this room was used
|
||||
QList<QString> profilesWithUserInThisRoom = mpMap->mRoomIdHash.keys( id );
|
||||
foreach( QString key, profilesWithUserInThisRoom ) {
|
||||
mpMap->mRoomIdHash[ key ] = 0;
|
||||
}
|
||||
}
|
||||
if( mpMap->mTargetID == id ) {
|
||||
mpMap->mTargetID = 0;
|
||||
|
|
|
|||
|
|
@ -1118,7 +1118,7 @@ void cTelnet::setATCPVariables(const QString & msg )
|
|||
{
|
||||
if( mpHost->mpMap )
|
||||
{
|
||||
mpHost->mpMap->mRoomId = arg.toInt();
|
||||
mpHost->mpMap->mRoomIdHash[ mpHost->getName() ] = arg.toInt();
|
||||
if( mpHost->mpMap->mpM && mpHost->mpMap->mpMapper && mpHost->mpMap->mpMapper->mp2dMap )
|
||||
{
|
||||
mpHost->mpMap->mpM->update();
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ void dlgMapper::choseRoom(QListWidgetItem * pT )
|
|||
{
|
||||
qDebug()<<"found room id="<<i;
|
||||
mpMap->mTargetID = i;
|
||||
if( ! mpMap->findPath( mpMap->mRoomId, i ) )
|
||||
if( ! mpMap->findPath( mpMap->mRoomIdHash.value( mpMap->mpHost->getName() ), i ) )
|
||||
{
|
||||
QString msg = "Cannot find a path to this room.\n";
|
||||
mpHost->mpConsole->printSystemMessage(msg);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "mudlet.h"
|
||||
#include "TConsole.h"
|
||||
#include "TMap.h"
|
||||
#include "TRoomDB.h"
|
||||
#include "TTextEdit.h"
|
||||
|
||||
#include "pre_guard.h"
|
||||
|
|
@ -876,27 +877,115 @@ void dlgProfilePreferences::hideActionLabel()
|
|||
map_file_action->hide();
|
||||
}
|
||||
|
||||
|
||||
// TODO: Reorder actions to get mRoomIdHash value from destination profile if NOT
|
||||
// active - or from other profile if it is - THEN update the value in our
|
||||
// mRoomIdHash QHash before saving and copying across.
|
||||
void dlgProfilePreferences::copyMap()
|
||||
{
|
||||
Host * pHost = mpHost;
|
||||
if( ! pHost )
|
||||
{
|
||||
if( ! pHost ) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString toProfile = mapper_profiles_combobox->itemText(mapper_profiles_combobox->currentIndex());
|
||||
QString toProfile = mapper_profiles_combobox->itemText( mapper_profiles_combobox->currentIndex() );
|
||||
|
||||
// at first, save our current map
|
||||
// Identify if other profile is active
|
||||
Host * pOtherHost = 0;
|
||||
QMapIterator<Host *, TConsole *> itSession( mudlet::self()->mConsoleMap );
|
||||
while( itSession.hasNext() ) {
|
||||
itSession.next();
|
||||
pOtherHost = itSession.key();
|
||||
if( pOtherHost->getName() != toProfile ) {
|
||||
pOtherHost = 0;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// pOtherHost will now be null if the profile is NOT active
|
||||
|
||||
// Try and get the player Room Id from the other profile if ACTIVE
|
||||
int otherProfileCurrentRoomId = 0;
|
||||
if( pOtherHost && pOtherHost->mpMap ) {
|
||||
otherProfileCurrentRoomId = pOtherHost->mpMap->mRoomIdHash.value( toProfile, -1 );
|
||||
}
|
||||
|
||||
// Check for the destination directory for the other profile
|
||||
QDir otherProfileDir;
|
||||
QString otherProfileDirPathString = QStringLiteral( "%1/.config/mudlet/profiles/%2/map" )
|
||||
.arg( QDir::homePath() )
|
||||
.arg( toProfile );
|
||||
if( ! otherProfileDir.exists( otherProfileDirPathString ) ) {
|
||||
if( ! otherProfileDir.mkpath( otherProfileDirPathString ) ) {
|
||||
QString errMsg = tr( "[ ERROR ] - Unable to create directory to store map for other profile. Please\n"
|
||||
"check that you have permissions/access to:\n"
|
||||
"\"%1\"\n"
|
||||
"and there is enough space. The copying operation has failed." );
|
||||
pHost->postMessage( errMsg );
|
||||
map_file_action->show();
|
||||
map_file_action->setText( tr( "Creating destination directory failed..." ) );
|
||||
}
|
||||
}
|
||||
|
||||
// We now KNOW there is a place where the destination profile will/has stored
|
||||
// its maps - if we do not already know where the player is in the other
|
||||
// profile - because it isn't active - or was not set - try and find out
|
||||
// what it was from the last saved file - ignoring other details that we
|
||||
// could have also obtained.
|
||||
// otherProfileCurrentRoomId will be -1 if tried and failed to get it from
|
||||
// current running profile, > 0 on sucess or 0 if not running as another profile
|
||||
|
||||
if( otherProfileCurrentRoomId < 1 ) {
|
||||
// Try and get it from saved profile
|
||||
QString otherProfileFileUsed;
|
||||
int otherProfileRoomCount;
|
||||
int otherProfileAreaCount;
|
||||
int otherProfileVersion;
|
||||
if( pHost->mpMap->retrieveMapFileStats( toProfile,
|
||||
& otherProfileFileUsed,
|
||||
& otherProfileVersion,
|
||||
& otherProfileCurrentRoomId,
|
||||
& otherProfileAreaCount,
|
||||
& otherProfileRoomCount ) ) {
|
||||
|
||||
qDebug() << "dlgProfilePreference::copyMap() in other INACTIVE profile:"
|
||||
<< toProfile
|
||||
<< "\nthe file examined was:"
|
||||
<< otherProfileFileUsed
|
||||
<< "\nit was of version:"
|
||||
<< otherProfileVersion
|
||||
<< "\nit had an area count of:"
|
||||
<< otherProfileAreaCount
|
||||
<< "\nit had a room count of:"
|
||||
<< otherProfileRoomCount
|
||||
<< "\nthe player was located in:"
|
||||
<< otherProfileCurrentRoomId;
|
||||
}
|
||||
}
|
||||
else {
|
||||
qDebug() << "dlgProfilePreference::copyMap() in other ACTIVE profile:"
|
||||
<< toProfile
|
||||
<< "\nthe player was located in:"
|
||||
<< otherProfileCurrentRoomId;
|
||||
}
|
||||
|
||||
if( pHost->mpMap->mpRoomDB->getRoom( otherProfileCurrentRoomId ) ) {
|
||||
// If the data for the player location in the other map IS valid in the
|
||||
// current one push the value into the store for THIS profile's map
|
||||
// which will supplant the other profile's one
|
||||
pHost->mpMap->mRoomIdHash[ toProfile ] = otherProfileCurrentRoomId;
|
||||
}
|
||||
|
||||
// Now, save our current map
|
||||
map_file_action->show();
|
||||
map_file_action->setText( tr( "Backing up current map - please wait..." ) );
|
||||
qApp->processEvents(); // Copied from "Loading map - please wait..." case
|
||||
// Just in case is needed to make the above message
|
||||
// show up when saving big maps
|
||||
|
||||
if ( ! mpHost->mpConsole->saveMap( QString() ) )
|
||||
{
|
||||
if ( ! pHost->mpConsole->saveMap( QString() ) ) {
|
||||
map_file_action->setText( tr( "Could not backup the map - saving it failed." ) );
|
||||
QTimer::singleShot(10*1000, this, SLOT(hideActionLabel()));
|
||||
QTimer::singleShot( 10*1000, this, SLOT( hideActionLabel() ) );
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -905,77 +994,66 @@ void dlgProfilePreferences::copyMap()
|
|||
qApp->processEvents(); // Copied from "Loading map - please wait..." case
|
||||
// Just in case is needed to make the above message
|
||||
// show up when saving big maps
|
||||
QDir dir_map;
|
||||
QString directory_map = QStringLiteral( "%1/.config/mudlet/profiles/%2/map" ).arg( QDir::homePath() ).arg( toProfile );
|
||||
if( ! dir_map.exists( directory_map ) )
|
||||
{
|
||||
dir_map.mkpath( directory_map );
|
||||
}
|
||||
|
||||
// work out which map is latest
|
||||
QFile latestMap;
|
||||
QString toMapFolder( QStringLiteral( "%1/.config/mudlet/profiles/%2/map" ).arg( QDir::homePath() ).arg( pHost->getName() ) );
|
||||
QStringList mProfileList = QDir(toMapFolder).entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Time);
|
||||
for( int i=0; i<mProfileList.size(); i++ )
|
||||
{
|
||||
QString s = mProfileList[i];
|
||||
if( s.size() < 1 ) {
|
||||
// work out which map is latest in THIS profile - which SHOULD be the one
|
||||
// we just saved!
|
||||
QString thisProfileLatestMapPathFileName;
|
||||
QFile thisProfileLatestMapFile;
|
||||
QString toMapFolder( QStringLiteral( "%1/.config/mudlet/profiles/%2/map" )
|
||||
.arg( QDir::homePath() )
|
||||
.arg( pHost->getName() ) );
|
||||
QStringList mProfileList = QDir( toMapFolder )
|
||||
.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Time);
|
||||
for( unsigned int i = 0; i < mProfileList.size(); ++i ) {
|
||||
thisProfileLatestMapPathFileName = mProfileList.at( i );
|
||||
if( thisProfileLatestMapPathFileName.size() < 1 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
latestMap.setFileName( QStringLiteral( "%1/%2" ).arg( toMapFolder ).arg( mProfileList.at( i ) ) );
|
||||
thisProfileLatestMapFile.setFileName( QStringLiteral( "%1/%2" )
|
||||
.arg( toMapFolder )
|
||||
.arg( thisProfileLatestMapPathFileName ) );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( latestMap.fileName().isEmpty() )
|
||||
{
|
||||
if( thisProfileLatestMapFile.fileName().isEmpty() ) {
|
||||
map_file_action->setText( tr( "Could not copy the map - failed to work out which map file we just saved the map as!" ) );
|
||||
QTimer::singleShot(10*1000, this, SLOT(hideActionLabel()));
|
||||
QTimer::singleShot( 10 * 1000, this, SLOT( hideActionLabel() ) );
|
||||
return;
|
||||
}
|
||||
|
||||
QFileInfo lm(latestMap.fileName());
|
||||
|
||||
if ( !latestMap.copy( QStringLiteral( "%1/%2" ).arg( directory_map ) .arg( lm.fileName() ) ) ) {
|
||||
if( ! thisProfileLatestMapFile.copy( QStringLiteral( "%1/%2" )
|
||||
.arg( otherProfileDirPathString )
|
||||
.arg( thisProfileLatestMapPathFileName ) ) ) {
|
||||
map_file_action->setText( tr( "Could not copy the map - unable to copy the offline map file over." ) );
|
||||
QTimer::singleShot(10*1000, this, SLOT(hideActionLabel()));
|
||||
QTimer::singleShot( 10*1000, this, SLOT( hideActionLabel() ) );
|
||||
return;
|
||||
}
|
||||
map_file_action->setText( tr( "Map copied successfully." ) ); // don't mention offline here, would be a bit confusing
|
||||
qApp->processEvents(); // Copied from "Loading map - please wait..." case
|
||||
// Just in case is needed to make the above message
|
||||
// show up when saving big maps
|
||||
|
||||
// then force that profile to reload it's latest map - this covers the online case
|
||||
QMap<Host *, TConsole *> activeSessions = mudlet::self()->mConsoleMap;
|
||||
QMapIterator<Host *, TConsole *> it2(activeSessions);
|
||||
while (it2.hasNext()){
|
||||
it2.next();
|
||||
Host * host = it2.key();
|
||||
if (host->mHostName != toProfile)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
map_file_action->setText( tr("Loading map into other running profile - please wait...") );
|
||||
if( ! pOtherHost ) {
|
||||
// Other profile NOT running - so report success
|
||||
map_file_action->setText( tr( "Map copied successfully." ) ); // don't mention offline here, would be a bit confusing
|
||||
qApp->processEvents(); // Copied from "Loading map - please wait..." case
|
||||
// Just in case is needed to make the above message
|
||||
// show up when saving big maps
|
||||
}
|
||||
else {
|
||||
map_file_action->setText( tr( "Map copied successfully - loading it into other running profile - please wait...") );
|
||||
qApp->processEvents(); // Copied from "Loading map - please wait..." case
|
||||
// Just in case is needed to make the above message
|
||||
// show up when saving big maps
|
||||
|
||||
if ( host->mpConsole->loadMap( QStringLiteral( "%1/%2" ).arg( directory_map ).arg( lm.fileName() ) ) )
|
||||
{
|
||||
if( pOtherHost->mpConsole->loadMap( QStringLiteral( "%1/%2" )
|
||||
.arg( otherProfileDirPathString )
|
||||
.arg( thisProfileLatestMapPathFileName ) ) ) {
|
||||
map_file_action->setText( tr( "Map copied and reloaded on %1." ).arg( toProfile ) );
|
||||
QTimer::singleShot(10*1000, this, SLOT(hideActionLabel()));
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
map_file_action->setText( tr( "Map copied, but could not be reloaded on %1." ).arg( toProfile ) );
|
||||
QTimer::singleShot(10*1000, this, SLOT(hideActionLabel()));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
QTimer::singleShot( 10*1000, this, SLOT( hideActionLabel() ) );
|
||||
}
|
||||
|
||||
void dlgProfilePreferences::slot_save_and_exit()
|
||||
|
|
|
|||
|
|
@ -339,7 +339,7 @@ void GLWidget::showArea(QString name)
|
|||
if( name == _n )
|
||||
{
|
||||
mAID = areaID;
|
||||
mRID = mpMap->mRoomId;//FIXME:
|
||||
mRID = mpMap->mRoomIdHash.value( mpMap->mpHost->getName() );
|
||||
mShiftMode = true;
|
||||
mOx = 0;
|
||||
mOy = 0;
|
||||
|
|
@ -357,14 +357,16 @@ void GLWidget::paintGL()
|
|||
return;
|
||||
}
|
||||
float px,py,pz;
|
||||
if( mRID != mpMap->mRoomId && mShiftMode ) mShiftMode = false;
|
||||
if( mRID != mpMap->mRoomIdHash.value( mpMap->mpHost->getName() ) && mShiftMode ) {
|
||||
mShiftMode = false;
|
||||
}
|
||||
|
||||
int ox, oy, oz;
|
||||
if( ! mShiftMode )
|
||||
{
|
||||
|
||||
|
||||
mRID = mpMap->mRoomId;
|
||||
mRID = mpMap->mRoomIdHash.value( mpMap->mpHost->getName() );
|
||||
TRoom * pRID = mpMap->mpRoomDB->getRoom( mRID );
|
||||
if( !pRID )
|
||||
{
|
||||
|
|
@ -1986,7 +1988,7 @@ void GLWidget::mousePressEvent(QMouseEvent *event)
|
|||
if( mpMap->mpRoomDB->getRoom(mTarget) )
|
||||
{
|
||||
mpMap->mTargetID = mTarget;
|
||||
if( mpMap->findPath( mpMap->mRoomId, mpMap->mTargetID) )
|
||||
if( mpMap->findPath( mpMap->mRoomIdHash.value( mpMap->mpHost->getName() ), mpMap->mTargetID) )
|
||||
{
|
||||
mpMap->mpHost->startSpeedWalk();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue