Merge branch 'map-redo' into client-fix (read more)
This merge splits RegionPager into two parts: RegionPagerBase, with the basic Region management code, and RegionPagerLua, which has lua hooks. The former is used by the client while the latter is used by the server. Both classes' internals have been optimized. There are also changes to the client and server code, to account for the new system, and I've fixed a couple of bugs. The player's character is not created, but the client can login and see the map.
This commit is contained in:
+10
-7
@@ -128,9 +128,9 @@ void InWorld::RenderFrame() {
|
||||
}
|
||||
|
||||
void InWorld::Render(SDL_Surface* const screen) {
|
||||
//draw the map
|
||||
for (auto it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) {
|
||||
tileSheet.DrawRegionTo(screen, *it, camera.x, camera.y);
|
||||
//draw the map0
|
||||
for (std::list<Region>::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) {
|
||||
tileSheet.DrawRegionTo(screen, &(*it), camera.x, camera.y);
|
||||
}
|
||||
|
||||
//draw characters
|
||||
@@ -343,6 +343,9 @@ void InWorld::HandleRegionContent(RegionPacket* const argPacket) {
|
||||
//replace existing regions
|
||||
regionPager.UnloadRegion(argPacket->x, argPacket->y);
|
||||
regionPager.PushRegion(argPacket->region);
|
||||
|
||||
//clean up after the serial code
|
||||
delete argPacket->region;
|
||||
argPacket->region = nullptr;
|
||||
}
|
||||
|
||||
@@ -431,13 +434,13 @@ void InWorld::UpdateMap() {
|
||||
int yEnd = snapToBase(REGION_HEIGHT, (camera.y+camera.height)/tileSheet.GetTileH()) + REGION_HEIGHT;
|
||||
|
||||
//prune distant regions
|
||||
for (auto it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); /* EMPTY */) {
|
||||
for (std::list<Region>::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); /* EMPTY */) {
|
||||
//check if the region is outside off this area
|
||||
if ((*it)->GetX() < xStart || (*it)->GetX() > xEnd || (*it)->GetY() < yStart || (*it)->GetY() > yEnd) {
|
||||
if (it->GetX() < xStart || it->GetX() > xEnd || it->GetY() < yStart || it->GetY() > yEnd) {
|
||||
|
||||
//clunky, but the alternative was time consuming
|
||||
int tmpX = (*it)->GetX();
|
||||
int tmpY = (*it)->GetY();
|
||||
int tmpX = it->GetX();
|
||||
int tmpY = it->GetY();
|
||||
++it;
|
||||
|
||||
regionPager.UnloadRegion(tmpX, tmpY);
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@
|
||||
#define INWORLD_HPP_
|
||||
|
||||
//maps
|
||||
#include "region_pager.hpp"
|
||||
#include "region_pager_base.hpp"
|
||||
|
||||
//networking
|
||||
#include "udp_network_utility.hpp"
|
||||
@@ -110,7 +110,7 @@ protected:
|
||||
TileSheet tileSheet;
|
||||
|
||||
//map
|
||||
RegionPager regionPager;
|
||||
RegionPagerBase regionPager;
|
||||
|
||||
//UI
|
||||
Button disconnectButton;
|
||||
|
||||
+10
-10
@@ -21,42 +21,42 @@
|
||||
*/
|
||||
#include "pager_api.hpp"
|
||||
|
||||
#include "region_pager.hpp"
|
||||
#include "region_pager_lua.hpp"
|
||||
#include "region.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
static int setTile(lua_State* L) {
|
||||
RegionPager* pager = reinterpret_cast<RegionPager*>(lua_touserdata(L, 1));
|
||||
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
|
||||
int ret = pager->SetTile(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5));
|
||||
lua_pushinteger(L, ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int getTile(lua_State* L) {
|
||||
RegionPager* pager = reinterpret_cast<RegionPager*>(lua_touserdata(L, 1));
|
||||
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
|
||||
int ret = pager->GetTile(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4));
|
||||
lua_pushinteger(L, ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int getRegion(lua_State* L) {
|
||||
RegionPager* pager = reinterpret_cast<RegionPager*>(lua_touserdata(L, 1));
|
||||
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
|
||||
Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3));
|
||||
lua_pushlightuserdata(L, region);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int setDirectory(lua_State* L) {
|
||||
RegionPager* pager = reinterpret_cast<RegionPager*>(lua_touserdata(L, 1));
|
||||
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
|
||||
std::string s = pager->SetDirectory(lua_tostring(L, 2));
|
||||
lua_pushstring(L, s.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int getDirectory(lua_State* L) {
|
||||
RegionPager* pager = reinterpret_cast<RegionPager*>(lua_touserdata(L, 1));
|
||||
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
|
||||
std::string s = pager->GetDirectory();
|
||||
lua_pushstring(L, s.c_str());
|
||||
return 1;
|
||||
@@ -64,7 +64,7 @@ static int getDirectory(lua_State* L) {
|
||||
|
||||
static int loadRegion(lua_State* L) {
|
||||
//get the parameters
|
||||
RegionPager* pager = reinterpret_cast<RegionPager*>(lua_touserdata(L, 1));
|
||||
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
|
||||
Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3));
|
||||
std::string s = pager->GetDirectory();
|
||||
|
||||
@@ -83,7 +83,7 @@ static int loadRegion(lua_State* L) {
|
||||
|
||||
static int saveRegion(lua_State* L) {
|
||||
//get the parameters
|
||||
RegionPager* pager = reinterpret_cast<RegionPager*>(lua_touserdata(L, 1));
|
||||
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
|
||||
Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3));
|
||||
std::string s = pager->GetDirectory();
|
||||
|
||||
@@ -102,7 +102,7 @@ static int saveRegion(lua_State* L) {
|
||||
|
||||
static int createRegion(lua_State* L) {
|
||||
//get the parameters
|
||||
RegionPager* pager = reinterpret_cast<RegionPager*>(lua_touserdata(L, 1));
|
||||
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
|
||||
Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3));
|
||||
|
||||
//push the parameters
|
||||
@@ -120,7 +120,7 @@ static int createRegion(lua_State* L) {
|
||||
|
||||
static int unloadRegion(lua_State* L) {
|
||||
//get the parameters
|
||||
RegionPager* pager = reinterpret_cast<RegionPager*>(lua_touserdata(L, 1));
|
||||
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
|
||||
Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3));
|
||||
std::string s = pager->GetDirectory();
|
||||
|
||||
|
||||
+13
-6
@@ -21,13 +21,20 @@
|
||||
*/
|
||||
#include "region.hpp"
|
||||
|
||||
Region::Region(int argX, int argY):
|
||||
x(argX),
|
||||
y(argY)
|
||||
{
|
||||
for (register int i = 0; i < REGION_WIDTH*REGION_HEIGHT*REGION_DEPTH; ++i) {
|
||||
*(reinterpret_cast<type_t*>(tiles) + i) = 0;
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <cstring>
|
||||
|
||||
Region::Region(int argX, int argY): x(argX), y(argY) {
|
||||
if (x != snapToBase(REGION_WIDTH, x) || y != snapToBase(REGION_HEIGHT, y)) {
|
||||
throw(std::invalid_argument("Region location is off grid"));
|
||||
}
|
||||
memset(tiles, 0, REGION_WIDTH*REGION_HEIGHT*REGION_DEPTH*sizeof(type_t));
|
||||
}
|
||||
|
||||
Region::Region(Region const& rhs): x(rhs.x), y(rhs.y) {
|
||||
memcpy(tiles, rhs.tiles, REGION_WIDTH*REGION_HEIGHT*REGION_DEPTH*sizeof(type_t));
|
||||
}
|
||||
|
||||
Region::type_t Region::SetTile(int x, int y, int z, type_t v) {
|
||||
|
||||
@@ -32,6 +32,7 @@ public:
|
||||
|
||||
Region() = delete;
|
||||
Region(int x, int y);
|
||||
Region(Region const&);
|
||||
~Region() = default;
|
||||
|
||||
type_t SetTile(int x, int y, int z, type_t v);
|
||||
|
||||
@@ -1,205 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2014
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#include "region_pager.hpp"
|
||||
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
Region::type_t RegionPager::SetTile(int x, int y, int z, Region::type_t v) {
|
||||
Region* ptr = GetRegion(x, y);
|
||||
return ptr->SetTile(x - ptr->GetX(), y - ptr->GetY(), z, v);
|
||||
}
|
||||
|
||||
Region::type_t RegionPager::GetTile(int x, int y, int z) {
|
||||
Region* ptr = GetRegion(x, y);
|
||||
return ptr->GetTile(x - ptr->GetX(), y - ptr->GetY(), z);
|
||||
}
|
||||
|
||||
Region* RegionPager::GetRegion(int x, int y) {
|
||||
//snap the coords
|
||||
x = snapToBase(REGION_WIDTH, x);
|
||||
y = snapToBase(REGION_HEIGHT, y);
|
||||
|
||||
//get the region by various means
|
||||
Region* ptr = nullptr;
|
||||
ptr = FindRegion(x, y);
|
||||
if (ptr) return ptr;
|
||||
ptr = LoadRegion(x, y);
|
||||
if (ptr) return ptr;
|
||||
return CreateRegion(x, y);
|
||||
}
|
||||
|
||||
Region* RegionPager::FindRegion(int x, int y) {
|
||||
//snap the coords
|
||||
x = snapToBase(REGION_WIDTH, x);
|
||||
y = snapToBase(REGION_HEIGHT, y);
|
||||
|
||||
//find the region
|
||||
for (std::list<Region*>::iterator it = regionList.begin(); it != regionList.end(); it++) {
|
||||
if ((*it)->GetX() == x && (*it)->GetY() == y) {
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Region* RegionPager::PushRegion(Region* const region) {
|
||||
if (
|
||||
region->GetX() != snapToBase(REGION_WIDTH, region->GetX()) ||
|
||||
region->GetY() != snapToBase(REGION_HEIGHT, region->GetY())
|
||||
)
|
||||
{
|
||||
throw(std::runtime_error("Pushed region does not conform to the region grid"));
|
||||
}
|
||||
|
||||
regionList.push_front(region);
|
||||
return regionList.front();
|
||||
}
|
||||
|
||||
Region* RegionPager::LoadRegion(int x, int y) {
|
||||
//only work if using lua
|
||||
if (!luaState) {
|
||||
throw(std::runtime_error("RegionPager::luaState is null"));
|
||||
}
|
||||
|
||||
//load the region if possible
|
||||
|
||||
//snap the coords
|
||||
x = snapToBase(REGION_WIDTH, x);
|
||||
y = snapToBase(REGION_HEIGHT, y);
|
||||
|
||||
//overwrite?
|
||||
Region* ptr = FindRegion(x, y);
|
||||
if (!ptr) {
|
||||
ptr = new Region(x, y);
|
||||
}
|
||||
|
||||
//API hook
|
||||
lua_getglobal(luaState, "region");
|
||||
lua_getfield(luaState, -1, "load");
|
||||
lua_pushlightuserdata(luaState, ptr);
|
||||
lua_pushstring(luaState, directory.c_str());
|
||||
if (lua_pcall(luaState, 2, 1, 0) != LUA_OK) {
|
||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) ));
|
||||
}
|
||||
if (lua_toboolean(luaState, -1)) {
|
||||
regionList.push_front(ptr);
|
||||
}
|
||||
else {
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
}
|
||||
lua_pop(luaState, 2);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
Region* RegionPager::SaveRegion(int x, int y) {
|
||||
//only work if using lua
|
||||
if (!luaState) {
|
||||
throw(std::runtime_error("RegionPager::luaState is null"));
|
||||
}
|
||||
|
||||
//snap the coords
|
||||
x = snapToBase(REGION_WIDTH, x);
|
||||
y = snapToBase(REGION_HEIGHT, y);
|
||||
|
||||
//find & save the region
|
||||
Region* ptr = FindRegion(x, y);
|
||||
if (ptr) {
|
||||
//API hook
|
||||
lua_getglobal(luaState, "region");
|
||||
lua_getfield(luaState, -1, "save");
|
||||
lua_pushlightuserdata(luaState, ptr);
|
||||
lua_pushstring(luaState, directory.c_str());
|
||||
if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) {
|
||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) ));
|
||||
}
|
||||
lua_pop(luaState, 1);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
Region* RegionPager::CreateRegion(int x, int y) {
|
||||
//only work if using lua
|
||||
if (!luaState) {
|
||||
throw(std::runtime_error("RegionPager::luaState is null"));
|
||||
}
|
||||
|
||||
//snap the coords
|
||||
x = snapToBase(REGION_WIDTH, x);
|
||||
y = snapToBase(REGION_HEIGHT, y);
|
||||
|
||||
//overwrite?
|
||||
Region* ptr = FindRegion(x, y);
|
||||
if (!ptr) {
|
||||
ptr = new Region(x, y);
|
||||
}
|
||||
|
||||
//API hook
|
||||
lua_getglobal(luaState, "region");
|
||||
lua_getfield(luaState, -1, "create");
|
||||
lua_pushlightuserdata(luaState, ptr);
|
||||
//TODO: parameters
|
||||
if (lua_pcall(luaState, 1, 0, 0) != LUA_OK) {
|
||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) ));
|
||||
}
|
||||
lua_pop(luaState, 1);
|
||||
|
||||
regionList.push_front(ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void RegionPager::UnloadRegion(int x, int y) {
|
||||
//only work if using lua
|
||||
if (!luaState) {
|
||||
throw(std::runtime_error("RegionPager::luaState is null"));
|
||||
}
|
||||
|
||||
//snap the coords
|
||||
x = snapToBase(REGION_WIDTH, x);
|
||||
y = snapToBase(REGION_HEIGHT, y);
|
||||
|
||||
lua_getglobal(luaState, "region");
|
||||
|
||||
//custom loop, not FindRegion()
|
||||
for (std::list<Region*>::iterator it = regionList.begin(); it != regionList.end(); /* EMPTY */) {
|
||||
if ((*it)->GetX() == x && (*it)->GetY() == y) {
|
||||
|
||||
//API hook
|
||||
lua_getfield(luaState, -1, "unload");
|
||||
lua_pushlightuserdata(luaState, *it);
|
||||
lua_pushstring(luaState, directory.c_str());
|
||||
if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) {
|
||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) ));
|
||||
}
|
||||
|
||||
delete (*it);
|
||||
it = regionList.erase(it);
|
||||
continue;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
lua_pop(luaState, 1);
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/* Copyright: (c) Kayne Ruse 2014
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#include "region_pager_base.hpp"
|
||||
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
Region::type_t RegionPagerBase::SetTile(int x, int y, int z, Region::type_t v) {
|
||||
Region* ptr = GetRegion(x, y);
|
||||
return ptr->SetTile(x - ptr->GetX(), y - ptr->GetY(), z, v);
|
||||
}
|
||||
|
||||
Region::type_t RegionPagerBase::GetTile(int x, int y, int z) {
|
||||
Region* ptr = GetRegion(x, y);
|
||||
return ptr->GetTile(x - ptr->GetX(), y - ptr->GetY(), z);
|
||||
}
|
||||
|
||||
Region* RegionPagerBase::GetRegion(int x, int y) {
|
||||
//get the region by various means
|
||||
Region* ptr = nullptr;
|
||||
ptr = FindRegion(x, y);
|
||||
if (ptr) return ptr;
|
||||
ptr = LoadRegion(x, y);
|
||||
if (ptr) return ptr;
|
||||
return CreateRegion(x, y);
|
||||
}
|
||||
|
||||
Region* RegionPagerBase::FindRegion(int x, int y) {
|
||||
//find the region
|
||||
std::list<Region>::iterator it = find_if(regionList.begin(), regionList.end(), [x, y](Region& region) -> bool {
|
||||
return region.GetX() == x && region.GetY() == y;
|
||||
});
|
||||
return it != regionList.end() ? &(*it) : nullptr;
|
||||
}
|
||||
|
||||
Region* RegionPagerBase::PushRegion(Region* const ptr) {
|
||||
regionList.push_front(*ptr);
|
||||
return ®ionList.front();
|
||||
}
|
||||
|
||||
Region* RegionPagerBase::LoadRegion(int x, int y) {
|
||||
//TODO: load the region if possible
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Region* RegionPagerBase::SaveRegion(int x, int y) {
|
||||
//TODO: find & save the region
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Region* RegionPagerBase::CreateRegion(int x, int y) {
|
||||
if (FindRegion(x, y)) {
|
||||
throw(std::logic_error("Cannot overwrite an existing region"));
|
||||
}
|
||||
regionList.emplace_front(x, y);
|
||||
return ®ionList.front();
|
||||
}
|
||||
|
||||
void RegionPagerBase::UnloadRegion(int x, int y) {
|
||||
//custom loop, not FindRegion()
|
||||
regionList.remove_if([x, y](Region& region) -> bool { return region.GetX() == x && region.GetY() == y; });
|
||||
}
|
||||
|
||||
void RegionPagerBase::UnloadAll() {
|
||||
regionList.clear();
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/* Copyright: (c) Kayne Ruse 2014
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#ifndef REGIONPAGERBASE_HPP_
|
||||
#define REGIONPAGERBASE_HPP_
|
||||
|
||||
#include "region.hpp"
|
||||
|
||||
#include <list>
|
||||
|
||||
class RegionPagerBase {
|
||||
public:
|
||||
RegionPagerBase() = default;
|
||||
virtual ~RegionPagerBase() { UnloadAll(); };
|
||||
|
||||
//tile manipulation
|
||||
virtual Region::type_t SetTile(int x, int y, int z, Region::type_t v);
|
||||
virtual Region::type_t GetTile(int x, int y, int z);
|
||||
|
||||
//region manipulation
|
||||
virtual Region* GetRegion(int x, int y);
|
||||
virtual Region* FindRegion(int x, int y);
|
||||
virtual Region* PushRegion(Region* const);
|
||||
|
||||
virtual Region* LoadRegion(int x, int y);
|
||||
virtual Region* SaveRegion(int x, int y);
|
||||
virtual Region* CreateRegion(int x, int y);
|
||||
virtual void UnloadRegion(int x, int y);
|
||||
|
||||
virtual void UnloadAll();
|
||||
|
||||
//accessors & mutators
|
||||
std::list<Region>* GetContainer() { return ®ionList; }
|
||||
protected:
|
||||
std::list<Region> regionList;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,126 @@
|
||||
/* Copyright: (c) Kayne Ruse 2014
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#include "region_pager_lua.hpp"
|
||||
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
Region* RegionPagerLua::LoadRegion(int x, int y) {
|
||||
//load the region if possible
|
||||
|
||||
//something to work on
|
||||
regionList.emplace_front(x, y);
|
||||
|
||||
//API hook
|
||||
lua_getglobal(luaState, "region");
|
||||
lua_getfield(luaState, -1, "load");
|
||||
lua_pushlightuserdata(luaState, ®ionList.front());
|
||||
lua_pushstring(luaState, directory.c_str());
|
||||
if (lua_pcall(luaState, 2, 1, 0) != LUA_OK) {
|
||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) ));
|
||||
}
|
||||
//success or failure
|
||||
if (!lua_toboolean(luaState, -1)) {
|
||||
lua_pop(luaState, 2);
|
||||
regionList.pop_front();
|
||||
return nullptr;
|
||||
}
|
||||
lua_pop(luaState, 2);
|
||||
return ®ionList.front();
|
||||
}
|
||||
|
||||
Region* RegionPagerLua::SaveRegion(int x, int y) {
|
||||
//find & save the region
|
||||
Region* ptr = FindRegion(x, y);
|
||||
if (ptr) {
|
||||
//API hook
|
||||
lua_getglobal(luaState, "region");
|
||||
lua_getfield(luaState, -1, "save");
|
||||
lua_pushlightuserdata(luaState, ptr);
|
||||
lua_pushstring(luaState, directory.c_str());
|
||||
if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) {
|
||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) ));
|
||||
}
|
||||
lua_pop(luaState, 1);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
Region* RegionPagerLua::CreateRegion(int x, int y) {
|
||||
if (FindRegion(x, y)) {
|
||||
throw(std::logic_error("Cannot overwrite an existing region"));
|
||||
}
|
||||
|
||||
//something to work on
|
||||
regionList.emplace_front(x, y);
|
||||
|
||||
//API hook
|
||||
lua_getglobal(luaState, "region");
|
||||
lua_getfield(luaState, -1, "create");
|
||||
lua_pushlightuserdata(luaState, ®ionList.front());
|
||||
//TODO: parameters
|
||||
if (lua_pcall(luaState, 1, 0, 0) != LUA_OK) {
|
||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) ));
|
||||
}
|
||||
lua_pop(luaState, 1);
|
||||
return ®ionList.front();;
|
||||
}
|
||||
|
||||
void RegionPagerLua::UnloadRegion(int x, int y) {
|
||||
lua_getglobal(luaState, "region");
|
||||
|
||||
regionList.remove_if([&](Region& region) -> bool {
|
||||
if (region.GetX() == x && region.GetY() == y) {
|
||||
|
||||
//API hook
|
||||
lua_getfield(luaState, -1, "unload");
|
||||
lua_pushlightuserdata(luaState, ®ion);
|
||||
lua_pushstring(luaState, directory.c_str());
|
||||
if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) {
|
||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) ));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
lua_pop(luaState, 1);
|
||||
}
|
||||
|
||||
void RegionPagerLua::UnloadAll() {
|
||||
lua_getglobal(luaState, "region");
|
||||
|
||||
for (auto& it : regionList) {
|
||||
//API hook
|
||||
lua_getfield(luaState, -1, "unload");
|
||||
lua_pushlightuserdata(luaState, &it);
|
||||
lua_pushstring(luaState, directory.c_str());
|
||||
if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) {
|
||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) ));
|
||||
}
|
||||
}
|
||||
|
||||
lua_pop(luaState, 1);
|
||||
regionList.clear();
|
||||
}
|
||||
@@ -19,47 +19,34 @@
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#ifndef REGIONPAGER_HPP_
|
||||
#define REGIONPAGER_HPP_
|
||||
#ifndef REGIONPAGERLUA_HPP_
|
||||
#define REGIONPAGERLUA_HPP_
|
||||
|
||||
#include "region.hpp"
|
||||
#include "region_pager_base.hpp"
|
||||
|
||||
#include "lua/lua.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
//TODO: split this into two: "RegionPagerBase" and "RegionPagerLua"
|
||||
class RegionPager {
|
||||
class RegionPagerLua : public RegionPagerBase {
|
||||
public:
|
||||
RegionPager() = default;
|
||||
~RegionPager() = default;
|
||||
|
||||
//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);
|
||||
RegionPagerLua() = default;
|
||||
~RegionPagerLua() = default;
|
||||
|
||||
//region manipulation
|
||||
Region* GetRegion(int x, int y);
|
||||
Region* FindRegion(int x, int y);
|
||||
Region* PushRegion(Region* const);
|
||||
Region* LoadRegion(int x, int y) override;
|
||||
Region* SaveRegion(int x, int y) override;
|
||||
Region* CreateRegion(int x, int y) override;
|
||||
void UnloadRegion(int x, int y) override;
|
||||
|
||||
Region* LoadRegion(int x, int y);
|
||||
Region* SaveRegion(int x, int y);
|
||||
Region* CreateRegion(int x, int y);
|
||||
void UnloadRegion(int x, int y);
|
||||
|
||||
//accessors & mutators
|
||||
std::list<Region*>* GetContainer() { return ®ionList; }
|
||||
void UnloadAll() override;
|
||||
|
||||
std::string SetDirectory(std::string s) { return directory = s; }
|
||||
std::string GetDirectory() { return directory; }
|
||||
|
||||
lua_State* SetLuaState(lua_State* L) { return luaState = L; }
|
||||
lua_State* GetLuaState() { return luaState; }
|
||||
|
||||
private:
|
||||
std::list<Region*> regionList;
|
||||
protected:
|
||||
std::string directory;
|
||||
lua_State* luaState = nullptr;
|
||||
};
|
||||
@@ -36,16 +36,6 @@ static const char* DELETE_USER_ACCOUNT = "DELETE FROM Accounts WHERE uid = ?;";
|
||||
//Define the public methods
|
||||
//-------------------------
|
||||
|
||||
AccountManager::AccountManager() {
|
||||
//
|
||||
}
|
||||
|
||||
AccountManager::~AccountManager() {
|
||||
for (auto& it : accountMap) {
|
||||
SaveAccount(it.first);
|
||||
}
|
||||
}
|
||||
|
||||
int AccountManager::CreateAccount(std::string username, int clientIndex) {
|
||||
//create this user account, failing if it exists, leave this account in memory
|
||||
sqlite3_stmt* statement = nullptr;
|
||||
@@ -202,6 +192,13 @@ void AccountManager::DeleteAccount(int uid) {
|
||||
accountMap.erase(uid);
|
||||
}
|
||||
|
||||
void AccountManager::UnloadAll() {
|
||||
for (auto& it : accountMap) {
|
||||
SaveAccount(it.first);
|
||||
}
|
||||
accountMap.clear();
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Define the accessors and mutators
|
||||
//-------------------------
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
|
||||
class AccountManager {
|
||||
public:
|
||||
AccountManager();
|
||||
~AccountManager();
|
||||
AccountManager() = default;
|
||||
~AccountManager() { UnloadAll(); };
|
||||
|
||||
//public access methods
|
||||
int CreateAccount(std::string username, int clientIndex);
|
||||
@@ -40,6 +40,8 @@ public:
|
||||
void UnloadAccount(int uid);
|
||||
void DeleteAccount(int uid);
|
||||
|
||||
void UnloadAll();
|
||||
|
||||
//accessors and mutators
|
||||
AccountData* GetAccount(int uid);
|
||||
std::map<int, AccountData>* GetContainer();
|
||||
|
||||
@@ -58,16 +58,6 @@ static const char* DELETE_CHARACTER = "DELETE FROM Characters WHERE uid = ?;";
|
||||
//Define the methods
|
||||
//-------------------------
|
||||
|
||||
CharacterManager::CharacterManager() {
|
||||
//
|
||||
}
|
||||
|
||||
CharacterManager::~CharacterManager() {
|
||||
for (auto& it : characterMap) {
|
||||
SaveCharacter(it.first);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: default stats as a parameter? This would be good for differing beggining states or multiple classes
|
||||
int CharacterManager::CreateCharacter(int owner, std::string handle, std::string avatar) {
|
||||
//Create the character, failing if it exists
|
||||
@@ -294,6 +284,13 @@ void CharacterManager::UnloadCharacterIf(std::function<bool(std::map<int, Charac
|
||||
}
|
||||
}
|
||||
|
||||
void CharacterManager::UnloadAll() {
|
||||
for (auto& it : characterMap) {
|
||||
SaveCharacter(it.first);
|
||||
}
|
||||
characterMap.clear();
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Define the accessors and mutators
|
||||
//-------------------------
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
|
||||
class CharacterManager {
|
||||
public:
|
||||
CharacterManager();
|
||||
~CharacterManager();
|
||||
CharacterManager() = default;
|
||||
~CharacterManager() { UnloadAll(); };
|
||||
|
||||
//public access methods
|
||||
int CreateCharacter(int owner, std::string handle, std::string avatar);
|
||||
@@ -43,6 +43,8 @@ public:
|
||||
|
||||
void UnloadCharacterIf(std::function<bool(std::map<int, CharacterData>::iterator)> f);
|
||||
|
||||
void UnloadAll();
|
||||
|
||||
//accessors and mutators
|
||||
CharacterData* GetCharacter(int uid);
|
||||
std::map<int, CharacterData>* GetContainer();
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#define ROOMDATA_HPP_
|
||||
|
||||
//map system
|
||||
#include "region_pager.hpp"
|
||||
#include "region_pager_lua.hpp"
|
||||
|
||||
struct RoomData {
|
||||
enum class RoomType {
|
||||
@@ -35,7 +35,7 @@ struct RoomData {
|
||||
};
|
||||
|
||||
//members
|
||||
RegionPager pager;
|
||||
RegionPagerLua pager;
|
||||
RoomType type;
|
||||
|
||||
//TODO: collision map
|
||||
|
||||
@@ -151,6 +151,14 @@ void ServerApplication::Proc() {
|
||||
void ServerApplication::Quit() {
|
||||
std::cout << "Shutting down" << std::endl;
|
||||
|
||||
//close the managers
|
||||
clientMap.clear();
|
||||
accountMgr.UnloadAll();
|
||||
characterMgr.UnloadAll();
|
||||
//TODO: unload combats
|
||||
//TODO: unload enemies
|
||||
//TODO: unload rooms
|
||||
|
||||
//APIs
|
||||
lua_close(luaState);
|
||||
sqlite3_close_v2(database);
|
||||
|
||||
Reference in New Issue
Block a user