* corrected terrain placement

* corrected object placement
* corrected grid formulas
* update MyCharacter position when beeing teleported
* tested in dun morogh, stormwind, thrallmar and arathi basin, object placement on the map is just fine now ;)
* cleanups not yet done, old unused funcs are still there
This commit is contained in:
false_genesis 2008-04-02 15:30:35 +00:00
parent cc5cf995fd
commit 6d5b8de2d5
7 changed files with 90 additions and 32 deletions

View File

@ -34,7 +34,7 @@ void DrawObject::_Init(void)
{
if(!cube && _obj->IsWorldObject()) // only world objects have coords and can be drawn
{
cube = _smgr->addCubeSceneNode(10);
cube = _smgr->addCubeSceneNode(2);
cube->setName("CUBE");
//cube->setPosition(irr::core::vector3di(100,100,100));
cube->setRotation(irr::core::vector3df(0,0,0));
@ -63,13 +63,7 @@ void DrawObject::Draw(void)
if(cube)
{
WorldPosition pos = ((WorldObject*)_obj)->GetPosition();
// TODO: these formulas are horribly wrong! FIXME ASAP!
// they work best for ".tele dunmorogh"
float dx=pos.x * -5.0f - 26830.0f;
float dy=pos.z;
float dz=pos.y * -3.5f - 566.0f;
cube->setPosition(irr::core::vector3df(dx,dy,dz));
cube->setPosition(irr::core::vector3df(-pos.x,pos.z,-pos.y));
if(_obj->IsPlayer())
{
cube->getMaterial(0).DiffuseColor.set(255,255,0,0);

View File

@ -36,6 +36,8 @@ enum DriverIDs
#define RAD_TO_DEG(x) ((x)/ANGLE_STEP)
#define RAD_FIX(x) ( (x)>(2*M_PI) ? ((x)-(2*M_PI)) : (x) )
#define DEG_FIX(x) ( (x)>360 ? ((x)-360) : (x) )
#define IRR_TO_O(x) (DEG_TO_RAD(x) + ((M_PI*3.0f)/2.0f))
#define O_TO_IRR(x) (((M_PI/3.0f)*2.0f) - DEG_TO_RAD(x))
#define COORD_SCALE_VALUE_X 0.336f
#define COORD_SCALE_VALUE_Y 0.2f

View File

@ -62,6 +62,7 @@ public:
void OnUpdate(s32);
void UpdateTerrain(void);
void InitTerrain(void);
void RelocateCamera(void);
WorldPosition GetWorldPosition(void);
void SetWorldPosition(WorldPosition);
@ -76,6 +77,7 @@ private:
s32 mapsize, meshsize;
f32 tilesize;
WorldSession *wsession;
World *world;
MapMgr *mapmgr;
IGUIStaticText *debugText;
bool debugmode;

View File

@ -20,7 +20,8 @@ SceneWorld::SceneWorld(PseuGUI *g) : Scene(g)
// store some pointers right now to prevent repeated ptr dereferencing later (speeds up code)
gui = g;
wsession = gui->GetInstance()->GetWSession();
mapmgr = wsession->GetWorld()->GetMapMgr();
world = wsession->GetWorld();
mapmgr = world->GetMapMgr();
// TODO: hardcoded for now, make this adjustable later
float fogdist = 150;
@ -51,6 +52,7 @@ SceneWorld::SceneWorld(PseuGUI *g) : Scene(g)
InitTerrain();
UpdateTerrain();
RelocateCamera();
DEBUG(logdebug("SceneWorld: Init done!"));
}
@ -123,6 +125,9 @@ void SceneWorld::OnUpdate(s32 timediff)
scrnshot->drop();
}
}
if(camera->getPitch() < 270 && camera->getPitch() > 90)
camera->turnUp(90);
if(mouse_pressed_left || mouse_pressed_right)
{
@ -150,7 +155,8 @@ void SceneWorld::OnUpdate(s32 timediff)
}
// camera height control
if (eventrecv->mouse.wheel < 10) eventrecv->mouse.wheel = 10;
if (eventrecv->mouse.wheel < 10)
eventrecv->mouse.wheel = 10;
camera->setHeight( eventrecv->mouse.wheel + terrain->getHeight(camera->getPosition()) );
WorldPosition wp = GetWorldPosition();
@ -162,6 +168,7 @@ void SceneWorld::OnUpdate(s32 timediff)
str += camera->getPosition().Y;
str += L",";
str += camera->getPosition().Z;
str += L"\n";
str += " ## HEAD: ";
str += DEG_TO_RAD(camera->getHeading());
str += L" Pos: ";
@ -194,12 +201,11 @@ void SceneWorld::InitTerrain(void)
return;
}
mapsize = 8 * 16 * 3; // 9-1 height floats in 16 chunks per tile per axis in 3 MapTiles
mapsize = (8 * 16 * 3) - 1; // 9-1 height floats in 16 chunks per tile per axis in 3 MapTiles
tilesize = UNITSIZE;
meshsize = (s32)CHUNKSIZE*3;
vector3df terrainPos(0.0f, 0.0f, 0.0f); // TODO: use PseuWoW's world coords here?
camera->setPosition(core::vector3df(mapsize*tilesize/2, 0, mapsize*tilesize/2) + terrainPos);
//camera->setPosition(core::vector3df(mapsize*tilesize/2, 0, mapsize*tilesize/2) + terrainPos);
terrain = new ShTlTerrainSceneNode(smgr,mapsize,mapsize,tilesize,meshsize);
terrain->drop();
@ -207,7 +213,7 @@ void SceneWorld::InitTerrain(void)
terrain->setMaterialTexture(0, driver->getTexture("data/misc/dirt_test.jpg"));
terrain->setMaterialFlag(video::EMF_LIGHTING, true);
terrain->setMaterialFlag(video::EMF_FOG_ENABLE, true);
terrain->setPosition(terrainPos);
}
@ -302,8 +308,40 @@ void SceneWorld::UpdateTerrain(void)
terrain->setColor(i,j, video::SColor(255,r,g,b));
}
// to set the correct position of the terrain, we have to use the top-left tile's coords as terrain base pos
MapTile *maptile = mapmgr->GetNearTile(-1, -1);
if(maptile)
{
vector3df tpos;
tpos.X = -maptile->GetBaseX();
tpos.Y = 0; // height already managed when building up terrain
tpos.Z = -maptile->GetBaseY();
logdebug("SceneWorld: Setting position of terrain (x:%.2f y:%.2f z:%.2f)", tpos.X, tpos.Y, tpos.Z);
terrain->setPosition(tpos);
}
logdebug("SceneWorld: Smoothing terrain normals...");
terrain->smoothNormals();
// TODO: check if camera should really be relocated -> in case we got teleported
// do NOT relocate camera if we moved around and triggered the map loading code by ourself!
RelocateCamera();
}
void SceneWorld::RelocateCamera(void)
{
MyCharacter *my = wsession->GetMyChar();
if(my)
{
logdebug("SceneWorld: Relocating camera to MyCharacter");
camera->setPosition(vector3df(-my->GetX(),my->GetZ(),-my->GetY()));
camera->turnLeft(camera->getHeading() - O_TO_IRR(my->GetO()));
}
else
{
logerror("SceneWorld: Relocating camera to MyCharacter - not found!");
}
}
WorldPosition SceneWorld::GetWorldPosition(void)
@ -328,12 +366,13 @@ WorldPosition SceneWorld::GetWorldPosition(void)
float relx = cam.X * COORD_SCALE_VALUE_X + CHUNKSIZE;
float rely = cam.Z * COORD_SCALE_VALUE_Y + CHUNKSIZE;
float o = DEG_TO_RAD(camera->getHeading()) + ((M_PI*3.0f)/2.0f);
float o = IRR_TO_O(camera->getHeading()) + ((M_PI*3.0f)/2.0f);
return WorldPosition(mapx - relx, mapy - rely, cam.Y, RAD_FIX(o) );
}
void SceneWorld::SetWorldPosition(WorldPosition wp)
{
return;
UpdateTerrain();
vector3df cam;
dimension2d<s32> tsize = terrain->getSize();
@ -346,7 +385,7 @@ void SceneWorld::SetWorldPosition(WorldPosition wp)
}
cam.X = tile->GetBaseX() - wp.x + (tsize.Width * UNITSIZE);
cam.Z = tile->GetBaseX() - wp.y + (tsize.Height * UNITSIZE);
float heading = RAD_TO_DEG(((M_PI*3.0f)/2.0f) - wp.o);
float heading = O_TO_IRR(wp.o);
float heading_diff = camera->getHeading() - heading;
//logdebug("Setting camera to x: %3f y: %3f z:%3f head: %3f", cam.X, cam.Y, cam.Z, heading);
//camera->turnLeft(heading_diff);

View File

@ -3,6 +3,19 @@
#include "MapTile.h"
#include "MapMgr.h"
void MakeMapFilename(char *fn, uint32 m, uint32 x, uint32 y)
{
sprintf(fn,"./data/maps/%u_%u_%u.adt",m,x,y);
}
bool TileExistsInFile(uint32 m, uint32 x, uint32 y)
{
char buf[50];
MakeMapFilename(buf,m,x,y);
return GetFileSize(buf);
}
MapMgr::MapMgr()
{
DEBUG(logdebug("Creating MapMgr with TILESIZE=%.3f CHUNKSIZE=%.3f UNITSIZE=%.3f",TILESIZE,CHUNKSIZE,UNITSIZE));
@ -69,15 +82,23 @@ 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(TileExistsInFile(m,gx,gy))
{
logerror("MapMgr: Tile (%u, %u) exists not in WDT, but as file?!",gx,gy);
// continue loading...
}
else
{
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);
MakeMapFilename(buf,m,gx,gy);
if(adt->Load(buf))
{
logdebug("MAPMGR: Loaded ADT '%s'",buf);
@ -120,7 +141,7 @@ void MapMgr::_UnloadOldTiles(void)
MapTile *MapMgr::GetTile(uint32 xg, uint32 yg, bool forceLoad)
{
MapTile *tile = _tiles->GetTile(xg,yg);
if(!tile)
if(!tile && forceLoad)
{
_LoadTile(xg,yg,_mapid);
tile = _tiles->GetTile(xg,yg);
@ -145,7 +166,7 @@ uint32 MapMgr::GetGridCoord(float f)
GridCoordPair MapMgr::GetTransformGridCoordPair(float x, float y)
{
return GridCoordPair(GetGridCoord(x), GetGridCoord(y));
return GridCoordPair(GetGridCoord(y), GetGridCoord(x)); // yes, they are reversed. definitely.
}
uint32 MapMgr::GetLoadedMapsCount(void)

View File

@ -919,10 +919,11 @@ void WorldSession::_HandleTelePortAckOpcode(WorldPacket& recvPacket)
SendWorldPacket(response);
_world->UpdatePos(x,y);
_world->Update();
if(PseuGUI *gui = GetInstance()->GetGUI())
if(MyCharacter *my = GetMyChar())
{
gui->SetWorldPosition(WorldPosition(x,y,z,o));
my->SetPosition(x,y,z,o);
}
if(GetInstance()->GetScripts()->ScriptExists("_onteleport"))
@ -947,8 +948,6 @@ void WorldSession::_HandleNewWorldOpcode(WorldPacket& recvPacket)
// else we had to do the following before:
// recvPacket >> tmapid >> tx >> ty >> tz >> to;
recvPacket >> mapid >> x >> y >> z >> o;
if(GetMyChar())
GetMyChar()->ClearSpells(); // will be resent by server
// when getting teleported, the client sends CMSG_CANCEL_TRADE 2 times.. dont ask me why.
WorldPacket wp(CMSG_CANCEL_TRADE,8);
@ -978,14 +977,14 @@ void WorldSession::_HandleNewWorldOpcode(WorldPacket& recvPacket)
_world->UpdatePos(x,y,mapid);
_world->Update();
// TODO: need to switch to SCENESTATE_LOGINSCREEN here, and after everything is loaded, back to SCENESTATE_WORLD
if(PseuGUI *gui = GetInstance()->GetGUI())
if(MyCharacter *my = GetMyChar())
{
//gui->SetSceneState(SCENESTATE_WORLD);
// commented out, should be world scene anyway at this point...
gui->SetWorldPosition(WorldPosition(x,y,z,o));
my->ClearSpells(); // will be resent by server
my->SetPosition(x,y,z,o,mapid);
}
// TODO: need to switch to SCENESTATE_LOGINSCREEN here, and after everything is loaded, back to SCENESTATE_WORLD
if(GetInstance()->GetScripts()->ScriptExists("_onteleport"))
{
CmdSet Set;

View File

@ -24,8 +24,8 @@ void MapTile::ImportFromADT(ADTFile *adt)
for(uint32 ch=0; ch<CHUNKS_PER_TILE; ch++)
{
_chunks[ch].baseheight = adt->_chunks[ch].hdr.zbase; // ADT files store (x/z) as ground coords and (y) as the height!
_chunks[ch].basex = adt->_chunks[ch].hdr.ybase; // here converting it to (x/y) on ground and basehight as actual height.
_chunks[ch].basey = adt->_chunks[ch].hdr.xbase; // strange coords they use... :S
_chunks[ch].basex = adt->_chunks[ch].hdr.xbase; // here converting it to (x/y) on ground and basehight as actual height.
_chunks[ch].basey = adt->_chunks[ch].hdr.ybase; // strange coords they use... :S
uint32 fcnt=0, rcnt=0;
while(true) //9*9 + 8*8
{
@ -128,3 +128,4 @@ void MapTile::DebugDumpToFile(void)
fprintf(fh, out.c_str());
fclose(fh);
}