diff --git a/src/Client/GUI/DrawObject.cpp b/src/Client/GUI/DrawObject.cpp index 3cab2a8..d6dcc47 100644 --- a/src/Client/GUI/DrawObject.cpp +++ b/src/Client/GUI/DrawObject.cpp @@ -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); diff --git a/src/Client/GUI/PseuGUI.h b/src/Client/GUI/PseuGUI.h index 133b07b..d1ce51c 100644 --- a/src/Client/GUI/PseuGUI.h +++ b/src/Client/GUI/PseuGUI.h @@ -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 diff --git a/src/Client/GUI/Scene.h b/src/Client/GUI/Scene.h index 7d2274d..cb5ca7c 100644 --- a/src/Client/GUI/Scene.h +++ b/src/Client/GUI/Scene.h @@ -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; diff --git a/src/Client/GUI/SceneWorld.cpp b/src/Client/GUI/SceneWorld.cpp index dcb7c60..87a3f3b 100644 --- a/src/Client/GUI/SceneWorld.cpp +++ b/src/Client/GUI/SceneWorld.cpp @@ -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 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); diff --git a/src/Client/World/MapMgr.cpp b/src/Client/World/MapMgr.cpp index 226c6f9..5fbe90f 100644 --- a/src/Client/World/MapMgr.cpp +++ b/src/Client/World/MapMgr.cpp @@ -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) diff --git a/src/Client/World/WorldSession.cpp b/src/Client/World/WorldSession.cpp index 4c8a8f5..a6b3e04 100644 --- a/src/Client/World/WorldSession.cpp +++ b/src/Client/World/WorldSession.cpp @@ -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; diff --git a/src/shared/MapTile.cpp b/src/shared/MapTile.cpp index 79de907..479ecd5 100644 --- a/src/shared/MapTile.cpp +++ b/src/shared/MapTile.cpp @@ -24,8 +24,8 @@ void MapTile::ImportFromADT(ADTFile *adt) for(uint32 ch=0; ch_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); } +