diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index 7dff310..19caef0 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -501,7 +501,9 @@ void InWorld::SendRegionRequest(int roomIndex, int x, int y) { void InWorld::HandleRegionContent(RegionPacket* const argPacket) { //replace existing regions - regionPager.UnloadRegion(argPacket->x, argPacket->y); + regionPager.UnloadIf([&](Region const& region) -> bool { + return region.GetX() == argPacket->x && region.GetY() == argPacket->y; + }); regionPager.PushRegion(argPacket->region); //clean up after the serial code @@ -540,9 +542,9 @@ void InWorld::UpdateMap() { //entity management //------------------------- -//NOTE: preexisting characters will result in query responses -//NOTE: new characters will result in create messages -//NOTE: this client's character will exist in both (skipped) +//DOCS: preexisting characters will result in query responses +//DOCS: new characters will result in create messages +//DOCS: this client's character will exist in both (skipped) void InWorld::HandleCharacterCreate(CharacterPacket* const argPacket) { //prevent double message diff --git a/common/map/map_system_api.cpp b/common/map/map_system_api.cpp index 9e908ad..1ab6984 100644 --- a/common/map/map_system_api.cpp +++ b/common/map/map_system_api.cpp @@ -26,31 +26,11 @@ #include "region_pager_api.hpp" #include "tile_sheet_api.hpp" -//macros -#include "region.hpp" - //useful "globals" -static int getRegionWidth(lua_State* L) { - lua_pushinteger(L, REGION_WIDTH); - return 1; -} - -static int getRegionHeight(lua_State* L) { - lua_pushinteger(L, REGION_HEIGHT); - return 1; -} - -static int getRegionDepth(lua_State* L) { - lua_pushinteger(L, REGION_DEPTH); - return 1; -} +//... //This mimics linit.c to create a nested collection of all map modules. static const luaL_Reg funcs[] = { - //synonyms - {"GetRegionWidth", getRegionWidth}, - {"GetRegionHeight", getRegionHeight}, - {"GetRegionDepth", getRegionDepth}, {nullptr, nullptr} }; diff --git a/common/map/region.cpp b/common/map/region.cpp index 229c350..4546bdf 100644 --- a/common/map/region.cpp +++ b/common/map/region.cpp @@ -21,9 +21,9 @@ */ #include "region.hpp" -#include #include #include +#include int snapToBase(int base, int x) { return floor((double)x / base) * base; @@ -55,4 +55,16 @@ bool Region::SetSolid(int x, int y, bool b) { bool Region::GetSolid(int x, int y) { return solid[x * REGION_WIDTH + y]; +} + +int Region::GetX() const { + return x; +} + +int Region::GetY() const { + return y; +} + +std::bitset* Region::GetSolidBitset() { + return &solid; } \ No newline at end of file diff --git a/common/map/region.hpp b/common/map/region.hpp index 5e2f882..fd8c461 100644 --- a/common/map/region.hpp +++ b/common/map/region.hpp @@ -48,10 +48,10 @@ public: bool GetSolid(int x, int y); //accessors - int GetX() const { return x; } - int GetY() const { return y; } + int GetX() const; + int GetY() const; - std::bitset* GetSolidBitset() { return &solid; } + std::bitset* GetSolidBitset(); private: const int x; const int y; diff --git a/common/map/region_api.cpp b/common/map/region_api.cpp index 1749f49..1c0f848 100644 --- a/common/map/region_api.cpp +++ b/common/map/region_api.cpp @@ -85,6 +85,8 @@ static const luaL_Reg regionLib[] = { {"GetSolid",getSolid}, {"GetX",getX}, {"GetY",getY}, + + //the global macros {"GetWidth",getWidth}, {"GetHeight",getHeight}, {"GetDepth",getDepth}, diff --git a/common/map/region_pager_api.cpp b/common/map/region_pager_api.cpp index d7a38e9..73ad6e9 100644 --- a/common/map/region_pager_api.cpp +++ b/common/map/region_pager_api.cpp @@ -84,7 +84,22 @@ static int createRegion(lua_State* L) { static int unloadRegion(lua_State* L) { RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); - pager->UnloadRegion(lua_tointeger(L, 2), lua_tointeger(L, 3)); + + //two argument types: coords & the region itself + switch(lua_type(L, 2)) { + case LUA_TNUMBER: + pager->UnloadIf([&](Region const& region) -> bool { + int x = lua_tointeger(L, 2); + int y = lua_tointeger(L, 3); + return region.GetX() == x && region.GetY() == y; + }); + break; + case LUA_TLIGHTUSERDATA: + pager->UnloadIf([&](Region const& region) -> bool { + return (®ion) == lua_touserdata(L, 2); + }); + break; + } return 0; } @@ -116,6 +131,13 @@ static int setOnUnload(lua_State* L) { return 0; } +//debugging +static int containerSize(lua_State* L) { + RegionPagerLua* pager = static_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, pager->GetContainer()->size()); + return 1; +} + static const luaL_Reg regionPagerLib[] = { //curry {"SetTile", setTile}, @@ -136,6 +158,9 @@ static const luaL_Reg regionPagerLib[] = { {"SetOnCreate",setOnCreate}, {"SetOnUnload",setOnUnload}, + //debugging + {"ContainerSize", containerSize}, + //sentinel {nullptr, nullptr} }; diff --git a/common/map/region_pager_base.cpp b/common/map/region_pager_base.cpp index d20b346..1df6864 100644 --- a/common/map/region_pager_base.cpp +++ b/common/map/region_pager_base.cpp @@ -24,6 +24,10 @@ #include #include +RegionPagerBase::~RegionPagerBase() { + UnloadAll(); +}; + 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); @@ -88,12 +92,14 @@ Region* RegionPagerBase::CreateRegion(int x, int y) { return ®ionList.front(); } -void RegionPagerBase::UnloadRegion(int x, int y) { - regionList.remove_if([x, y](Region& region) -> bool { - return region.GetX() == x && region.GetY() == y; - }); +void RegionPagerBase::UnloadIf(std::function fn) { + regionList.remove_if(fn); } void RegionPagerBase::UnloadAll() { regionList.clear(); +} + +std::list* RegionPagerBase::GetContainer() { + return ®ionList; } \ No newline at end of file diff --git a/common/map/region_pager_base.hpp b/common/map/region_pager_base.hpp index c6d6b3d..cdafa3f 100644 --- a/common/map/region_pager_base.hpp +++ b/common/map/region_pager_base.hpp @@ -24,12 +24,13 @@ #include "region.hpp" +#include #include class RegionPagerBase { public: RegionPagerBase() = default; - virtual ~RegionPagerBase() { UnloadAll(); }; + virtual ~RegionPagerBase(); //tile manipulation virtual Region::type_t SetTile(int x, int y, int z, Region::type_t v); @@ -47,12 +48,12 @@ public: 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 UnloadIf(std::function fn); virtual void UnloadAll(); //accessors & mutators - std::list* GetContainer() { return ®ionList; } + std::list* GetContainer(); protected: std::list regionList; }; diff --git a/common/map/region_pager_lua.cpp b/common/map/region_pager_lua.cpp index 8fb0dfc..4e0a973 100644 --- a/common/map/region_pager_lua.cpp +++ b/common/map/region_pager_lua.cpp @@ -23,6 +23,9 @@ #include +//DOCS: Load, Save and Create fail unless the lua function has been set +//DOCS: UnloadIf and UnloadAll will still continue without the function set + RegionPagerLua::~RegionPagerLua() { //unload all regions UnloadAll(); @@ -130,23 +133,25 @@ Region* RegionPagerLua::CreateRegion(int x, int y) { } //no return -void RegionPagerLua::UnloadRegion(int x, int y) { +void RegionPagerLua::UnloadIf(std::function fn) { //get the pager's function from the registry lua_rawgeti(lua, LUA_REGISTRYINDEX, unloadRef); //check if this function is available if (lua_isnil(lua, -1)) { lua_pop(lua, 1); + //remove the regions anyway + regionList.remove_if(fn); return; } //run each region through this lambda regionList.remove_if([&](Region& region) -> bool { - if (region.GetX() == x && region.GetY() == y) { + if (fn(region)) { //push a copy of the function onto the stack with the region lua_pushvalue(lua, -1); - lua_pushlightuserdata(lua, ®ion); + lua_pushlightuserdata(lua, static_cast(®ion)); //call the function, 1 arg, 0 return if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { @@ -171,6 +176,8 @@ void RegionPagerLua::UnloadAll() { //check if this function is available if (lua_isnil(lua, -1)) { lua_pop(lua, 1); + //remove the regions anyway + regionList.clear(); return; } diff --git a/common/map/region_pager_lua.hpp b/common/map/region_pager_lua.hpp index 203715b..a4f5ba1 100644 --- a/common/map/region_pager_lua.hpp +++ b/common/map/region_pager_lua.hpp @@ -30,6 +30,7 @@ #include "lua.hpp" #endif +#include #include class RegionPagerLua : public RegionPagerBase { @@ -41,8 +42,8 @@ public: 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; + void UnloadIf(std::function fn) override; void UnloadAll() override; //accessors & mutators diff --git a/common/network/udp_network_utility.cpp b/common/network/udp_network_utility.cpp index c069b27..4dfb044 100644 --- a/common/network/udp_network_utility.cpp +++ b/common/network/udp_network_utility.cpp @@ -26,7 +26,7 @@ #include -//NOTE: memset() is used before sending a packet to remove old data; you don't want to send sensitive data over the network +//DOCS: memset() is used before sending a packet to remove old data; you don't want to send sensitive data over the network //NOTE: don't confuse SerialPacketBase with UDPpacket void UDPNetworkUtility::Open(int port) { diff --git a/rsc/scripts/setup_server.lua b/rsc/scripts/setup_server.lua index d39656f..53c733f 100644 --- a/rsc/scripts/setup_server.lua +++ b/rsc/scripts/setup_server.lua @@ -1,11 +1,67 @@ print("Lua script check") +mapSystem = require "map_system" mapMaker = require "map_maker" mapSaver = require "map_saver" roomSystem = require "room_system" +waypointSystem = require "waypoint_system" + +local function dumpTable(t) + print(t) + for k, v in pairs(t) do + print("",k,v) + end +end --NOTE: room 0 is the first that the client asks for, therefore it must exist -local overworld, uid = roomSystem.RoomManager.CreateRoom("overworld") -roomSystem.Room.Initialize(overworld, "overworld.bmp", mapSaver.Load, mapSaver.Save, mapMaker.debugIsland, mapSaver.Save) +local overworld, uid = roomSystem.RoomManager.CreateRoom("overworld", "overworld.bmp") + +--NOTE: This is horrible; room initialization is important +mapSystem.RegionPager.SetOnLoad(roomSystem.Room.GetPager(overworld), mapSaver.Load) +mapSystem.RegionPager.SetOnSave(roomSystem.Room.GetPager(overworld), mapSaver.Save) +mapSystem.RegionPager.SetOnCreate(roomSystem.Room.GetPager(overworld), mapMaker.debugIsland) +mapSystem.RegionPager.SetOnUnload(roomSystem.Room.GetPager(overworld), mapSaver.Save) print("Finished the lua script") + +--[[ +debugging test + +Ideal output: + +------------------------- +pager: userdata: [memory location] +Size 0: 0 +[debug output from load] +Size 1: 1 +[debug output from save] +Size 2: 0 +[debug output from load] +Size 3: 1 +[debug output from save] +Size 4: 0 +------------------------- + +--]-] + +print("-------------------------") +local pager = roomSystem.Room.GetPager(overworld) + +print("pager:", pager) + +print("Size 0:", mapSystem.RegionPager.ContainerSize(pager)) + +local regionFoo = mapSystem.RegionPager.GetRegion(pager, 0, 0) +print("Size 1:", mapSystem.RegionPager.ContainerSize(pager)) + +mapSystem.RegionPager.UnloadRegion(pager, regionFoo) +print("Size 2:", mapSystem.RegionPager.ContainerSize(pager)) + +local regionFoo = mapSystem.RegionPager.GetRegion(pager, 0, 0) +print("Size 3:", mapSystem.RegionPager.ContainerSize(pager)) + +mapSystem.RegionPager.UnloadRegion(pager, 0, 0) +print("Size 4:", mapSystem.RegionPager.ContainerSize(pager)) + +print("-------------------------") +--]] \ No newline at end of file diff --git a/server/accounts/account_manager.cpp b/server/accounts/account_manager.cpp index 84e7d06..22538bb 100644 --- a/server/accounts/account_manager.cpp +++ b/server/accounts/account_manager.cpp @@ -219,7 +219,6 @@ void AccountManager::UnloadIf(std::function::iterator it = elementMap.find(uid); if (it == elementMap.end()) { diff --git a/server/accounts/account_manager.hpp b/server/accounts/account_manager.hpp index 9e6e550..ad65836 100644 --- a/server/accounts/account_manager.hpp +++ b/server/accounts/account_manager.hpp @@ -24,7 +24,6 @@ #include "account_data.hpp" #include "singleton.hpp" -#include "manager_interface.hpp" #if defined(__MINGW32__) #include "sqlite3/sqlite3.h" @@ -35,26 +34,23 @@ #include #include -class AccountManager: - public Singleton, - public ManagerInterface -{ +class AccountManager: public Singleton { public: //common public methods - int Create(std::string username, int clientIndex) override; - int Load(std::string username, int clientIndex) override; - int Save(int uid) override; - void Unload(int uid) override; - void Delete(int uid) override; + int Create(std::string username, int clientIndex); + int Load(std::string username, int clientIndex); + int Save(int uid); + void Unload(int uid); + void Delete(int uid); - void UnloadAll() override; - void UnloadIf(std::function)> fn) override; + void UnloadAll(); + void UnloadIf(std::function)> fn); //accessors and mutators - AccountData* Get(int uid) override; - int GetLoadedCount() override; - int GetTotalCount() override; - std::map* GetContainer() override; + AccountData* Get(int uid); + int GetLoadedCount(); + int GetTotalCount(); + std::map* GetContainer(); sqlite3* SetDatabase(sqlite3* db); sqlite3* GetDatabase(); @@ -65,6 +61,8 @@ private: AccountManager() = default; ~AccountManager() = default; + //members + std::map elementMap; sqlite3* database = nullptr; }; diff --git a/server/characters/character_manager.hpp b/server/characters/character_manager.hpp index fadf54c..2263d46 100644 --- a/server/characters/character_manager.hpp +++ b/server/characters/character_manager.hpp @@ -24,7 +24,6 @@ #include "character_data.hpp" #include "singleton.hpp" -#include "manager_interface.hpp" #if defined(__MINGW32__) #include "sqlite3/sqlite3.h" @@ -35,26 +34,23 @@ #include #include -class CharacterManager: - public Singleton, - public ManagerInterface -{ +class CharacterManager: public Singleton { public: //common public methods - int Create(int owner, std::string handle, std::string avatar) override; - int Load(int owner, std::string handle, std::string avatar) override; - int Save(int uid) override; - void Unload(int uid) override; - void Delete(int uid) override; + int Create(int owner, std::string handle, std::string avatar); + int Load(int owner, std::string handle, std::string avatar); + int Save(int uid); + void Unload(int uid); + void Delete(int uid); - void UnloadAll() override; - void UnloadIf(std::function)> fn) override; + void UnloadAll(); + void UnloadIf(std::function)> fn); //accessors and mutators - CharacterData* Get(int uid) override; - int GetLoadedCount() override; - int GetTotalCount() override; - std::map* GetContainer() override; + CharacterData* Get(int uid); + int GetLoadedCount(); + int GetTotalCount(); + std::map* GetContainer(); sqlite3* SetDatabase(sqlite3* db); sqlite3* GetDatabase(); @@ -65,6 +61,8 @@ private: CharacterManager() = default; ~CharacterManager() = default; + //members + std::map elementMap; sqlite3* database = nullptr; }; diff --git a/server/clients/client_manager.cpp b/server/clients/client_manager.cpp index 87604f6..a1c1808 100644 --- a/server/clients/client_manager.cpp +++ b/server/clients/client_manager.cpp @@ -78,7 +78,6 @@ void ClientManager::UnloadIf(std::function while (it != elementMap.end()) { if (fn(*it)) { it = elementMap.erase(it); - //TODO: ? disconnect, unload characters, notify other clients } else { ++it; diff --git a/server/clients/client_manager.hpp b/server/clients/client_manager.hpp index 4e0b0d1..165199b 100644 --- a/server/clients/client_manager.hpp +++ b/server/clients/client_manager.hpp @@ -23,35 +23,32 @@ #define CLIENTMANAGER_HPP_ #include "client_data.hpp" -#include "manager_interface.hpp" #include "server_packet.hpp" #include "singleton.hpp" #include "SDL/SDL_net.h" #include +#include -class ClientManager: - public Singleton, - public ManagerInterface -{ +class ClientManager: public Singleton { public: //methods int CheckConnections(); void HandlePong(ServerPacket* const argPacket); //common public methods - int Create(IPaddress) override; - void Unload(int uid) override; + int Create(IPaddress); + void Unload(int uid); - void UnloadAll() override; - void UnloadIf(std::function)> fn) override; + void UnloadAll(); + void UnloadIf(std::function)> fn); //accessors & mutators - ClientData* Get(int uid) override; - int GetLoadedCount() override; - int GetTotalCount() override; - std::map* GetContainer() override; + ClientData* Get(int uid); + int GetLoadedCount(); + int GetTotalCount(); + std::map* GetContainer(); private: friend Singleton; @@ -59,11 +56,8 @@ private: ClientManager() = default; ~ClientManager() = default; - //EMPTY - int Load(IPaddress) override { return -1; } - int Save(int uid) override { return -1; } - void Delete(int uid) override { return; } - + //members + std::map elementMap; int counter = 0; }; diff --git a/server/entities/entity.hpp b/server/entities/entity.hpp index e110e80..f71fbf9 100644 --- a/server/entities/entity.hpp +++ b/server/entities/entity.hpp @@ -38,7 +38,7 @@ public: protected: Entity() = default; - ~Entity() = default; + virtual ~Entity() = default; int roomIndex = -1; Vector2 origin; diff --git a/server/entities/entity_api.cpp b/server/entities/entity_api.cpp index 84c1a63..a7f71bd 100644 --- a/server/entities/entity_api.cpp +++ b/server/entities/entity_api.cpp @@ -23,7 +23,51 @@ #include "entity.hpp" +static int setRoomIndex(lua_State* L) { + Entity* entity = static_cast(lua_touserdata(L, 1)); + entity->SetRoomIndex(lua_tointeger(L, 2)); + return 0; +} + +static int setOrigin(lua_State* L) { + Entity* entity = static_cast(lua_touserdata(L, 1)); + entity->SetOrigin({lua_tonumber(L, 2), lua_tonumber(L, 3)}); + return 0; +} + +static int setMotion(lua_State* L) { + Entity* entity = static_cast(lua_touserdata(L, 1)); + entity->SetMotion({lua_tonumber(L, 2), lua_tonumber(L, 3)}); + return 0; +} + +static int getRoomIndex(lua_State* L) { + Entity* entity = static_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, entity->GetRoomIndex()); + return 1; +} + +static int getOrigin(lua_State* L) { + Entity* entity = static_cast(lua_touserdata(L, 1)); + lua_pushnumber(L, entity->GetOrigin().x); + lua_pushnumber(L, entity->GetOrigin().y); + return 2; +} + +static int getMotion(lua_State* L) { + Entity* entity = static_cast(lua_touserdata(L, 1)); + lua_pushnumber(L, entity->GetOrigin().x); + lua_pushnumber(L, entity->GetOrigin().y); + return 2; +} + static const luaL_Reg entityLib[] = { + {"SetRoomIndex", setRoomIndex}, + {"SetOrigin", setOrigin}, + {"SetMotion", setMotion}, + {"GetRoomIndex", getRoomIndex}, + {"GetOrigin", getOrigin}, + {"GetMotion", getMotion}, {nullptr, nullptr} }; diff --git a/server/linit.cpp b/server/linit.cpp index 1030490..d4ab6e6 100644 --- a/server/linit.cpp +++ b/server/linit.cpp @@ -42,6 +42,7 @@ #include "map_system_api.hpp" #include "room_system_api.hpp" +#include "waypoint_system_api.hpp" //these libs are loaded by lua.c and are readily available to any Lua program static const luaL_Reg loadedlibs[] = { @@ -64,6 +65,7 @@ static const luaL_Reg loadedlibs[] = { static const luaL_Reg preloadedlibs[] = { {TORTUGA_MAP_SYSTEM_API, openMapSystemAPI}, {TORTUGA_ROOM_SYSTEM_API, openRoomSystemAPI}, + {TORTUGA_WAYPOINT_SYSTEM_API, openWaypointSystemAPI}, {NULL, NULL} }; diff --git a/server/monsters/monster_manager.hpp b/server/monsters/monster_manager.hpp index de19e2c..24f980f 100644 --- a/server/monsters/monster_manager.hpp +++ b/server/monsters/monster_manager.hpp @@ -22,7 +22,6 @@ #ifndef MONSTERMANAGER_HPP_ #define MONSTERMANAGER_HPP_ -#include "manager_interface.hpp" #include "monster_data.hpp" #include "singleton.hpp" @@ -35,28 +34,26 @@ #endif #include +#include #include -class MonsterManager: - public Singleton, - public ManagerInterface -{ +class MonsterManager: public Singleton { public: //common public methods - int Create(std::string) override; - int Load(std::string) override; - int Save(int uid) override; - void Unload(int uid) override; - void Delete(int uid) override; + int Create(std::string); + int Load(std::string); + int Save(int uid); + void Unload(int uid); + void Delete(int uid); - void UnloadAll() override; - void UnloadIf(std::function)> fn) override; + void UnloadAll(); + void UnloadIf(std::function)> fn); //accessors & mutators - MonsterData* Get(int uid) override; - int GetLoadedCount() override; - int GetTotalCount() override; - std::map* GetContainer() override; + MonsterData* Get(int uid); + int GetLoadedCount(); + int GetTotalCount(); + std::map* GetContainer(); //hooks sqlite3* SetDatabase(sqlite3* db); @@ -70,6 +67,8 @@ private: MonsterManager() = default; ~MonsterManager() = default; + //members + std::map elementMap; sqlite3* database = nullptr; lua_State* lua = nullptr; }; diff --git a/server/rooms/room_api.cpp b/server/rooms/room_api.cpp index b40d123..b6606f8 100644 --- a/server/rooms/room_api.cpp +++ b/server/rooms/room_api.cpp @@ -25,25 +25,25 @@ static int setRoomName(lua_State* L) { RoomData* room = reinterpret_cast(lua_touserdata(L, 1)); - room->SetRoomName(lua_tostring(L, 2)); + room->SetName(lua_tostring(L, 2)); return 0; } static int getRoomName(lua_State* L) { RoomData* room = reinterpret_cast(lua_touserdata(L, 1)); - lua_pushstring(L, room->GetRoomName().c_str()); + lua_pushstring(L, room->GetName().c_str()); return 1; } static int setTilesetName(lua_State* L) { RoomData* room = reinterpret_cast(lua_touserdata(L, 1)); - room->SetTilesetName(lua_tostring(L, 2)); + room->SetTileset(lua_tostring(L, 2)); return 0; } static int getTilesetName(lua_State* L) { RoomData* room = reinterpret_cast(lua_touserdata(L, 1)); - lua_pushstring(L, room->GetTilesetName().c_str()); + lua_pushstring(L, room->GetTileset().c_str()); return 1; } @@ -56,7 +56,8 @@ static int getPager(lua_State* L) { static int initialize(lua_State* L) { //set the members of the given room RoomData* room = static_cast(lua_touserdata(L, 1)); - room->SetRoomName(lua_tostring(L, 2)); + room->SetName(lua_tostring(L, 2)); + room->SetTileset(lua_tostring(L, 3)); //set the refs of these parameters (backwards, since it pops from the top of the stack) room->GetPager()->SetUnloadReference(luaL_ref(L, LUA_REGISTRYINDEX)); @@ -70,8 +71,8 @@ static int initialize(lua_State* L) { static const luaL_Reg roomLib[] = { {"GetPager",getPager}, - {"SetRoomName", setRoomName}, - {"GetRoomName", getRoomName}, + {"SetName", setRoomName}, + {"GetName", getRoomName}, {"SetTileset", setTilesetName}, {"GetTileset", getTilesetName}, {"Initialize", initialize}, diff --git a/server/rooms/room_data.cpp b/server/rooms/room_data.cpp index 5b7ec8f..8919564 100644 --- a/server/rooms/room_data.cpp +++ b/server/rooms/room_data.cpp @@ -21,19 +21,19 @@ */ #include "room_data.hpp" -std::string RoomData::SetRoomName(std::string s) { +std::string RoomData::SetName(std::string s) { return roomName = s; } -std::string RoomData::GetRoomName() { +std::string RoomData::GetName() { return roomName; } -std::string RoomData::SetTilesetName(std::string s) { +std::string RoomData::SetTileset(std::string s) { return tilesetName = s; } -std::string RoomData::GetTilesetName() { +std::string RoomData::GetTileset() { return tilesetName; } diff --git a/server/rooms/room_data.hpp b/server/rooms/room_data.hpp index c3668fc..eb977d2 100644 --- a/server/rooms/room_data.hpp +++ b/server/rooms/room_data.hpp @@ -40,15 +40,17 @@ public: ~RoomData() = default; //accessors and mutators - std::string SetRoomName(std::string s); - std::string GetRoomName(); + std::string SetName(std::string); + std::string GetName(); - std::string SetTilesetName(std::string s); - std::string GetTilesetName(); + std::string SetTileset(std::string); + std::string GetTileset(); RegionPagerLua* GetPager(); std::list* GetEntityList(); + //TODO: triggers for unload, save, per-second, player enter, player exit, etc. + private: friend class RoomManager; diff --git a/server/rooms/room_manager.cpp b/server/rooms/room_manager.cpp index 2d190c9..4ce2dff 100644 --- a/server/rooms/room_manager.cpp +++ b/server/rooms/room_manager.cpp @@ -29,27 +29,18 @@ //public access methods //------------------------- -int RoomManager::Create(std::string roomName) { +int RoomManager::Create(std::string roomName, std::string tileset) { //create the room RoomData* newRoom = &elementMap[counter]; //implicitly constructs the element - newRoom->SetRoomName(roomName); + newRoom->SetName(roomName); + newRoom->SetTileset(tileset); + newRoom->pager.SetLuaState(lua); //finish the routine return counter++; } -void RoomManager::Unload(int uid) { - //find the room - std::map::iterator it = elementMap.find(uid); - if (it == elementMap.end()) { - return; - } - - //free the memory - elementMap.erase(uid); -} - void RoomManager::UnloadAll() { elementMap.clear(); } @@ -76,14 +67,27 @@ RoomData* RoomManager::Get(int uid) { return &it->second; } -int RoomManager::GetLoadedCount() { - return elementMap.size(); +RoomData* RoomManager::Get(std::string name) { + for (std::map::iterator it = elementMap.begin(); it != elementMap.end(); ++it) { + if (it->second.GetName() == name) { + return &it->second; + } + } + return nullptr; } -int RoomManager::GetTotalCount() { +int RoomManager::GetLoadedCount() { return elementMap.size(); } std::map* RoomManager::GetContainer() { return &elementMap; } + +lua_State* RoomManager::SetLuaState(lua_State* L) { + return lua = L; +} + +lua_State* RoomManager::GetLuaState() { + return lua; +} diff --git a/server/rooms/room_manager.hpp b/server/rooms/room_manager.hpp index e5ae344..9f9f37c 100644 --- a/server/rooms/room_manager.hpp +++ b/server/rooms/room_manager.hpp @@ -24,7 +24,6 @@ #include "room_data.hpp" #include "singleton.hpp" -#include "manager_interface.hpp" #if defined(__MINGW32__) #include "lua/lua.hpp" @@ -32,27 +31,26 @@ #include "lua.hpp" #endif -class RoomManager: - public Singleton, - public ManagerInterface -{ +#include +#include + +class RoomManager: public Singleton { public: //common public methods - int Create(std::string) override; - void Unload(int uid) override; + int Create(std::string name, std::string tileset); - void UnloadAll() override; - void UnloadIf(std::function)> fn) override; + void UnloadAll(); + void UnloadIf(std::function)> fn); //accessors and mutators - RoomData* Get(int uid) override; - int GetLoadedCount() override; - int GetTotalCount() override; - std::map* GetContainer() override; + RoomData* Get(int uid); + RoomData* Get(std::string name); + int GetLoadedCount(); + std::map* GetContainer(); //hooks - lua_State* SetLuaState(lua_State* L) { return lua = L; } - lua_State* GetLuaState() { return lua; } + lua_State* SetLuaState(lua_State* L); + lua_State* GetLuaState(); private: friend Singleton; @@ -60,10 +58,8 @@ private: RoomManager() = default; ~RoomManager() = default; - int Load(std::string) override { return -1; } - int Save(int uid) override { return -1; } - void Delete(int uid) override { } - + //members + std::map elementMap; lua_State* lua = nullptr; int counter = 0; }; diff --git a/server/rooms/room_manager_api.cpp b/server/rooms/room_manager_api.cpp index 0a22f46..1eade08 100644 --- a/server/rooms/room_manager_api.cpp +++ b/server/rooms/room_manager_api.cpp @@ -24,31 +24,67 @@ #include "room_manager.hpp" int createRoom(lua_State* L) { - //create & get the room RoomManager& roomMgr = RoomManager::GetSingleton(); - int uid = roomMgr.Create(lua_tostring(L, 1)); + int uid = roomMgr.Create(lua_tostring(L, 1), lua_tostring(L, 2)); RoomData* room = roomMgr.Get(uid); + //TODO: initialization parameters here? + //return room, uid lua_pushlightuserdata(L, static_cast(room)); - lua_pushinteger(L, uid); + lua_pushinteger(L, uid); //for debugging, mostly return 2; } int unloadRoom(lua_State* L) { - //TODO: check authorization for room deletion RoomManager& roomMgr = RoomManager::GetSingleton(); - roomMgr.Unload(lua_tointeger(L, 1)); + + switch(lua_type(L, 1)) { + case LUA_TNUMBER: { + //number + int uid = lua_tointeger(L, 1); + roomMgr.UnloadIf([uid](std::pair it){ + return it.first == uid; + }); + } + break; + case LUA_TSTRING: { + //name + std::string name = lua_tostring(L, 1); + roomMgr.UnloadIf([name](std::pair it){ + return it.second.GetName() == name; + }); + } + break; + case LUA_TLIGHTUSERDATA: { + //the room itself + std::string name = static_cast(lua_touserdata(L, 1))->GetName(); + roomMgr.UnloadIf([name](std::pair it){ + return it.second.GetName() == name; + }); + } + break; + } return 0; } int getRoom(lua_State* L) { //TODO: integer vs name for getRoom() RoomManager& roomMgr = RoomManager::GetSingleton(); + RoomData* room = nullptr; - RoomData* room = roomMgr.Get(lua_tointeger(L, 1)); + switch(lua_type(L, 1)) { + case LUA_TNUMBER: + //number + room = roomMgr.Get(lua_tointeger(L, 1)); + break; + case LUA_TSTRING: + //name + room = roomMgr.Get(lua_tostring(L, 1)); + break; + } if (room) { lua_pushlightuserdata(L, static_cast(room)); diff --git a/server/server_character_methods.cpp b/server/server_character_methods.cpp index 018db97..d123d8e 100644 --- a/server/server_character_methods.cpp +++ b/server/server_character_methods.cpp @@ -105,7 +105,7 @@ void ServerApplication::HandleCharacterLoad(CharacterPacket* const argPacket) { if (characterIndex == -1) { msg << "Character already loaded: "; } - if (characterIndex == -1) { + if (characterIndex == -2) { msg << "Character name is taken: "; } msg << argPacket->handle; @@ -191,7 +191,6 @@ void ServerApplication::HandleCharacterSetRoom(CharacterPacket* const argPacket) } //set the character's room, zero it's origin, zero it's motion - //TODO: Set the origin here characterData->SetRoomIndex(argPacket->roomIndex); characterData->SetOrigin({0, 0}); characterData->SetMotion({0, 0}); diff --git a/server/server_logic.cpp b/server/server_logic.cpp index 5e93167..ad78485 100644 --- a/server/server_logic.cpp +++ b/server/server_logic.cpp @@ -105,6 +105,7 @@ void ServerApplication::Init(int argc, char* argv[]) { characterMgr.SetDatabase(database); roomMgr.SetLuaState(luaState); + waypointMgr.SetLuaState(luaState); std::cout << "Internal managers initialized" << std::endl; diff --git a/server/waypoints/makefile b/server/waypoints/makefile index 2a5c671..3585271 100644 --- a/server/waypoints/makefile +++ b/server/waypoints/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../server_utilities ../../common/utilities +INCLUDES+=. ../entities ../server_utilities ../../common/utilities LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/server/waypoints/waypoint_api.cpp b/server/waypoints/waypoint_api.cpp index 0092d3d..6059f69 100644 --- a/server/waypoints/waypoint_api.cpp +++ b/server/waypoints/waypoint_api.cpp @@ -23,6 +23,7 @@ #include "waypoint_data.hpp" +//TODO: Can I alias the entity API for this? static const luaL_Reg waypointLib[] = { {nullptr, nullptr} }; diff --git a/server/waypoints/waypoint_data.cpp b/server/waypoints/waypoint_data.cpp index 229d597..b720e1d 100644 --- a/server/waypoints/waypoint_data.cpp +++ b/server/waypoints/waypoint_data.cpp @@ -21,3 +21,10 @@ */ #include "waypoint_data.hpp" +int WaypointData::SetTriggerReference(int i) { + return triggerRef = i; +} + +int WaypointData::GetTriggerReference() { + return triggerRef; +} \ No newline at end of file diff --git a/server/waypoints/waypoint_data.hpp b/server/waypoints/waypoint_data.hpp index d1d3f77..32aa7d0 100644 --- a/server/waypoints/waypoint_data.hpp +++ b/server/waypoints/waypoint_data.hpp @@ -22,15 +22,28 @@ #ifndef WAYPOINTDATA_HPP_ #define WAYPOINTDATA_HPP_ +#include "entity.hpp" + +#if defined(__MINGW32__) + #include "lua/lua.hpp" +#else + #include "lua.hpp" +#endif + #include -class WaypointData { +class WaypointData: public Entity { public: WaypointData() = default; ~WaypointData() = default; + int SetTriggerReference(int i); + int GetTriggerReference(); + private: friend class WaypointManager; + + int triggerRef = LUA_NOREF; }; #endif \ No newline at end of file diff --git a/server/waypoints/waypoint_manager.hpp b/server/waypoints/waypoint_manager.hpp index f4975aa..0e51d3a 100644 --- a/server/waypoints/waypoint_manager.hpp +++ b/server/waypoints/waypoint_manager.hpp @@ -23,39 +23,52 @@ #define WAYPOINTMANAGER_HPP_ #include "waypoint_data.hpp" -#include "manager_interface.hpp" #include "singleton.hpp" #include "vector2.hpp" +#if defined(__MINGW32__) + #include "lua/lua.hpp" +#else + #include "lua.hpp" +#endif + #include +#include #include -class WaypointManager: - public Singleton, - public ManagerInterface -{ +//TODO: should waypoints be managed on a per-room basis? +class WaypointManager: public Singleton { public: //common public methods - int Create() override; - int Load() override; - int Save(int uid) override; - void Unload(int uid) override; - void Delete(int uid) override; + int Create(); + int Load(); + int Save(int uid); + void Unload(int uid); + void Delete(int uid); - void UnloadAll() override; - void UnloadIf(std::function)> fn) override; + void UnloadAll(); + void UnloadIf(std::function)> fn); //accessors & mutators - WaypointData* Get(int uid) override; - int GetLoadedCount() override; - int GetTotalCount() override; - std::map* GetContainer() override; + WaypointData* Get(int uid); + int GetLoadedCount(); + int GetTotalCount(); + std::map* GetContainer(); + + //hooks + lua_State* SetLuaState(lua_State* L) { return lua = L; } + lua_State* GetLuaState() { return lua; } private: friend Singleton; WaypointManager() = default; ~WaypointManager() = default; + + //members + std::map elementMap; + lua_State* lua = nullptr; + int counter = 0; }; #endif \ No newline at end of file diff --git a/server/server_utilities/manager_interface.hpp b/server/waypoints/waypoint_system_api.cpp similarity index 52% rename from server/server_utilities/manager_interface.hpp rename to server/waypoints/waypoint_system_api.cpp index c10e6d2..a16f6ea 100644 --- a/server/server_utilities/manager_interface.hpp +++ b/server/waypoints/waypoint_system_api.cpp @@ -19,37 +19,37 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#ifndef MANAGERINTERFACE_HPP_ -#define MANAGERINTERFACE_HPP_ +#include "waypoint_system_api.hpp" -#include -#include +//all waypoint API headers +#include "waypoint_api.hpp" +#include "waypoint_manager_api.hpp" -template -class ManagerInterface { -public: - //common public methods - virtual int Create(Arguments... parameters) = 0; - virtual int Load(Arguments... parameters) = 0; - virtual int Save(int uid) = 0; - virtual void Unload(int uid) = 0; - virtual void Delete(int uid) = 0; +//useful "globals" +//... - virtual void UnloadAll() = 0; - virtual void UnloadIf(std::function)> fn) = 0; - - //accessors & mutators - virtual T* Get(int uid) = 0; - virtual int GetLoadedCount() = 0; - virtual int GetTotalCount() = 0; //can be an alias of GetLoadedCount() - virtual std::map* GetContainer() = 0; - -protected: - ManagerInterface() = default; - ~ManagerInterface() = default; - - //members - std::map elementMap; +//This mimics linit.c to create a nested collection of all waypoint modules. +static const luaL_Reg funcs[] = { + {nullptr, nullptr} }; -#endif \ No newline at end of file +static const luaL_Reg libs[] = { + {"Waypoint", openWaypointAPI}, + {"WaypointManager", openWaypointManagerAPI}, + {nullptr, nullptr} +}; + +int openWaypointSystemAPI(lua_State* L) { + //create the table + luaL_newlibtable(L, libs); + + //push the "global" functions + luaL_setfuncs(L, funcs, 0); + + //push the substable + for (const luaL_Reg* lib = libs; lib->func; lib++) { + lib->func(L); + lua_setfield(L, -2, lib->name); + } + return 1; +} diff --git a/server/waypoints/waypoint_system_api.hpp b/server/waypoints/waypoint_system_api.hpp new file mode 100644 index 0000000..d651a1f --- /dev/null +++ b/server/waypoints/waypoint_system_api.hpp @@ -0,0 +1,34 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * 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 WAYPOINTSYSTEMAPI_HPP_ +#define WAYPOINTSYSTEMAPI_HPP_ + +#if defined(__MINGW32__) + #include "lua/lua.hpp" +#else + #include "lua.hpp" +#endif + +#define TORTUGA_WAYPOINT_SYSTEM_API "waypoint_system" +LUAMOD_API int openWaypointSystemAPI(lua_State* L); + +#endif \ No newline at end of file diff --git a/todo.txt b/todo.txt index c543542..655f6e5 100644 --- a/todo.txt +++ b/todo.txt @@ -10,6 +10,7 @@ TODO: Account passwords (list) * ... * salts & hashes +TODO: Pagers giving their region counts in the API TODO: Waypoints, with positions and trigger zones (collision areas) for doors, monster spawns, etc. TODO: Fix shoddy movement TODO: Periodic mass server saves