* implemented map loading. new conf option: 'useMaps'

* found a problem with file listing, _startup.def refuses to load some .def files. trying to fix that now...
This commit is contained in:
False.Genesis 2007-06-24 17:53:54 +00:00
parent 28178f7727
commit 8ff8117e53
19 changed files with 355 additions and 66 deletions

View File

@ -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

View File

@ -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

View File

@ -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")

View File

@ -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
{

View File

@ -52,6 +52,7 @@ class PseuInstanceConf
bool disablespellcheck;
uint32 rmcontrolport;
std::string rmcontrolhost;
bool useMaps;
// gui related
bool enablegui;

View File

@ -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

118
src/Client/World/MapMgr.cpp Normal file
View File

@ -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);
}
}
}
}
}

23
src/Client/World/MapMgr.h Normal file
View File

@ -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

View File

@ -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;
}

29
src/Client/World/World.h Normal file
View File

@ -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

View File

@ -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)
@ -157,6 +162,8 @@ 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;i<num;i++){
logcustom(0,LGREEN,"## %s (%u) [%s/%s] Map: %s; Zone: %s",
@ -375,7 +382,6 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
char_found=true;
_myGUID=plr[i]._guid;
GetInstance()->GetScripts()->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

View File

@ -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

View File

@ -354,6 +354,12 @@
<File
RelativePath=".\Client\World\UpdateMask.h">
</File>
<File
RelativePath=".\Client\World\World.cpp">
</File>
<File
RelativePath=".\Client\World\World.h">
</File>
<File
RelativePath=".\Client\World\WorldPacket.cpp">
</File>
@ -376,22 +382,10 @@
Name="MapSystem"
Filter="">
<File
RelativePath=".\Client\World\MapTile.cpp">
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
RelativePath=".\Client\World\MapMgr.cpp">
</File>
<File
RelativePath=".\Client\World\MapTile.h">
RelativePath=".\Client\World\MapMgr.h">
</File>
</Filter>
</Filter>

View File

@ -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<MCIN_chunk>();
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<ndoodads; i++)
{
_doodadsp.push_back(buf.read<MDDF_chunk>());
@ -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<nwmos; i++)
{
_wmosp.push_back(buf.read<MODF_chunk>());
@ -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;
}

View File

@ -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<std::string> _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<std::string>&, char*);

View File

@ -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());
}

View File

@ -1,6 +1,8 @@
#ifndef MAPTILE_H
#define MAPTILE_H
#include <bitset>
#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;
};

View File

@ -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);
}

View File

@ -11,7 +11,7 @@
#include "DBCFieldData.h"
#include "Locale.h"
std::vector<std::string> mapNames;
std::map<uint32,std::string> mapNames;
std::set<std::string> texNames;
std::set<std::string> modelNames;
std::set<std::string> 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<uint32,std::string>::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);
}
}
}