diff --git a/bin/_startup.def b/bin/_startup.def index b73b489..b97df35 100644 --- a/bin/_startup.def +++ b/bin/_startup.def @@ -15,7 +15,7 @@ LOOP EXITLOOP ENDIF SET,fn ./scripts/?{LINDEX,scriptlist ${i}} - LOGDEBUG * Loading script file [${fn}] + LOG *** Loading script file [${fn}] IF ?{NOT ?{LOADDEF ${fn}}} LOGERROR Can't load script [${fn}] ENDIF diff --git a/bin/conf/PseuWoW.conf.default b/bin/conf/PseuWoW.conf.default index 730a2bc..d9e7194 100644 --- a/bin/conf/PseuWoW.conf.default +++ b/bin/conf/PseuWoW.conf.default @@ -108,3 +108,8 @@ rmcontrolport=8101 // IP or hostname that is allowed to connect. leave blank to allow connections from everywhere (dangerous!) rmcontrolhost=localhost +// if you have exported and copied data from your original client, +// set this to 1 to enable movement and everything map related. +// PseuWoW will need more memory with maps enabled! +useMaps=0 + diff --git a/src/Client/DefScript/DefScript.cpp b/src/Client/DefScript/DefScript.cpp index 2d8b691..b5cfda4 100644 --- a/src/Client/DefScript/DefScript.cpp +++ b/src/Client/DefScript/DefScript.cpp @@ -243,6 +243,7 @@ bool DefScriptPackage::LoadScriptFromFile(std::string fn){ DeleteScript(curScript->GetName()); sn = stringToLower(value); _UpdateOrCreateScriptByName(sn); + _DEFSC_DEBUG(printf("DefScript: now loading '%s'\n",sn.c_str())); curScript=Script[sn]; } else if(line=="debug") diff --git a/src/Client/PseuWoW.cpp b/src/Client/PseuWoW.cpp index 7dbdd0b..acab2a6 100644 --- a/src/Client/PseuWoW.cpp +++ b/src/Client/PseuWoW.cpp @@ -81,8 +81,8 @@ PseuInstance::~PseuInstance() delete _scp; delete _conf; + log("--- Instance shut down ---"); log_close(); - } bool PseuInstance::Init(void) { @@ -338,6 +338,7 @@ void PseuInstanceConf::ApplyFromVarSet(VarSet &v) enablegui=(bool)atoi(v.Get("ENABLEGUI").c_str()); rmcontrolport=atoi(v.Get("RMCONTROLPORT").c_str()); rmcontrolhost=v.Get("RMCONTROLHOST"); + useMaps=(bool)atoi(v.Get("USEMAPS").c_str()); // clientversion is a bit more complicated to add { diff --git a/src/Client/PseuWoW.h b/src/Client/PseuWoW.h index 135775f..346c605 100644 --- a/src/Client/PseuWoW.h +++ b/src/Client/PseuWoW.h @@ -52,6 +52,7 @@ class PseuInstanceConf bool disablespellcheck; uint32 rmcontrolport; std::string rmcontrolhost; + bool useMaps; // gui related bool enablegui; diff --git a/src/Client/World/Channel.cpp b/src/Client/World/Channel.cpp index ee95274..4d0825b 100644 --- a/src/Client/World/Channel.cpp +++ b/src/Client/World/Channel.cpp @@ -136,7 +136,7 @@ void Channel::HandleNotifyOpcode(WorldPacket &packet) } } - log("%s left channel %s", channel.c_str()); + log("%s left channel %s", name.c_str(), channel.c_str()); break; // You joined channel successfully diff --git a/src/Client/World/MapMgr.cpp b/src/Client/World/MapMgr.cpp new file mode 100644 index 0000000..77c99a1 --- /dev/null +++ b/src/Client/World/MapMgr.cpp @@ -0,0 +1,118 @@ +#include "common.h" +#include "log.h" +#include "MapTile.h" +#include "MapMgr.h" + +MapMgr::MapMgr() +{ + _tiles = new MapTileStorage(); + _gridx = _gridy = _mapid = (-1); +} + +MapMgr::~MapMgr() +{ + Flush(); + delete _tiles; +} + +void MapMgr::Update(float x, float y, uint32 m) +{ + if(m != _mapid) + { + Flush(); // we teleported to a new map, drop all loaded maps + WDTFile *wdt = new WDTFile(); + char buf[100]; + sprintf(buf,"data/maps/%u.wdt",m); + if(!wdt->Load(buf)) + { + logerror("MAPMGR: Could not load WDT file '%s'",buf); + } + _tiles->ImportTileMap(wdt); + delete wdt; + _mapid = m; + _gridx = _gridy = (-1); // must load tiles now + } + uint32 xg,yg; // MapTile IDs. Range 0..64 + xg = (uint32)( (ZEROPOINT - x) / TILESIZE); + yg = (uint32)( (ZEROPOINT - y) / TILESIZE); + if(xg != _gridx || yg != _gridy) + { + _LoadNearTiles(xg,yg,m); + _gridx = xg; + _gridy = yg; + _UnloadOldTiles(); + } + _mapid = m; +} + +void MapMgr::Flush(void) +{ + for(uint32 i = 0; i < 4096; i++) + _tiles->UnloadMapTile(i); + logdebug("MAPMGR: Flushed all maps"); +} + +void MapMgr::_LoadNearTiles(uint32 gx, uint32 gy, uint32 m) +{ + logdebug("MAPMGR: Loading near tiles for (%u, %u) map %u",gx,gy,m); + for(uint32 v = gy-1; v <= gy+1; v++) + { + for(uint32 h = gx-1; h <= gx+1; h++) + { + _LoadTile(h,v,m); + } + } +} + +void MapMgr::_LoadTile(uint32 gx, uint32 gy, uint32 m) +{ + if(!_tiles->TileExists(gx,gy)) + { + logerror("MAPMGR: Not loading MapTile (%u, %u) map %u, no entry in WDT tile map",gx,gy,m); + return; + } + + if( !_tiles->GetTile(gx,gy) ) + { + ADTFile *adt = new ADTFile(); + char buf[300]; + sprintf(buf,"data/maps/%u_%u_%u.adt",m,gx,gy); + if(adt->Load(buf)) + { + logdebug("MAPMGR: Loaded ADT '%s'",buf); + MapTile *tile = new MapTile(); + tile->ImportFromADT(adt); + _tiles->SetTile(tile,gx,gy); + logdebug("MAPMGR: Imported MapTile (%u, %u) for map %u",gx,gy,m); + } + else + { + logerror("MAPMGR: Loading ADT '%s' failed!",buf); + } + delete adt; + } + else + { + logdebug("MAPMGR: No need to load MapTile (%u, %u) map %u",gx,gy,m); + } +} + +void MapMgr::_UnloadOldTiles(void) +{ + for(uint32 gx=0; gx<64; gx++) + { + for(uint32 gy=0; gy<64; gy++) + { + if( (_gridx < gx-1 || _gridx > gx+1) && (_gridy < gy-1 || _gridy > gy+1) ) + { + if(_tiles->GetTile(gx,gy)) + { + logdebug("MAPMGR: Unloading old MapTile (%u, %u) map %u",gx,gy,_mapid); + _tiles->UnloadMapTile(gx,gy); + } + } + } + } +} + + diff --git a/src/Client/World/MapMgr.h b/src/Client/World/MapMgr.h new file mode 100644 index 0000000..c90d516 --- /dev/null +++ b/src/Client/World/MapMgr.h @@ -0,0 +1,23 @@ +#ifndef MAPMGR_H +#define MAPMGR_H + +class MapTileStorage; + +class MapMgr +{ +public: + MapMgr(); + ~MapMgr(); + void Update(float,float,uint32); + void Flush(void); + +private: + MapTileStorage *_tiles; + void _LoadTile(uint32,uint32,uint32); + void _LoadNearTiles(uint32,uint32,uint32); + void _UnloadOldTiles(void); + uint32 _mapid; + uint32 _gridx,_gridy; +}; + +#endif \ No newline at end of file diff --git a/src/Client/World/World.cpp b/src/Client/World/World.cpp new file mode 100644 index 0000000..d617fdf --- /dev/null +++ b/src/Client/World/World.cpp @@ -0,0 +1,40 @@ +#include "common.h" +#include "MapMgr.h" +#include "WorldSession.h" +#include "World.h" + +World::World(WorldSession *s) +{ + _session = s; + _mapId = -1; + _mapmgr = NULL; + if(_session->GetInstance()->GetConf()->useMaps) + _mapmgr = new MapMgr(); +} + +World::~World() +{ + if(_mapmgr) + delete _mapmgr; +} + +void World::Update(void) +{ + if(_mapmgr) + { + _mapmgr->Update(_x,_y,_mapId); + } +} + +void World::UpdatePos(float x, float y, uint32 m) +{ + UpdatePos(x,y); + _mapId = m; +} + +void World::UpdatePos(float x, float y) +{ + _x = x; + _y = y; +} + \ No newline at end of file diff --git a/src/Client/World/World.h b/src/Client/World/World.h new file mode 100644 index 0000000..d6a4c37 --- /dev/null +++ b/src/Client/World/World.h @@ -0,0 +1,29 @@ +#ifndef WORLD_H +#define WORLD_H + +class WorldSession; +class MapMgr; + +// used as interface for movement, map data, +class World +{ +public: + World(WorldSession*); + ~World(); + + uint32 GetMapId(void) { return _mapId; } + WorldSession *GetSession(void) { return _session; } + void Update(void); + void UpdatePos(float,float,uint32); + void UpdatePos(float,float); + //GetPosZ(float x, float y); + +private: + WorldSession *_session; + MapMgr *_mapmgr; + uint32 _mapId; + float _x,_y; + +}; + +#endif diff --git a/src/Client/World/WorldSession.cpp b/src/Client/World/WorldSession.cpp index 8ed8037..d113c72 100644 --- a/src/Client/World/WorldSession.cpp +++ b/src/Client/World/WorldSession.cpp @@ -8,6 +8,8 @@ #include "WorldSocket.h" #include "RealmSocket.h" #include "Channel.h" +#include "ObjMgr.h" +#include "World.h" #include "RealmSession.h" #include "WorldSession.h" @@ -27,6 +29,7 @@ WorldSession::WorldSession(PseuInstance *in) _socket=NULL; _myGUID=0; // i dont have a guid yet _channels = new Channel(this); + _world = NULL; _sh.SetAutoCloseSockets(false); //... } @@ -45,6 +48,8 @@ WorldSession::~WorldSession() delete _channels; if(_socket) delete _socket; + if(_world) + delete _world; } void WorldSession::Start(void) @@ -156,7 +161,9 @@ void WorldSession::Update(void) } _DoTimedActions(); - + + if(_world) + _world->Update(); } @@ -206,6 +213,7 @@ OpcodeHandler *WorldSession::_GetOpcodeHandlerTable() const {SMSG_EMOTE, &WorldSession::_HandleEmoteOpcode}, {SMSG_TEXT_EMOTE, &WorldSession::_HandleTextEmoteOpcode}, {SMSG_NEW_WORLD, &WorldSession::_HandleNewWorldOpcode}, + {SMSG_LOGIN_VERIFY_WORLD, &WorldSession::_HandleLoginVerifyWorldOpcode}, // table termination { 0, NULL } @@ -353,7 +361,6 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket) plrNameCache.AddInfo(plr[i]._guid, plr[i]._name); } bool char_found=false; - int playerNum = 0; for(unsigned int i=0;iGetScripts()->variables.Set("@myrace",toString(plr[i]._race)); - playerNum = i; } } @@ -390,8 +396,10 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket) my->Create(_myGUID); objmgr.Add(my); - WorldPacket pkt; - pkt.SetOpcode(CMSG_PLAYER_LOGIN); + // TODO: initialize the world here, and load required maps. + // must remove appropriate code from _HandleLoginVerifyWorldOpcode() then!! + + WorldPacket pkt(CMSG_PLAYER_LOGIN,8); pkt << _myGUID; SendWorldPacket(pkt); } @@ -644,6 +652,8 @@ void WorldSession::_HandleTelePortAckOpcode(WorldPacket& recvPacket) response << uint32(0) << (uint32)getMSTime(); // no flags; time correct? response << x << y << z << o << uint32(0); SendWorldPacket(response); + if(_world) + _world->UpdatePos(x,y); } void WorldSession::_HandleNewWorldOpcode(WorldPacket& recvPacket) @@ -655,7 +665,11 @@ void WorldSession::_HandleNewWorldOpcode(WorldPacket& recvPacket) // recvPacket >> tmapid >> tx >> ty >> tz >> to; recvPacket >> mapid >> x >> y >> z >> o; GetMyChar()->ClearSpells(); // will be resent by server - // clear action buttons + // TODO: clear action buttons + if(_world) + delete _world; + _world = new World(this); + _world->UpdatePos(x,y,mapid); } void WorldSession::_HandleChannelNotifyOpcode(WorldPacket& recvPacket) @@ -836,3 +850,19 @@ void WorldSession::_HandleTextEmoteOpcode(WorldPacket& recvPacket) } +void WorldSession::_HandleLoginVerifyWorldOpcode(WorldPacket& recvPacket) +{ + float x,y,z,o; + uint32 m; + recvPacket >> m >> x >> y >> z >> o; + // for now, init the world as soon as the server confirmed that we are where we are. + logdebug("LoginVerifyWorld: map=%u x=%f y=%f z=%f o=%f",m,x,y,z,o); + if(_world) + delete _world; + _world = new World(this); + _world->UpdatePos(x,y,m); +} + + +// TODO: delete world on LogoutComplete once implemented + diff --git a/src/Client/World/WorldSession.h b/src/Client/World/WorldSession.h index 221a716..be40b8a 100644 --- a/src/Client/World/WorldSession.h +++ b/src/Client/World/WorldSession.h @@ -15,6 +15,7 @@ class WorldPacket; class Channel; class RealmSession; struct OpcodeHandler; +class World; class WorldSession @@ -40,6 +41,7 @@ public: uint64 GetGuid(void) { return _myGUID; } Channel *GetChannels(void) { return _channels; } MyCharacter *GetMyChar(void) { ASSERT(_myGUID > 0); return (MyCharacter*)objmgr.GetObj(_myGUID); } + World *GetWorld(void) { return _world; } // CMSGConstructor @@ -88,6 +90,7 @@ private: void _HandleEmoteOpcode(WorldPacket& recvPacket); void _HandleTextEmoteOpcode(WorldPacket& recvPacket); void _HandleNewWorldOpcode(WorldPacket& recvPacket); + void _HandleLoginVerifyWorldOpcode(WorldPacket& recvPacket); void _MovementUpdate(uint8 objtypeid, uint64 guid, WorldPacket& recvPacket); // Helper for _HandleUpdateObjectOpcode void _ValuesUpdate(uint64 uguid, WorldPacket& recvPacket); // ... @@ -102,6 +105,7 @@ private: SocketHandler _sh; // handles the WorldSocket Channel *_channels; uint64 _myGUID; + World *_world; }; #endif \ No newline at end of file diff --git a/src/PseuWoW.vcproj b/src/PseuWoW.vcproj index e15e48d..59ac995 100644 --- a/src/PseuWoW.vcproj +++ b/src/PseuWoW.vcproj @@ -354,6 +354,12 @@ + + + + @@ -376,22 +382,10 @@ Name="MapSystem" Filter=""> - - - - - - + RelativePath=".\Client\World\MapMgr.cpp"> + RelativePath=".\Client\World\MapMgr.h"> diff --git a/src/shared/ADTFile.cpp b/src/shared/ADTFile.cpp index 025c311..e0a8194 100644 --- a/src/shared/ADTFile.cpp +++ b/src/shared/ADTFile.cpp @@ -20,7 +20,7 @@ bool ADTFile::Load(std::string fn) if(!fs) return false; std::fstream fh; - fh.open(fn.c_str()); + fh.open(fn.c_str(), std::ios_base::in | std::ios_base::binary); if(!fh.is_open()) return false; @@ -28,9 +28,8 @@ bool ADTFile::Load(std::string fn) buf.resize(fs); fh.read((char*)buf.contents(),fs); fh.close(); - - LoadMem(buf); - return m_loaded; + buf.rpos(0); + return LoadMem(buf); } bool ADTFile::LoadMem(ByteBuffer& buf) @@ -44,7 +43,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf) { buf.read(fourcc,4); flipcc(fourcc); buf.read((uint8*)&size,4); - DEBUG(printf("ADT: reading '%s' size %u\n",fourcc,size)); + //DEBUG(printf("ADT: reading '%s' size %u\n",fourcc,size)); if(!strcmp((char*)fourcc,"MVER")) { @@ -59,7 +58,12 @@ bool ADTFile::LoadMem(ByteBuffer& buf) for(uint32 i = 0; i < CHUNKS_PER_TILE; i++) { mcin[i] = buf.read(); - DEBUG(printf("ADT chunk %u at offset %u, size %u flags %X async %u\n",i,mcin[i].offset,mcin[i].size,mcin[i].flags,mcin[i].async)); + //DEBUG(printf("ADT chunk %u at offset %u, size %u flags %X async %u\n",i,mcin[i].offset,mcin[i].size,mcin[i].flags,mcin[i].async)); + if(!mcin[i].offset) + { + printf("ADT: ERROR: chunk offset is NULL! Not loading.\n"); + return false; + } } } else if(!strcmp((char*)fourcc,"MTEX")) @@ -72,10 +76,11 @@ bool ADTFile::LoadMem(ByteBuffer& buf) if(!memcmp(fourcc,"MMDX",4)) break; buf >> tex; - DEBUG(printf("MTEX offset %u \"%s\"\n",buf.rpos(),tex.c_str())); + //DEBUG(printf("MTEX offset %u \"%s\"\n",buf.rpos(),tex.c_str())); _textures.push_back(tex); texturecnt++; } + //DEBUG(printf("ADT: loaded %u textures\n",texturecnt)); } else if(!strcmp((char*)fourcc,"MMDX")) { @@ -87,10 +92,11 @@ bool ADTFile::LoadMem(ByteBuffer& buf) if(!memcmp(fourcc,"MMID",4)) break; buf >> model; - DEBUG(printf("MMDX offset %u \"%s\"\n",buf.rpos(),model.c_str())); + //DEBUG(printf("MMDX offset %u \"%s\"\n",buf.rpos(),model.c_str())); _models.push_back(model); modelcnt++; } + //DEBUG(printf("ADT: loaded %u models\n",modelcnt)); } /*else if(!strcmp((char*)fourcc,"MMID")) { @@ -110,7 +116,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf) if(!memcmp(fourcc,"MWID",4)) break; buf >> wmo; - DEBUG(printf("MWMO offset %u \"%s\"\n",buf.rpos(),wmo.c_str())); + //DEBUG(printf("MWMO offset %u \"%s\"\n",buf.rpos(),wmo.c_str())); _wmos.push_back(wmo); wmocnt++; } @@ -126,7 +132,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf) else if(!strcmp((char*)fourcc,"MDDF")) { uint32 ndoodads = size / 36; - DEBUG(printf("ADT: Loading %u doodads.\n",ndoodads)); + //DEBUG(printf("ADT: Loading %u doodads.\n",ndoodads)); for(uint32 i = 0; i()); @@ -135,7 +141,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf) else if(!strcmp((char*)fourcc,"MODF")) { uint32 nwmos = size / 64; - DEBUG(printf("ADT: Loading %u wmos.\n",nwmos)); + //DEBUG(printf("ADT: Loading %u wmos.\n",nwmos)); for(uint32 i = 0; i()); @@ -157,7 +163,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf) if((!msize) && !strcmp((char*)mfcc,"MCLQ")) msize = _chunks[mcnkid].hdr.sizeLiquid; - DEBUG(printf("ADT: MCNK: reading '%s' size %u\n",mfcc,msize)); + //DEBUG(printf("ADT: MCNK: reading '%s' size %u\n",mfcc,msize)); if(!strcmp((char*)mfcc,"MCVT")) { @@ -205,7 +211,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf) if (!strcmp((char*)fcc1,"MCSE")) { _chunks[mcnkid].haswater = false; - DEBUG(printf("ADT: MCNK: MCLQ not present\n")); + //DEBUG(printf("ADT: MCNK: MCLQ not present\n")); buf.rpos(buf.rpos()-4); delete [] fcc1; continue; // next block read will be the MCSE block @@ -219,7 +225,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf) uint32 rbytes,diffbytes; buf >> _chunks[mcnkid].waterlevel; buf >> tmp; - DEBUG(printf("ADT: MCNK: MCLQ base floats: %f %f\n",_chunks[mcnkid].waterlevel,tmp)); + //DEBUG(printf("ADT: MCNK: MCLQ base floats: %f %f\n",_chunks[mcnkid].waterlevel,tmp)); //buf.rpos(buf.rpos()+4); // base height?? if(msize > 8) // just to be sure { @@ -232,16 +238,16 @@ bool ADTFile::LoadMem(ByteBuffer& buf) buf >> _chunks[mcnkid].lqflags[i]; } rbytes = buf.rpos() - bufpos; - DEBUG(printf("ADT: MCNK: MCLQ block loaded. %u / %u bytes.\n",rbytes,msize)); + //DEBUG(printf("ADT: MCNK: MCLQ block loaded. %u / %u bytes.\n",rbytes,msize)); } else { - DEBUG(printf("ADT: MCNK: MCLQ block has only %u bytes\n",msize)); + //DEBUG(printf("ADT: MCNK: MCLQ block has only %u bytes\n",msize)); } // HACK: skip some unk junk bytes diffbytes = (msize-8) - rbytes; // dont forget to skip the 8 initial bytes buf.rpos(buf.rpos()+diffbytes); - DEBUG(printf("ADT: MCNK: MCLQ - %u junk bytes skipped\n",diffbytes)); + //DEBUG(printf("ADT: MCNK: MCLQ - %u junk bytes skipped\n",diffbytes)); delete [] fcc1; } } @@ -256,7 +262,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf) } else { - DEBUG(printf("ADT: MCNK: '%s' block unhandled, skipping %u bytes\n",mfcc,msize)); + //DEBUG(printf("ADT: MCNK: '%s' block unhandled, skipping %u bytes\n",mfcc,msize)); if(!(isalnum(mfcc[0]) && isalnum(mfcc[1]) && isalnum(mfcc[2]) && isalnum(mfcc[3]))) { printf("Error loading ADT file (chunk %u error).\n",mcnkid); @@ -272,7 +278,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf) } else { - DEBUG(printf("ADT: '%s' block unhandled, skipping %u bytes\n",fourcc,size)); + //DEBUG(printf("ADT: '%s' block unhandled, skipping %u bytes\n",fourcc,size)); if(!(isalnum(fourcc[0]) && isalnum(fourcc[1]) && isalnum(fourcc[2]) && isalnum(fourcc[3]))) { printf("Error loading ADT file.\n"); @@ -283,9 +289,6 @@ bool ADTFile::LoadMem(ByteBuffer& buf) } delete [] fourcc; - - - m_loaded = true; return true; } diff --git a/src/shared/ADTFile.h b/src/shared/ADTFile.h index aca424c..3e8b4fc 100644 --- a/src/shared/ADTFile.h +++ b/src/shared/ADTFile.h @@ -12,7 +12,6 @@ class ADTFile public: bool Load(std::string); bool LoadMem(ByteBuffer&); - bool Loaded(void) { return m_loaded; } ADTMapChunk _chunks[CHUNKS_PER_TILE]; // 16x16 std::vector _textures; @@ -24,8 +23,6 @@ public: MHDR_chunk mhdr; MCIN_chunk mcin[CHUNKS_PER_TILE]; uint32 _version; - - bool m_loaded; }; void ADT_ExportStringSetByOffset(const uint8*, uint32, std::set&, char*); diff --git a/src/shared/MapTile.cpp b/src/shared/MapTile.cpp index fa298ec..4ae91bc 100644 --- a/src/shared/MapTile.cpp +++ b/src/shared/MapTile.cpp @@ -27,18 +27,37 @@ void MapTile::ImportFromADT(ADTFile *adt) _chunks[ch].ybase = adt->_chunks[ch].hdr.ybase; _chunks[ch].zbase = adt->_chunks[ch].hdr.zbase; uint32 fcnt=0, rcnt=0; - while(fcnt+rcnt < 145) //9*9 + 8*8 + while(true) //9*9 + 8*8 { for(uint32 h=0; h<9; h++) { - rcnt++; _chunks[ch].hmap_rough[rcnt] = adt->_chunks[ch].vertices[fcnt+rcnt]; + rcnt++; } + if(rcnt+fcnt >= 145) + break; for(uint32 h=0; h<8; h++) { + _chunks[ch].hmap_fine[fcnt] = adt->_chunks[ch].vertices[fcnt+rcnt]; fcnt++; - _chunks[ch].hmap_fine[rcnt] = adt->_chunks[ch].vertices[fcnt+rcnt]; } } } +} + +// seems to be somewhat buggy... wtf? +void MapTileStorage::_DebugDump(void) +{ + std::string out; + for(uint32 i=0; i<64; i++) + { + for(uint32 j=0; j<64; j++) + { + + out += (_hasTile[i*64 + j] ? "1" : "0"); + } + out += "\n"; + } + printf("MAP TILE MAP DEBUG DUMP, 64x64 TILES:\n"); + printf(out.c_str()); } \ No newline at end of file diff --git a/src/shared/MapTile.h b/src/shared/MapTile.h index c8b08a4..12ccb6e 100644 --- a/src/shared/MapTile.h +++ b/src/shared/MapTile.h @@ -1,6 +1,8 @@ #ifndef MAPTILE_H #define MAPTILE_H +#include + #include "WDTFile.h" #include "ADTFile.h" @@ -42,12 +44,27 @@ private: class MapTileStorage { public: + inline MapTileStorage() + { + memset(_tiles,0,sizeof(MapTile*)*4096); + } + inline ~MapTileStorage() + { + for(uint32 i=0; i<4096; i++) + UnloadMapTile(i); + } inline void ImportTileMap(WDTFile* w) { + _hasTile.reset(); for(uint32 i=0; i<64; i++) + { for(uint32 j=0; j<64; j++) + { if(w->_main.tiles[i*64 + j]) - _hasTile[i] &= (1 << j); + _hasTile[i*64 + j] = true; + } + + } } inline void SetTile(MapTile* tile, uint32 x, uint32 y) { SetTile(tile, y*64 + x); } inline void SetTile(MapTile* tile, uint32 pos) @@ -57,22 +74,26 @@ public: inline void UnloadMapTile(uint32 x, uint32 y) { UnloadMapTile(y*64 + x); } inline void UnloadMapTile(uint32 pos) { - delete _tiles[pos]; - _tiles[pos] = NULL; + if(_tiles[pos]) + { + delete _tiles[pos]; + _tiles[pos] = NULL; + } } - inline void TileExists(uint32 x, uint32 y) { TileExists(y*64 + x); } + inline bool TileExists(uint32 x, uint32 y) { return TileExists(y*64 + x); } inline bool TileExists(uint32 pos) { - return _hasTile[pos/64] & (1<<(pos%64)); + return _hasTile[pos]; } - inline MapTile *GetTile(uint32 x, uint32 y) { GetTile(y*64 + x); } + inline MapTile *GetTile(uint32 x, uint32 y) { return GetTile(y*64 + x); } inline MapTile *GetTile(uint32 pos) { return _tiles[pos]; } + void _DebugDump(void); private: MapTile *_tiles[4096]; //64x64 - uint64 _hasTile[64]; //64 x 64 bits, this saves some mem compared to bluzz format + std::bitset<4096> _hasTile; }; diff --git a/src/shared/WDTFile.cpp b/src/shared/WDTFile.cpp index c5fa82c..3954c10 100644 --- a/src/shared/WDTFile.cpp +++ b/src/shared/WDTFile.cpp @@ -22,8 +22,10 @@ bool WDTFile::Load(std::string fn) return false; uint32 fs = GetFileSize(fn.c_str()); ByteBuffer bb(fs); + bb.resize(fs); fh.read((char*)bb.contents(),fs); fh.close(); + bb.rpos(0); return LoadMem(bb); } diff --git a/src/tools/stuffextract/StuffExtract.cpp b/src/tools/stuffextract/StuffExtract.cpp index 2186d92..b522521 100644 --- a/src/tools/stuffextract/StuffExtract.cpp +++ b/src/tools/stuffextract/StuffExtract.cpp @@ -11,7 +11,7 @@ #include "DBCFieldData.h" #include "Locale.h" -std::vector mapNames; +std::map mapNames; std::set texNames; std::set modelNames; std::set wmoNames; @@ -207,7 +207,7 @@ bool ConvertDBC(void) printf("map info.."); for(DBCFile::Iterator it = Map.begin(); it != Map.end(); ++it) { - mapNames.push_back(it->getString(MAP_NAME_GENERAL)); + mapNames[it->getInt(MAP_ID)] = it->getString(MAP_NAME_GENERAL); uint32 id = it->getUInt(MAP_ID); for(uint32 field=MAP_ID; field < MAP_END; field++) { @@ -266,12 +266,12 @@ void ExtractMaps(void) uint32 extr,extrtotal=0; MPQHelper mpq("terrain"); CreateDir("stuffextract/data/maps"); - for(uint32 it=0; it < mapNames.size(); it++) + for(std::map::iterator it = mapNames.begin(); it != mapNames.end(); it++) { // extract the WDT file that stores tile information char wdt_name[300], wdt_out[300]; - sprintf(wdt_name,"World\\Maps\\%s\\%s.wdt",mapNames[it].c_str(),mapNames[it].c_str()); - sprintf(wdt_out,MAPSDIR"/%s.wdt",mapNames[it].c_str()); + sprintf(wdt_name,"World\\Maps\\%s\\%s.wdt",it->second.c_str(),it->second.c_str()); + sprintf(wdt_out,MAPSDIR"/%u.wdt",it->first); ByteBuffer& wdt_bb = mpq.ExtractFile(wdt_name); std::fstream wdt_fh; wdt_fh.open(wdt_out, std::ios_base::out|std::ios_base::binary); @@ -293,8 +293,8 @@ void ExtractMaps(void) { uint32 olddeps; uint32 depdiff; - sprintf(namebuf,"World\\Maps\\%s\\%s_%u_%u.adt",mapNames[it].c_str(),mapNames[it].c_str(),x,y); - sprintf(outbuf,MAPSDIR"/%s_%u_%u.adt",mapNames[it].c_str(),x,y); + sprintf(namebuf,"World\\Maps\\%s\\%s_%u_%u.adt",it->second.c_str(),it->second.c_str(),x,y); + sprintf(outbuf,MAPSDIR"/%u_%u_%u.adt",it->first,x,y); if(mpq.FileExists(namebuf)) { ByteBuffer& bb = mpq.ExtractFile(namebuf); @@ -309,6 +309,7 @@ void ExtractMaps(void) return; } fh.write((char*)bb.contents(),bb.size()); + fh.flush(); fh.close(); olddeps = texNames.size() + modelNames.size() + wmoNames.size(); ADT_FillTextureData(bb.contents(),texNames); @@ -316,7 +317,7 @@ void ExtractMaps(void) ADT_FillWMOData(bb.contents(),wmoNames); depdiff = texNames.size() + modelNames.size() + wmoNames.size() - olddeps; extr++; - printf("[%u/%u]: %s; %u new deps.\n",it+1,mapNames.size(),namebuf,depdiff); + printf("[%u:%u] %s; %u new deps.\n",extr,it->first,namebuf,depdiff); } } }