* 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 EXITLOOP
ENDIF ENDIF
SET,fn ./scripts/?{LINDEX,scriptlist ${i}} SET,fn ./scripts/?{LINDEX,scriptlist ${i}}
LOGDEBUG * Loading script file [${fn}] LOG *** Loading script file [${fn}]
IF ?{NOT ?{LOADDEF ${fn}}} IF ?{NOT ?{LOADDEF ${fn}}}
LOGERROR Can't load script [${fn}] LOGERROR Can't load script [${fn}]
ENDIF 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!) // IP or hostname that is allowed to connect. leave blank to allow connections from everywhere (dangerous!)
rmcontrolhost=localhost 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()); DeleteScript(curScript->GetName());
sn = stringToLower(value); sn = stringToLower(value);
_UpdateOrCreateScriptByName(sn); _UpdateOrCreateScriptByName(sn);
_DEFSC_DEBUG(printf("DefScript: now loading '%s'\n",sn.c_str()));
curScript=Script[sn]; curScript=Script[sn];
} }
else if(line=="debug") else if(line=="debug")

View File

@ -81,8 +81,8 @@ PseuInstance::~PseuInstance()
delete _scp; delete _scp;
delete _conf; delete _conf;
log("--- Instance shut down ---");
log_close(); log_close();
} }
bool PseuInstance::Init(void) { bool PseuInstance::Init(void) {
@ -338,6 +338,7 @@ void PseuInstanceConf::ApplyFromVarSet(VarSet &v)
enablegui=(bool)atoi(v.Get("ENABLEGUI").c_str()); enablegui=(bool)atoi(v.Get("ENABLEGUI").c_str());
rmcontrolport=atoi(v.Get("RMCONTROLPORT").c_str()); rmcontrolport=atoi(v.Get("RMCONTROLPORT").c_str());
rmcontrolhost=v.Get("RMCONTROLHOST"); rmcontrolhost=v.Get("RMCONTROLHOST");
useMaps=(bool)atoi(v.Get("USEMAPS").c_str());
// clientversion is a bit more complicated to add // clientversion is a bit more complicated to add
{ {

View File

@ -52,6 +52,7 @@ class PseuInstanceConf
bool disablespellcheck; bool disablespellcheck;
uint32 rmcontrolport; uint32 rmcontrolport;
std::string rmcontrolhost; std::string rmcontrolhost;
bool useMaps;
// gui related // gui related
bool enablegui; 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; break;
// You joined channel successfully // 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 "WorldSocket.h"
#include "RealmSocket.h" #include "RealmSocket.h"
#include "Channel.h" #include "Channel.h"
#include "ObjMgr.h"
#include "World.h"
#include "RealmSession.h" #include "RealmSession.h"
#include "WorldSession.h" #include "WorldSession.h"
@ -27,6 +29,7 @@ WorldSession::WorldSession(PseuInstance *in)
_socket=NULL; _socket=NULL;
_myGUID=0; // i dont have a guid yet _myGUID=0; // i dont have a guid yet
_channels = new Channel(this); _channels = new Channel(this);
_world = NULL;
_sh.SetAutoCloseSockets(false); _sh.SetAutoCloseSockets(false);
//... //...
} }
@ -45,6 +48,8 @@ WorldSession::~WorldSession()
delete _channels; delete _channels;
if(_socket) if(_socket)
delete _socket; delete _socket;
if(_world)
delete _world;
} }
void WorldSession::Start(void) void WorldSession::Start(void)
@ -157,6 +162,8 @@ void WorldSession::Update(void)
_DoTimedActions(); _DoTimedActions();
if(_world)
_world->Update();
} }
@ -206,6 +213,7 @@ OpcodeHandler *WorldSession::_GetOpcodeHandlerTable() const
{SMSG_EMOTE, &WorldSession::_HandleEmoteOpcode}, {SMSG_EMOTE, &WorldSession::_HandleEmoteOpcode},
{SMSG_TEXT_EMOTE, &WorldSession::_HandleTextEmoteOpcode}, {SMSG_TEXT_EMOTE, &WorldSession::_HandleTextEmoteOpcode},
{SMSG_NEW_WORLD, &WorldSession::_HandleNewWorldOpcode}, {SMSG_NEW_WORLD, &WorldSession::_HandleNewWorldOpcode},
{SMSG_LOGIN_VERIFY_WORLD, &WorldSession::_HandleLoginVerifyWorldOpcode},
// table termination // table termination
{ 0, NULL } { 0, NULL }
@ -353,7 +361,6 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
plrNameCache.AddInfo(plr[i]._guid, plr[i]._name); plrNameCache.AddInfo(plr[i]._guid, plr[i]._name);
} }
bool char_found=false; bool char_found=false;
int playerNum = 0;
for(unsigned int i=0;i<num;i++){ for(unsigned int i=0;i<num;i++){
logcustom(0,LGREEN,"## %s (%u) [%s/%s] Map: %s; Zone: %s", logcustom(0,LGREEN,"## %s (%u) [%s/%s] Map: %s; Zone: %s",
@ -375,7 +382,6 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
char_found=true; char_found=true;
_myGUID=plr[i]._guid; _myGUID=plr[i]._guid;
GetInstance()->GetScripts()->variables.Set("@myrace",toString(plr[i]._race)); GetInstance()->GetScripts()->variables.Set("@myrace",toString(plr[i]._race));
playerNum = i;
} }
} }
@ -390,8 +396,10 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
my->Create(_myGUID); my->Create(_myGUID);
objmgr.Add(my); objmgr.Add(my);
WorldPacket pkt; // TODO: initialize the world here, and load required maps.
pkt.SetOpcode(CMSG_PLAYER_LOGIN); // must remove appropriate code from _HandleLoginVerifyWorldOpcode() then!!
WorldPacket pkt(CMSG_PLAYER_LOGIN,8);
pkt << _myGUID; pkt << _myGUID;
SendWorldPacket(pkt); SendWorldPacket(pkt);
} }
@ -644,6 +652,8 @@ void WorldSession::_HandleTelePortAckOpcode(WorldPacket& recvPacket)
response << uint32(0) << (uint32)getMSTime(); // no flags; time correct? response << uint32(0) << (uint32)getMSTime(); // no flags; time correct?
response << x << y << z << o << uint32(0); response << x << y << z << o << uint32(0);
SendWorldPacket(response); SendWorldPacket(response);
if(_world)
_world->UpdatePos(x,y);
} }
void WorldSession::_HandleNewWorldOpcode(WorldPacket& recvPacket) void WorldSession::_HandleNewWorldOpcode(WorldPacket& recvPacket)
@ -655,7 +665,11 @@ void WorldSession::_HandleNewWorldOpcode(WorldPacket& recvPacket)
// recvPacket >> tmapid >> tx >> ty >> tz >> to; // recvPacket >> tmapid >> tx >> ty >> tz >> to;
recvPacket >> mapid >> x >> y >> z >> o; recvPacket >> mapid >> x >> y >> z >> o;
GetMyChar()->ClearSpells(); // will be resent by server 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) 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 Channel;
class RealmSession; class RealmSession;
struct OpcodeHandler; struct OpcodeHandler;
class World;
class WorldSession class WorldSession
@ -40,6 +41,7 @@ public:
uint64 GetGuid(void) { return _myGUID; } uint64 GetGuid(void) { return _myGUID; }
Channel *GetChannels(void) { return _channels; } Channel *GetChannels(void) { return _channels; }
MyCharacter *GetMyChar(void) { ASSERT(_myGUID > 0); return (MyCharacter*)objmgr.GetObj(_myGUID); } MyCharacter *GetMyChar(void) { ASSERT(_myGUID > 0); return (MyCharacter*)objmgr.GetObj(_myGUID); }
World *GetWorld(void) { return _world; }
// CMSGConstructor // CMSGConstructor
@ -88,6 +90,7 @@ private:
void _HandleEmoteOpcode(WorldPacket& recvPacket); void _HandleEmoteOpcode(WorldPacket& recvPacket);
void _HandleTextEmoteOpcode(WorldPacket& recvPacket); void _HandleTextEmoteOpcode(WorldPacket& recvPacket);
void _HandleNewWorldOpcode(WorldPacket& recvPacket); void _HandleNewWorldOpcode(WorldPacket& recvPacket);
void _HandleLoginVerifyWorldOpcode(WorldPacket& recvPacket);
void _MovementUpdate(uint8 objtypeid, uint64 guid, WorldPacket& recvPacket); // Helper for _HandleUpdateObjectOpcode void _MovementUpdate(uint8 objtypeid, uint64 guid, WorldPacket& recvPacket); // Helper for _HandleUpdateObjectOpcode
void _ValuesUpdate(uint64 uguid, WorldPacket& recvPacket); // ... void _ValuesUpdate(uint64 uguid, WorldPacket& recvPacket); // ...
@ -102,6 +105,7 @@ private:
SocketHandler _sh; // handles the WorldSocket SocketHandler _sh; // handles the WorldSocket
Channel *_channels; Channel *_channels;
uint64 _myGUID; uint64 _myGUID;
World *_world;
}; };
#endif #endif

View File

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

View File

@ -20,7 +20,7 @@ bool ADTFile::Load(std::string fn)
if(!fs) if(!fs)
return false; return false;
std::fstream fh; 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()) if(!fh.is_open())
return false; return false;
@ -28,9 +28,8 @@ bool ADTFile::Load(std::string fn)
buf.resize(fs); buf.resize(fs);
fh.read((char*)buf.contents(),fs); fh.read((char*)buf.contents(),fs);
fh.close(); fh.close();
buf.rpos(0);
LoadMem(buf); return LoadMem(buf);
return m_loaded;
} }
bool ADTFile::LoadMem(ByteBuffer& buf) bool ADTFile::LoadMem(ByteBuffer& buf)
@ -44,7 +43,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf)
{ {
buf.read(fourcc,4); flipcc(fourcc); buf.read(fourcc,4); flipcc(fourcc);
buf.read((uint8*)&size,4); 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")) if(!strcmp((char*)fourcc,"MVER"))
{ {
@ -59,7 +58,12 @@ bool ADTFile::LoadMem(ByteBuffer& buf)
for(uint32 i = 0; i < CHUNKS_PER_TILE; i++) for(uint32 i = 0; i < CHUNKS_PER_TILE; i++)
{ {
mcin[i] = buf.read<MCIN_chunk>(); 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")) else if(!strcmp((char*)fourcc,"MTEX"))
@ -72,10 +76,11 @@ bool ADTFile::LoadMem(ByteBuffer& buf)
if(!memcmp(fourcc,"MMDX",4)) if(!memcmp(fourcc,"MMDX",4))
break; break;
buf >> tex; 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); _textures.push_back(tex);
texturecnt++; texturecnt++;
} }
//DEBUG(printf("ADT: loaded %u textures\n",texturecnt));
} }
else if(!strcmp((char*)fourcc,"MMDX")) else if(!strcmp((char*)fourcc,"MMDX"))
{ {
@ -87,10 +92,11 @@ bool ADTFile::LoadMem(ByteBuffer& buf)
if(!memcmp(fourcc,"MMID",4)) if(!memcmp(fourcc,"MMID",4))
break; break;
buf >> model; 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); _models.push_back(model);
modelcnt++; modelcnt++;
} }
//DEBUG(printf("ADT: loaded %u models\n",modelcnt));
} }
/*else if(!strcmp((char*)fourcc,"MMID")) /*else if(!strcmp((char*)fourcc,"MMID"))
{ {
@ -110,7 +116,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf)
if(!memcmp(fourcc,"MWID",4)) if(!memcmp(fourcc,"MWID",4))
break; break;
buf >> wmo; 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); _wmos.push_back(wmo);
wmocnt++; wmocnt++;
} }
@ -126,7 +132,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf)
else if(!strcmp((char*)fourcc,"MDDF")) else if(!strcmp((char*)fourcc,"MDDF"))
{ {
uint32 ndoodads = size / 36; 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++) for(uint32 i = 0; i<ndoodads; i++)
{ {
_doodadsp.push_back(buf.read<MDDF_chunk>()); _doodadsp.push_back(buf.read<MDDF_chunk>());
@ -135,7 +141,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf)
else if(!strcmp((char*)fourcc,"MODF")) else if(!strcmp((char*)fourcc,"MODF"))
{ {
uint32 nwmos = size / 64; 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++) for(uint32 i = 0; i<nwmos; i++)
{ {
_wmosp.push_back(buf.read<MODF_chunk>()); _wmosp.push_back(buf.read<MODF_chunk>());
@ -157,7 +163,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf)
if((!msize) && !strcmp((char*)mfcc,"MCLQ")) if((!msize) && !strcmp((char*)mfcc,"MCLQ"))
msize = _chunks[mcnkid].hdr.sizeLiquid; 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")) if(!strcmp((char*)mfcc,"MCVT"))
{ {
@ -205,7 +211,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf)
if (!strcmp((char*)fcc1,"MCSE")) if (!strcmp((char*)fcc1,"MCSE"))
{ {
_chunks[mcnkid].haswater = false; _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); buf.rpos(buf.rpos()-4);
delete [] fcc1; delete [] fcc1;
continue; // next block read will be the MCSE block continue; // next block read will be the MCSE block
@ -219,7 +225,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf)
uint32 rbytes,diffbytes; uint32 rbytes,diffbytes;
buf >> _chunks[mcnkid].waterlevel; buf >> _chunks[mcnkid].waterlevel;
buf >> tmp; 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?? //buf.rpos(buf.rpos()+4); // base height??
if(msize > 8) // just to be sure if(msize > 8) // just to be sure
{ {
@ -232,16 +238,16 @@ bool ADTFile::LoadMem(ByteBuffer& buf)
buf >> _chunks[mcnkid].lqflags[i]; buf >> _chunks[mcnkid].lqflags[i];
} }
rbytes = buf.rpos() - bufpos; 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 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 // HACK: skip some unk junk bytes
diffbytes = (msize-8) - rbytes; // dont forget to skip the 8 initial bytes diffbytes = (msize-8) - rbytes; // dont forget to skip the 8 initial bytes
buf.rpos(buf.rpos()+diffbytes); 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; delete [] fcc1;
} }
} }
@ -256,7 +262,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf)
} }
else 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]))) if(!(isalnum(mfcc[0]) && isalnum(mfcc[1]) && isalnum(mfcc[2]) && isalnum(mfcc[3])))
{ {
printf("Error loading ADT file (chunk %u error).\n",mcnkid); printf("Error loading ADT file (chunk %u error).\n",mcnkid);
@ -272,7 +278,7 @@ bool ADTFile::LoadMem(ByteBuffer& buf)
} }
else 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]))) if(!(isalnum(fourcc[0]) && isalnum(fourcc[1]) && isalnum(fourcc[2]) && isalnum(fourcc[3])))
{ {
printf("Error loading ADT file.\n"); printf("Error loading ADT file.\n");
@ -283,9 +289,6 @@ bool ADTFile::LoadMem(ByteBuffer& buf)
} }
delete [] fourcc; delete [] fourcc;
m_loaded = true;
return true; return true;
} }

View File

@ -12,7 +12,6 @@ class ADTFile
public: public:
bool Load(std::string); bool Load(std::string);
bool LoadMem(ByteBuffer&); bool LoadMem(ByteBuffer&);
bool Loaded(void) { return m_loaded; }
ADTMapChunk _chunks[CHUNKS_PER_TILE]; // 16x16 ADTMapChunk _chunks[CHUNKS_PER_TILE]; // 16x16
std::vector<std::string> _textures; std::vector<std::string> _textures;
@ -24,8 +23,6 @@ public:
MHDR_chunk mhdr; MHDR_chunk mhdr;
MCIN_chunk mcin[CHUNKS_PER_TILE]; MCIN_chunk mcin[CHUNKS_PER_TILE];
uint32 _version; uint32 _version;
bool m_loaded;
}; };
void ADT_ExportStringSetByOffset(const uint8*, uint32, std::set<std::string>&, char*); 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].ybase = adt->_chunks[ch].hdr.ybase;
_chunks[ch].zbase = adt->_chunks[ch].hdr.zbase; _chunks[ch].zbase = adt->_chunks[ch].hdr.zbase;
uint32 fcnt=0, rcnt=0; 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++) for(uint32 h=0; h<9; h++)
{ {
rcnt++;
_chunks[ch].hmap_rough[rcnt] = adt->_chunks[ch].vertices[fcnt+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++) for(uint32 h=0; h<8; h++)
{ {
_chunks[ch].hmap_fine[fcnt] = adt->_chunks[ch].vertices[fcnt+rcnt];
fcnt++; 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 #ifndef MAPTILE_H
#define MAPTILE_H #define MAPTILE_H
#include <bitset>
#include "WDTFile.h" #include "WDTFile.h"
#include "ADTFile.h" #include "ADTFile.h"
@ -42,12 +44,27 @@ private:
class MapTileStorage class MapTileStorage
{ {
public: 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) inline void ImportTileMap(WDTFile* w)
{ {
_hasTile.reset();
for(uint32 i=0; i<64; i++) for(uint32 i=0; i<64; i++)
{
for(uint32 j=0; j<64; j++) for(uint32 j=0; j<64; j++)
{
if(w->_main.tiles[i*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 x, uint32 y) { SetTile(tile, y*64 + x); }
inline void SetTile(MapTile* tile, uint32 pos) inline void SetTile(MapTile* tile, uint32 pos)
@ -56,23 +73,27 @@ public:
} }
inline void UnloadMapTile(uint32 x, uint32 y) { UnloadMapTile(y*64 + x); } inline void UnloadMapTile(uint32 x, uint32 y) { UnloadMapTile(y*64 + x); }
inline void UnloadMapTile(uint32 pos) inline void UnloadMapTile(uint32 pos)
{
if(_tiles[pos])
{ {
delete _tiles[pos]; delete _tiles[pos];
_tiles[pos] = NULL; _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) 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) inline MapTile *GetTile(uint32 pos)
{ {
return _tiles[pos]; return _tiles[pos];
} }
void _DebugDump(void);
private: private:
MapTile *_tiles[4096]; //64x64 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; return false;
uint32 fs = GetFileSize(fn.c_str()); uint32 fs = GetFileSize(fn.c_str());
ByteBuffer bb(fs); ByteBuffer bb(fs);
bb.resize(fs);
fh.read((char*)bb.contents(),fs); fh.read((char*)bb.contents(),fs);
fh.close(); fh.close();
bb.rpos(0);
return LoadMem(bb); return LoadMem(bb);
} }

View File

@ -11,7 +11,7 @@
#include "DBCFieldData.h" #include "DBCFieldData.h"
#include "Locale.h" #include "Locale.h"
std::vector<std::string> mapNames; std::map<uint32,std::string> mapNames;
std::set<std::string> texNames; std::set<std::string> texNames;
std::set<std::string> modelNames; std::set<std::string> modelNames;
std::set<std::string> wmoNames; std::set<std::string> wmoNames;
@ -207,7 +207,7 @@ bool ConvertDBC(void)
printf("map info.."); printf("map info..");
for(DBCFile::Iterator it = Map.begin(); it != Map.end(); ++it) 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); uint32 id = it->getUInt(MAP_ID);
for(uint32 field=MAP_ID; field < MAP_END; field++) for(uint32 field=MAP_ID; field < MAP_END; field++)
{ {
@ -266,12 +266,12 @@ void ExtractMaps(void)
uint32 extr,extrtotal=0; uint32 extr,extrtotal=0;
MPQHelper mpq("terrain"); MPQHelper mpq("terrain");
CreateDir("stuffextract/data/maps"); 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 // extract the WDT file that stores tile information
char wdt_name[300], wdt_out[300]; 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_name,"World\\Maps\\%s\\%s.wdt",it->second.c_str(),it->second.c_str());
sprintf(wdt_out,MAPSDIR"/%s.wdt",mapNames[it].c_str()); sprintf(wdt_out,MAPSDIR"/%u.wdt",it->first);
ByteBuffer& wdt_bb = mpq.ExtractFile(wdt_name); ByteBuffer& wdt_bb = mpq.ExtractFile(wdt_name);
std::fstream wdt_fh; std::fstream wdt_fh;
wdt_fh.open(wdt_out, std::ios_base::out|std::ios_base::binary); wdt_fh.open(wdt_out, std::ios_base::out|std::ios_base::binary);
@ -293,8 +293,8 @@ void ExtractMaps(void)
{ {
uint32 olddeps; uint32 olddeps;
uint32 depdiff; uint32 depdiff;
sprintf(namebuf,"World\\Maps\\%s\\%s_%u_%u.adt",mapNames[it].c_str(),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"/%s_%u_%u.adt",mapNames[it].c_str(),x,y); sprintf(outbuf,MAPSDIR"/%u_%u_%u.adt",it->first,x,y);
if(mpq.FileExists(namebuf)) if(mpq.FileExists(namebuf))
{ {
ByteBuffer& bb = mpq.ExtractFile(namebuf); ByteBuffer& bb = mpq.ExtractFile(namebuf);
@ -309,6 +309,7 @@ void ExtractMaps(void)
return; return;
} }
fh.write((char*)bb.contents(),bb.size()); fh.write((char*)bb.contents(),bb.size());
fh.flush();
fh.close(); fh.close();
olddeps = texNames.size() + modelNames.size() + wmoNames.size(); olddeps = texNames.size() + modelNames.size() + wmoNames.size();
ADT_FillTextureData(bb.contents(),texNames); ADT_FillTextureData(bb.contents(),texNames);
@ -316,7 +317,7 @@ void ExtractMaps(void)
ADT_FillWMOData(bb.contents(),wmoNames); ADT_FillWMOData(bb.contents(),wmoNames);
depdiff = texNames.size() + modelNames.size() + wmoNames.size() - olddeps; depdiff = texNames.size() + modelNames.size() + wmoNames.size() - olddeps;
extr++; 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);
} }
} }
} }