diff --git a/README.md b/README.md index 2444399..1b97518 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## Outline -Tortuga is a 2D multiplayer JRPG featuring permadeath, with an emphasis on multiplayer cooperation, exploration and customization. The game runs on customizable public and private servers. +Tortuga is a 2D MMORPG featuring permadeath, with an emphasis on multiplayer cooperation, exploration and customization. The game runs on customizable public and private servers. This game is inspired by classic 2D RPGs (Final Fantasy, The Legend of Zelda), as well as more modern sandboxes amd MMOs (Minecraft, EVE Online). This project is currently independently created and funded, with the goal of creating a game that will engage the players and inspire a large community. diff --git a/client/gameplay_scenes/world_logic.cpp b/client/gameplay_scenes/world_logic.cpp index 4c724fb..c0ff20e 100644 --- a/client/gameplay_scenes/world_logic.cpp +++ b/client/gameplay_scenes/world_logic.cpp @@ -125,8 +125,16 @@ void World::Update() { it.second.Update(); } - //update the map - UpdateMap(); + try { + //update the map + UpdateMap(); + } + catch(terminal_error& e) { + throw(e); + } + catch(std::exception& e) { + std::cerr << "UpdateMap Error: " << e.what() << std::endl; + } //skip the rest without a local character if (!localCharacter) { @@ -162,6 +170,11 @@ void World::Render(SDL_Surface* const screen) { //draw the map for (std::list::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) { tileSheet.DrawRegionTo(screen, &(*it), camera.x, camera.y); + + //debugging +// std::ostringstream msg; +// msg << it->GetX() << ", " << it->GetY(); +// font.DrawStringTo(msg.str(), screen, it->GetX() * tileSheet.GetImage()->GetClipW() - camera.x, it->GetY() * tileSheet.GetImage()->GetClipH() - camera.y); } //draw the entities diff --git a/client/gameplay_scenes/world_map.cpp b/client/gameplay_scenes/world_map.cpp index 592c8e9..1265281 100644 --- a/client/gameplay_scenes/world_map.cpp +++ b/client/gameplay_scenes/world_map.cpp @@ -23,6 +23,24 @@ #include "channels.hpp" +#include + +//------------------------- +//static functions +//------------------------- + +static int regionChecksum(Region* const region) { + int sum = 0; + for(int i = 0; i < REGION_WIDTH; i++) { + for (int j = 0; j < REGION_HEIGHT; j++) { + for (int k = 0; k < REGION_DEPTH; k++) { + sum += region->GetTile(i, j, k); + } + } + } + return sum; +} + //------------------------- //map management //------------------------- @@ -40,6 +58,13 @@ void World::SendRegionRequest(int roomIndex, int x, int y) { } void World::hRegionContent(RegionPacket* const argPacket) { + //checksum + if (regionChecksum(argPacket->region) == 0) { + std::ostringstream msg; + msg << "Received region checksum failed: " << argPacket->x << ", " << argPacket->y; + throw(std::runtime_error(msg.str())); + } + //replace existing regions regionPager.UnloadIf([&](Region const& region) -> bool { return region.GetX() == argPacket->x && region.GetY() == argPacket->y; @@ -71,9 +96,23 @@ void World::UpdateMap() { //request empty regions within this zone for (int i = xStart; i <= xEnd; i += REGION_WIDTH) { for (int j = yStart; j <= yEnd; j += REGION_HEIGHT) { - if (!regionPager.FindRegion(i, j)) { + Region* region = regionPager.FindRegion(i, j); + if (!region) { + //request absent region SendRegionRequest(roomIndex, i, j); } + else if (regionChecksum(region) == 0) { + //checksum failed + //NOTE: this patches bug #45, but does not resolve it + regionPager.UnloadIf([region](Region const& ref) -> bool { + //remove the erroneous region + return region == &ref; + }); + SendRegionRequest(roomIndex, i, j); + std::ostringstream msg; + msg << "Existing region checksum failed: " << roomIndex << ", " << i << ", " << j; + throw(std::runtime_error(msg.str())); + } } } } \ No newline at end of file diff --git a/common/map/region_pager_base.cpp b/common/map/region_pager_base.cpp index 1df6864..857dabd 100644 --- a/common/map/region_pager_base.cpp +++ b/common/map/region_pager_base.cpp @@ -70,6 +70,7 @@ Region* RegionPagerBase::FindRegion(int x, int y) { } Region* RegionPagerBase::PushRegion(Region* const ptr) { + //BUG: #45 Some regions are occasionally losing their tile data regionList.push_front(*ptr); return ®ionList.front(); } diff --git a/rsc/scripts/map_maker.lua b/rsc/scripts/map_maker.lua index dbcc2ec..d2a7f4e 100644 --- a/rsc/scripts/map_maker.lua +++ b/rsc/scripts/map_maker.lua @@ -65,6 +65,9 @@ end --custom generation systems here function mapMaker.DebugIsland(r) + --debug + io.write("map_maker:DebugIsland(", regionAPI.GetX(r), ", ", regionAPI.GetY(r), ")\n") + --basic distance check for each tile, placing an island around the world origin for i = 1, regionAPI.GetWidth(r) do for j = 1, regionAPI.GetHeight(r) do @@ -95,6 +98,9 @@ function mapMaker.DebugIsland(r) end function mapMaker.DebugGrassland(r) + --debug + io.write("map_maker:DebugGrassland(", regionAPI.GetX(r), ", ", regionAPI.GetY(r), ")\n") + --all dirt for i = 1, regionAPI.GetWidth(r) do for j = 1, regionAPI.GetHeight(r) do diff --git a/rsc/scripts/map_saver.lua b/rsc/scripts/map_saver.lua index b28d1bd..2ec8832 100644 --- a/rsc/scripts/map_saver.lua +++ b/rsc/scripts/map_saver.lua @@ -4,11 +4,11 @@ local mapSaver = {} function mapSaver.Load(r) --empty - io.write("map_saver:Load(", region.GetX(r), ", ", region.GetY(r), ")\n") +-- io.write("map_saver:Load(", region.GetX(r), ", ", region.GetY(r), ")\n") end function mapSaver.Save(r) --empty - io.write("map_saver:Save(", region.GetX(r), ", ", region.GetY(r), ")\n") +-- io.write("map_saver:Save(", region.GetX(r), ", ", region.GetY(r), ")\n") end --TODO: (3) create a flexible saving & loading system diff --git a/rsc/scripts/setup_server.lua b/rsc/scripts/setup_server.lua index 02f5059..5c55900 100644 --- a/rsc/scripts/setup_server.lua +++ b/rsc/scripts/setup_server.lua @@ -31,6 +31,6 @@ local underworld, uidTwo = roomManagerAPI.CreateRoom("underworld", "overworld.bm roomAPI.Initialize(underworld, mapSaver.Load, mapSaver.Save, mapMaker.DebugGrassland, mapSaver.Save) --call the monstrosity -doorUtility.createDoorPair("pair 1", overworld, 0, -64, underworld, 0, 0) +doorUtility.createDoorPair("pair 1", overworld, -64, -64, underworld, 64, 64) print("Finished the lua script") diff --git a/server/rooms/room_data.cpp b/server/rooms/room_data.cpp index fd0c7e7..dcb544c 100644 --- a/server/rooms/room_data.cpp +++ b/server/rooms/room_data.cpp @@ -26,6 +26,7 @@ #include #include +//TODO: (9) character collisions should be preformed client-side void RoomData::RunFrame() { //get the hook lua_rawgeti(lua, LUA_REGISTRYINDEX, tickRef);