diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index cc8776c..695b54a 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -55,6 +55,11 @@ InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNet disconnectButton.SetText("Disconnect"); shutDownButton.SetText("Shut Down"); + //setup the map object + mapPager.SetRegionWidth(REGION_WIDTH); + mapPager.SetRegionHeight(REGION_HEIGHT); + mapPager.SetRegionDepth(REGION_DEPTH); + //create the server-side player object NetworkPacket packet; packet.meta.type = NetworkPacket::Type::PLAYER_NEW; @@ -73,6 +78,9 @@ InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNet packet.meta.type = NetworkPacket::Type::SYNCHRONIZE; serialize(&packet, buffer); network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE); + + //debug + mapPager.GetRegion(0, 0); } InWorld::~InWorld() { @@ -90,17 +98,6 @@ void InWorld::FrameStart() { void InWorld::Update(double delta) { NetworkPacket packet; - //update the camera - if(localCharacter) { - int marginX = (GetScreen()->w / 2 - localCharacter->GetSprite()->GetImage()->GetClipW() / 2); - int marginY = (GetScreen()->h / 2 - localCharacter->GetSprite()->GetImage()->GetClipH() / 2); - camera.x = localCharacter->GetPosition().x - marginX; - camera.y = localCharacter->GetPosition().y - marginY; - } - - //check the map - UpdateMap(); - //suck in all waiting packets while(network.Receive()) { deserialize(&packet, network.GetInData()); @@ -108,9 +105,20 @@ void InWorld::Update(double delta) { HandlePacket(packet); } + //update the characters for (auto& it : playerCharacters) { it.second.Update(delta); } + //TODO: sort the players and entities by Y position + + //update the camera + if(localCharacter) { + camera.x = localCharacter->GetPosition().x - camera.marginX; + camera.y = localCharacter->GetPosition().y - camera.marginY; + } + + //check the map + UpdateMap(); } void InWorld::FrameEnd() { @@ -118,9 +126,15 @@ void InWorld::FrameEnd() { } void InWorld::Render(SDL_Surface* const screen) { + //draw the map + //TODO + + //draw characters for (auto& it : playerCharacters) { it.second.DrawTo(screen, camera.x, camera.y); } + + //draw UI disconnectButton.DrawTo(screen); shutDownButton.DrawTo(screen); } @@ -242,6 +256,9 @@ void InWorld::HandlePacket(NetworkPacket packet) { case NetworkPacket::Type::PLAYER_UPDATE: HandlePlayerUpdate(packet); break; + case NetworkPacket::Type::REGION_CONTENT: + HandleRegionContent(packet); + break; //handle errors default: throw(std::runtime_error("Unknown NetworkPacket::Type encountered")); @@ -269,6 +286,9 @@ void InWorld::HandlePlayerNew(NetworkPacket packet) { if (packet.playerInfo.clientIndex == clientIndex && !localCharacter) { playerIndex = packet.playerInfo.playerIndex; localCharacter = &playerCharacters[playerIndex]; + //center on the player's character + camera.marginX = (GetScreen()->w / 2 - localCharacter->GetSprite()->GetImage()->GetClipW() / 2); + camera.marginY = (GetScreen()->h / 2 - localCharacter->GetSprite()->GetImage()->GetClipH() / 2); } } @@ -300,6 +320,15 @@ void InWorld::HandlePlayerUpdate(NetworkPacket packet) { playerCharacters[packet.playerInfo.playerIndex].ResetDirection(); } +void InWorld::HandleRegionContent(NetworkPacket packet) { + //replace existing regions + if (mapPager.FindRegion(packet.regionInfo.x, packet.regionInfo.y)) { + mapPager.UnloadRegion(packet.regionInfo.x, packet.regionInfo.y); + } + mapPager.PushRegion(packet.regionInfo.region); + packet.regionInfo.region = nullptr; +} + //------------------------- //Server control //------------------------- @@ -348,5 +377,16 @@ void InWorld::UpdateMap() { } void InWorld::RequestRegion(int x, int y) { - // + NetworkPacket packet; + char buffer[PACKET_BUFFER_SIZE]; + + //pack the region's data + packet.meta.type = NetworkPacket::Type::REGION_REQUEST; + packet.regionInfo.width = mapPager.GetRegionWidth(); + packet.regionInfo.height = mapPager.GetRegionHeight(); + packet.regionInfo.depth = mapPager.GetRegionDepth(); + packet.regionInfo.x = x; + packet.regionInfo.y = y; + serialize(&packet, buffer); + network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE); } \ No newline at end of file diff --git a/client/scenes/in_world.hpp b/client/scenes/in_world.hpp index b50850c..c1cd032 100644 --- a/client/scenes/in_world.hpp +++ b/client/scenes/in_world.hpp @@ -74,6 +74,7 @@ protected: void HandlePlayerNew(NetworkPacket); void HandlePlayerDelete(NetworkPacket); void HandlePlayerUpdate(NetworkPacket); + void HandleRegionContent(NetworkPacket); //Server control void SendState(); @@ -99,6 +100,7 @@ protected: Button shutDownButton; struct { int x = 0, y = 0; + int marginX = 0, marginY = 0; } camera; //game diff --git a/common/map/map_file_format.cpp b/common/map/map_file_format.cpp index 879d14e..cc9aa7f 100644 --- a/common/map/map_file_format.cpp +++ b/common/map/map_file_format.cpp @@ -24,11 +24,11 @@ #include void DummyFormat::Load(Region** const ptr, int width, int height, int depth, int x, int y) { - //TODO + //EMPTY } void DummyFormat::Save(Region* const ptr) { - //TODO + //EMPTY } /* void VerboseFormat::Load(Region** const ptr, int x, int y) { diff --git a/common/map/region.cpp b/common/map/region.cpp index 8dd701b..e47100c 100644 --- a/common/map/region.cpp +++ b/common/map/region.cpp @@ -21,6 +21,12 @@ */ #include "region.hpp" +#include +#include + +//decorator +#define TRY(x) try { x } catch(std::exception& e) { throw std::runtime_error(std::string() + e.what() + ": " + #x); } + Region::Region(int argWidth, int argHeight, int argDepth, int argX, int argY): width(argWidth), height(argHeight), @@ -28,11 +34,11 @@ Region::Region(int argWidth, int argHeight, int argDepth, int argX, int argY): x(argX), y(argY) { - tiles = new type_t**[width]; + TRY(tiles = new type_t**[width];) for (register int i = 0; i < width; ++i) { - tiles[i] = new type_t*[height]; + TRY(tiles[i] = new type_t*[height];) for (register int j = 0; j < height; ++j) { - tiles[i][j] = new type_t[depth]; + TRY(tiles[i][j] = new type_t[depth];) for (register int k = 0; k < depth; ++k) { tiles[i][j][k] = 0; } diff --git a/common/map/region_pager.cpp b/common/map/region_pager.cpp index bbef22d..9589b3c 100644 --- a/common/map/region_pager.cpp +++ b/common/map/region_pager.cpp @@ -23,6 +23,11 @@ #include "utility.hpp" +#include +#include + +using namespace std; + RegionPagerBase::RegionPagerBase(int argWidth, int argHeight, int argDepth): regionWidth(argWidth), regionHeight(argHeight), @@ -50,15 +55,46 @@ Region* RegionPagerBase::GetRegion(int x, int y) { x = snapToBase(regionWidth, x); y = snapToBase(regionHeight, y); + //get the region by various means + + //TODO: revert this try/catch point + Region* ptr = nullptr; + try { + ptr = FindRegion(x, y); + if (ptr) return ptr; + } + catch(exception& e) { + cerr << "FindRegion Error: " << e.what() << endl; + } + + try { + ptr = LoadRegion(x, y); + if (ptr) return ptr; + } + catch(exception& e) { + cerr << "LoadRegion Error: " << e.what() << endl; + } + + try { + return CreateRegion(x, y); + } + catch(exception& e) { + cerr << "CreateRegion Error: " << e.what() << endl; + } + return nullptr; +} + +Region* RegionPagerBase::FindRegion(int x, int y) { //find the region for (std::list::iterator it = regionList.begin(); it != regionList.end(); it++) { if ((*it)->GetX() == x && (*it)->GetY() == y) { return *it; } } - - //get the region by other means - Region* ptr = LoadRegion(x, y); - if (ptr) return ptr; - return CreateRegion(x, y); + return nullptr; } + +Region* RegionPagerBase::PushRegion(Region* ptr) { + regionList.push_front(ptr); + return regionList.front(); +} \ No newline at end of file diff --git a/common/map/region_pager.hpp b/common/map/region_pager.hpp index 016cab9..da07cea 100644 --- a/common/map/region_pager.hpp +++ b/common/map/region_pager.hpp @@ -33,18 +33,23 @@ public: RegionPagerBase(int regionWidth, int regionHeight, int regionDepth); virtual ~RegionPagerBase(); + //tile manipulation Region::type_t SetTile(int x, int y, int z, Region::type_t v); Region::type_t GetTile(int x, int y, int z); + //region manipulation Region* GetRegion(int x, int y); + Region* FindRegion(int x, int y); + Region* PushRegion(Region*); //interface virtual Region* LoadRegion(int x, int y) = 0; virtual Region* SaveRegion(int x, int y) = 0; virtual Region* CreateRegion(int x, int y) = 0; virtual void UnloadRegion(int x, int y) = 0; + //TODO: delete? - //accessors + //accessors & mutators //NOTE: don't change the sizes mid-program, it will cause issues int SetRegionWidth(int i) { return regionWidth = i; } int SetRegionHeight(int i) { return regionHeight = i; } diff --git a/server/server_application.cpp b/server/server_application.cpp index 9466ce8..3532a63 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -114,7 +114,7 @@ void ServerApplication::Init(int argc, char** argv) { cout << "Startup completed successfully" << endl; //debugging - // + mapPager.GetRegion(0, 0); } void ServerApplication::Loop() {