diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index 19caef0..ec03408 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -589,8 +589,6 @@ void InWorld::HandleCharacterDelete(CharacterPacket* const argPacket) { //ignore if this character doesn't exist std::map::iterator characterIt = characterMap.find(argPacket->characterIndex); if (characterIt == characterMap.end()) { - //debug - std::cout << "Ignoring character deletion" << std::endl; return; } diff --git a/common/graphics/makefile b/common/graphics/makefile index 9013447..afcde11 100644 --- a/common/graphics/makefile +++ b/common/graphics/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. +INCLUDES+=. ../map LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/common/map/tile_sheet.cpp b/common/graphics/tile_sheet.cpp similarity index 100% rename from common/map/tile_sheet.cpp rename to common/graphics/tile_sheet.cpp diff --git a/common/map/tile_sheet.hpp b/common/graphics/tile_sheet.hpp similarity index 100% rename from common/map/tile_sheet.hpp rename to common/graphics/tile_sheet.hpp diff --git a/common/map/makefile b/common/map/makefile index 24e7779..769709e 100644 --- a/common/map/makefile +++ b/common/map/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../graphics ../utilities +INCLUDES+=. ../utilities LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/common/map/map_system_api.cpp b/common/map/map_system_api.cpp index 1ab6984..7a980c7 100644 --- a/common/map/map_system_api.cpp +++ b/common/map/map_system_api.cpp @@ -24,7 +24,6 @@ //all map API headers #include "region_api.hpp" #include "region_pager_api.hpp" -#include "tile_sheet_api.hpp" //useful "globals" //... @@ -37,7 +36,6 @@ static const luaL_Reg funcs[] = { static const luaL_Reg libs[] = { {"Region", openRegionAPI}, {"RegionPager", openRegionPagerAPI}, -// {"TileSheet", openTileSheetAPI}, {nullptr, nullptr} }; diff --git a/common/map/region.cpp b/common/map/region.cpp index 4546bdf..1815d36 100644 --- a/common/map/region.cpp +++ b/common/map/region.cpp @@ -42,18 +42,30 @@ Region::Region(Region const& rhs): x(rhs.x), y(rhs.y) { } Region::type_t Region::SetTile(int x, int y, int z, type_t v) { + if (x < 0 || y < 0 || z < 0 || x >= REGION_WIDTH || y >= REGION_HEIGHT || z >= REGION_DEPTH) { + throw(std::out_of_range("Region::SetTile() argument out of range")); + } return tiles[x][y][z] = v; } Region::type_t Region::GetTile(int x, int y, int z) { + if (x < 0 || y < 0 || z < 0 || x >= REGION_WIDTH || y >= REGION_HEIGHT || z >= REGION_DEPTH) { + throw(std::out_of_range("Region::GetTile() argument out of range")); + } return tiles[x][y][z]; } bool Region::SetSolid(int x, int y, bool b) { + if (x < 0 || y < 0 || x >= REGION_WIDTH || y >= REGION_HEIGHT) { + throw(std::out_of_range("Region::SetSolid() argument out of range")); + } return solid[x * REGION_WIDTH + y] = b; } bool Region::GetSolid(int x, int y) { + if (x < 0 || y < 0 || x >= REGION_WIDTH || y >= REGION_HEIGHT) { + throw(std::out_of_range("Region::GetSolid() argument out of range")); + } return solid[x * REGION_WIDTH + y]; } diff --git a/common/map/tile_sheet_api.cpp b/common/map/tile_sheet_api.cpp deleted file mode 100644 index 141f200..0000000 --- a/common/map/tile_sheet_api.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* 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. -*/ -#include "tile_sheet_api.hpp" - -#include "tile_sheet.hpp" - -static int load(lua_State* L) { - TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); - sheet->Load(lua_tostring(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4)); - return 0; -} - -static int unload(lua_State* L) { - TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); - sheet->Unload(); - return 0; -} - -static int getXCount(lua_State* L) { - TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); - lua_pushinteger(L, sheet->GetXCount()); - return 1; -} - -static int getYCount(lua_State* L) { - TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); - lua_pushinteger(L, sheet->GetYCount()); - return 1; -} - -static int getTileW(lua_State* L) { - TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); - lua_pushinteger(L, sheet->GetTileW()); - return 1; -} - -static int getTileH(lua_State* L) { - TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); - lua_pushinteger(L, sheet->GetTileH()); - return 1; -} - -static const luaL_Reg tileSheetLib[] = { - {"Load",load}, - {"Unload",unload}, - {"GetXCount",getXCount}, - {"GetYCount",getYCount}, - {"GetTileW",getTileW}, - {"GetTileH",getTileH}, - {nullptr, nullptr} -}; - -LUAMOD_API int openTileSheetAPI(lua_State* L) { - luaL_newlib(L, tileSheetLib); - return 1; -} \ No newline at end of file diff --git a/rsc/scripts/map_maker.lua b/rsc/scripts/map_maker.lua index ca9ebc8..c48f6bf 100644 --- a/rsc/scripts/map_maker.lua +++ b/rsc/scripts/map_maker.lua @@ -1,39 +1,95 @@ -local mapSystem = require "map_system" +local Region = require("map_system").Region local mapMaker = {} --utility functions -function mapMaker.sqr(x) return x*x end -function mapMaker.dist(x, y, i, j) return math.sqrt(mapMaker.sqr(x - i) + mapMaker.sqr(y - j)) end +function mapMaker.Sqr(x) return x*x end +function mapMaker.Dist(x, y, i, j) return math.sqrt(mapMaker.Sqr(x - i) + mapMaker.Sqr(y - j)) end --tile macros, mapped to the tilesheet "overworld.bmp" -mapMaker.edges = {} -mapMaker.edges.north = -16 -mapMaker.edges.south = 16 -mapMaker.edges.east = 1 -mapMaker.edges.west = -1 - mapMaker.water = 18 + 3 * 0 mapMaker.sand = 18 + 3 * 1 mapMaker.plains = 18 + 3 * 2 mapMaker.grass = 18 + 3 * 3 mapMaker.dirt = 18 + 3 * 4 ---custom generation systems here -function mapMaker.debugIsland(region) - for i = 1, mapSystem.Region.GetWidth(region) do - for j = 1, mapSystem.Region.GetHeight(region) do - local dist = mapMaker.dist(0, 0, i + mapSystem.Region.GetX(region) -1, j + mapSystem.Region.GetY(region) -1) - if dist < 10 then - mapSystem.Region.SetTile(region, i, j, 1, mapMaker.plains) - elseif dist < 12 then - mapSystem.Region.SetTile(region, i, j, 1, mapMaker.sand) - else - mapSystem.Region.SetTile(region, i, j, 1, mapMaker.water) - mapSystem.Region.SetSolid(region, i, j, true) +--"edge" macros +mapMaker.edges = {} +mapMaker.edges.north = -16 +mapMaker.edges.south = 16 +mapMaker.edges.east = 1 +mapMaker.edges.west = -1 + +--use these macros (mapped to "overworld.bmp" for now) to smooth the region's edges +function mapMaker.SmoothEdgesSimple(r) + --make and pad an array to use + local shiftArray = {} + for i = 1, Region.GetWidth(r) do + shiftArray[i] = {} + for j = 1, Region.GetHeight(r) do + shiftArray[i][j] = 0 + end + end + + --build the array + for i = 1, Region.GetWidth(r) do + for j = 1, Region.GetHeight(r) do + --if (not region edge) and (west tile < this tile), etc. + if i > 1 and Region.GetTile(r, i - 1, j, 1) < Region.GetTile(r, i, j, 1) then + shiftArray[i][j] = shiftArray[i][j] + mapMaker.edges.west + end + if j > 1 and Region.GetTile(r, i, j - 1, 1) < Region.GetTile(r, i, j, 1) then + shiftArray[i][j] = shiftArray[i][j] + mapMaker.edges.north + end + if i < Region.GetWidth(r) and Region.GetTile(r, i + 1, j, 1) < Region.GetTile(r, i, j, 1) then + shiftArray[i][j] = shiftArray[i][j] + mapMaker.edges.east + end + if j < Region.GetHeight(r) and Region.GetTile(r, i, j + 1, 1) < Region.GetTile(r, i, j, 1) then + shiftArray[i][j] = shiftArray[i][j] + mapMaker.edges.south + end + end + end + + --finally apply this + for i = 1, Region.GetWidth(r) do + for j = 1, Region.GetHeight(r) do + if shiftArray[i][j] ~= 0 then + Region.SetTile(r, i, j, 2, Region.GetTile(r, i, j, 1) + shiftArray[i][j]) + Region.SetTile(r, i, j, 1, Region.GetTile(r, i, j, 1) - 3) end end end end +--custom generation systems here +function mapMaker.DebugIsland(r) + --basic distance check for each tile, placing an island around the world origin + for i = 1, Region.GetWidth(r) do + for j = 1, Region.GetHeight(r) do + local dist = mapMaker.Dist(0, 0, i + Region.GetX(r) -1, j + Region.GetY(r) -1) + if dist < 10 then + Region.SetTile(r, i, j, 1, mapMaker.plains) + elseif dist < 12 then + Region.SetTile(r, i, j, 1, mapMaker.sand) + else + Region.SetTile(r, i, j, 1, mapMaker.water) + Region.SetSolid(r, i, j, true) + end + end + end + + --examples of the smoothing function NOT working correctly + --[[ + for j = 1, Region.GetHeight(r) do + Region.SetTile(r, 3, j, 1, mapMaker.dirt) + Region.SetTile(r, 4, j, 1, mapMaker.dirt) + + Region.SetTile(r, 10, j, 1, mapMaker.dirt) + end + --]] + + --A generic edge system + mapMaker.SmoothEdgesSimple(r) +end + return mapMaker \ No newline at end of file diff --git a/rsc/scripts/map_saver.lua b/rsc/scripts/map_saver.lua index 7454081..b9b77ea 100644 --- a/rsc/scripts/map_saver.lua +++ b/rsc/scripts/map_saver.lua @@ -1,11 +1,15 @@ +local Region = require("map_system").Region + local mapSaver = {} -function mapSaver.Load(region) + +function mapSaver.Load(r) --empty - print("map_saver.lua:mapSaver.Load(region)") + io.write("map_saver:Load(", Region.GetX(r), ", ", Region.GetY(r), ")\n") end -function mapSaver.Save(region) +function mapSaver.Save(r) --empty - print("map_saver.lua:mapSaver.Save(region)") + io.write("map_saver:Save(", Region.GetX(r), ", ", Region.GetY(r), ")\n") end + --TODO: create a flexible saving & loading system return mapSaver \ No newline at end of file diff --git a/rsc/scripts/setup_server.lua b/rsc/scripts/setup_server.lua index 53c733f..8e498a3 100644 --- a/rsc/scripts/setup_server.lua +++ b/rsc/scripts/setup_server.lua @@ -1,10 +1,8 @@ print("Lua script check") -mapSystem = require "map_system" -mapMaker = require "map_maker" -mapSaver = require "map_saver" -roomSystem = require "room_system" -waypointSystem = require "waypoint_system" +mapMaker = require("map_maker") +mapSaver = require("map_saver") +roomSystem = require("room_system") local function dumpTable(t) print(t) @@ -15,53 +13,6 @@ end --NOTE: room 0 is the first that the client asks for, therefore it must exist 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) +roomSystem.Room.Initialize(overworld, mapSaver.Load, mapSaver.Save, mapMaker.DebugIsland, 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/entities/entity.cpp b/server/entities/entity.cpp index fcfa8aa..5587e81 100644 --- a/server/entities/entity.cpp +++ b/server/entities/entity.cpp @@ -33,14 +33,14 @@ Vector2 Entity::SetMotion(Vector2 v) { return motion = v; } -int Entity::GetRoomIndex() { +int Entity::GetRoomIndex() const { return roomIndex; } -Vector2 Entity::GetOrigin() { +Vector2 Entity::GetOrigin() const { return origin; } -Vector2 Entity::GetMotion() { +Vector2 Entity::GetMotion() const { return motion; } \ No newline at end of file diff --git a/server/entities/entity.hpp b/server/entities/entity.hpp index f71fbf9..6874a7e 100644 --- a/server/entities/entity.hpp +++ b/server/entities/entity.hpp @@ -32,9 +32,9 @@ public: Vector2 SetOrigin(Vector2 v); Vector2 SetMotion(Vector2 v); - int GetRoomIndex(); - Vector2 GetOrigin(); - Vector2 GetMotion(); + int GetRoomIndex() const; + Vector2 GetOrigin() const; + Vector2 GetMotion() const; protected: Entity() = default; diff --git a/server/linit.cpp b/server/linit.cpp index aaa449d..b460290 100644 --- a/server/linit.cpp +++ b/server/linit.cpp @@ -36,7 +36,9 @@ #include "lua.hpp" +#include "entity_api.hpp" #include "map_system_api.hpp" +#include "monster_system_api.hpp" #include "room_system_api.hpp" #include "waypoint_system_api.hpp" @@ -59,7 +61,9 @@ static const luaL_Reg loadedlibs[] = { //these libs are preloaded and must be required before used static const luaL_Reg preloadedlibs[] = { + {TORTUGA_ENTITY_API, openEntityAPI}, {TORTUGA_MAP_SYSTEM_API, openMapSystemAPI}, + {TORTUGA_MONSTER_SYSTEM_API, openMonsterSystemAPI}, {TORTUGA_ROOM_SYSTEM_API, openRoomSystemAPI}, {TORTUGA_WAYPOINT_SYSTEM_API, openWaypointSystemAPI}, {NULL, NULL} diff --git a/server/main.cpp b/server/main.cpp index a86f4f0..b7a8953 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -26,7 +26,6 @@ #include "character_manager.hpp" #include "client_manager.hpp" #include "config_utility.hpp" -#include "monster_manager.hpp" #include "room_manager.hpp" #include "udp_network_utility.hpp" #include "waypoint_manager.hpp" @@ -43,10 +42,8 @@ int main(int argc, char* argv[]) { CharacterManager::CreateSingleton(); ClientManager::CreateSingleton(); ConfigUtility::CreateSingleton(); - MonsterManager::CreateSingleton(); RoomManager::CreateSingleton(); UDPNetworkUtility::CreateSingleton(); - WaypointManager::CreateSingleton(); //call the server's routines ServerApplication::CreateSingleton(); @@ -63,10 +60,8 @@ int main(int argc, char* argv[]) { CharacterManager::DeleteSingleton(); ClientManager::DeleteSingleton(); ConfigUtility::DeleteSingleton(); - MonsterManager::DeleteSingleton(); RoomManager::DeleteSingleton(); UDPNetworkUtility::DeleteSingleton(); - WaypointManager::DeleteSingleton(); } catch(exception& e) { cerr << "Fatal exception thrown: " << e.what() << endl; diff --git a/server/monsters/monster_api.cpp b/server/monsters/monster_api.cpp index 3baec56..06d6551 100644 --- a/server/monsters/monster_api.cpp +++ b/server/monsters/monster_api.cpp @@ -23,11 +23,66 @@ #include "monster_data.hpp" +#include "entity_api.hpp" + +static int setAvatar(lua_State* L) { + MonsterData* monster = static_cast(lua_touserdata(L, 1)); + monster->SetAvatar(lua_tostring(L, 2)); + //TODO: send an update to the clients? + return 0; +} + +static int getAvatar(lua_State* L) { + MonsterData* monster = static_cast(lua_touserdata(L, 1)); + lua_pushstring(L, monster->GetAvatar().c_str()); + return 1; +} + +static int setScript(lua_State* L) { + MonsterData* monster = static_cast(lua_touserdata(L, 1)); + luaL_unref(L, LUA_REGISTRYINDEX, monster->GetScriptReference()); + monster->SetScriptReference(luaL_ref(L, LUA_REGISTRYINDEX)); + return 0; +} + +static int getScript(lua_State* L) { + MonsterData* monster = static_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, monster->GetScriptReference()); + lua_gettable(L, LUA_REGISTRYINDEX); + return 1; +} + static const luaL_Reg monsterLib[] = { + {"SetAvatar", setAvatar}, + {"GetAvatar", getAvatar}, + {"SetScript", setScript}, + {"GetScript", getScript}, {nullptr, nullptr} }; LUAMOD_API int openMonsterAPI(lua_State* L) { + //the local table luaL_newlib(L, monsterLib); + + //get the parent table + luaL_requiref(L, TORTUGA_ENTITY_API, openEntityAPI, false); + + //clone the parent table into the local table + lua_pushnil(L); //first key + while(lua_next(L, -2)) { + //copy the key-value pair + lua_pushvalue(L, -2); + lua_pushvalue(L, -2); + + //push the copy to the local table + lua_settable(L, -6); + + //pop the original value before continuing + lua_pop(L, 1); + } + + //remove the parent table, leaving the expanded child table + lua_pop(L, 1); + return 1; } \ No newline at end of file diff --git a/server/monsters/monster_data.cpp b/server/monsters/monster_data.cpp index 7fda714..22f5252 100644 --- a/server/monsters/monster_data.cpp +++ b/server/monsters/monster_data.cpp @@ -25,14 +25,14 @@ std::string MonsterData::SetAvatar(std::string s) { return avatar = s; } -int MonsterData::SetScriptReference(int i) { - return scriptRef = i; -} - std::string MonsterData::GetAvatar() { return avatar; } +int MonsterData::SetScriptReference(int i) { + return scriptRef = i; +} + int MonsterData::GetScriptReference() { return scriptRef; } \ No newline at end of file diff --git a/server/monsters/monster_data.hpp b/server/monsters/monster_data.hpp index 034cebb..f02723b 100644 --- a/server/monsters/monster_data.hpp +++ b/server/monsters/monster_data.hpp @@ -32,9 +32,9 @@ public: ~MonsterData() = default; std::string SetAvatar(std::string); - int SetScriptReference(int); - std::string GetAvatar(); + + int SetScriptReference(int); int GetScriptReference(); private: diff --git a/server/monsters/monster_manager.cpp b/server/monsters/monster_manager.cpp index 0cc78ce..5717e45 100644 --- a/server/monsters/monster_manager.cpp +++ b/server/monsters/monster_manager.cpp @@ -21,26 +21,22 @@ */ #include "monster_manager.hpp" +MonsterManager::MonsterManager() { + //EMPTY +} + +MonsterManager::~MonsterManager() { + UnloadAll(); +} + int MonsterManager::Create(std::string) { //TODO } -int MonsterManager::Load(std::string) { - //TODO -} - -int MonsterManager::Save(int uid) { - //TODO -} - void MonsterManager::Unload(int uid) { //TODO } -void MonsterManager::Delete(int uid) { - //TODO -} - void MonsterManager::UnloadAll() { //TODO } @@ -57,22 +53,10 @@ int MonsterManager::GetLoadedCount() { //TODO } -int MonsterManager::GetTotalCount() { - //TODO -} - std::map* MonsterManager::GetContainer() { //TODO } -sqlite3* MonsterManager::SetDatabase(sqlite3* db) { - //TODO -} - -sqlite3* MonsterManager::GetDatabase() { - //TODO -} - lua_State* MonsterManager::SetLuaState(lua_State* L) { //TODO } @@ -80,3 +64,11 @@ lua_State* MonsterManager::SetLuaState(lua_State* L) { lua_State* MonsterManager::GetLuaState() { //TODO } + +sqlite3* MonsterManager::SetDatabase(sqlite3* db) { + //TODO +} + +sqlite3* MonsterManager::GetDatabase() { + //TODO +} diff --git a/server/monsters/monster_manager.hpp b/server/monsters/monster_manager.hpp index 83e799a..5d74e4c 100644 --- a/server/monsters/monster_manager.hpp +++ b/server/monsters/monster_manager.hpp @@ -23,7 +23,6 @@ #define MONSTERMANAGER_HPP_ #include "monster_data.hpp" -#include "singleton.hpp" #include "lua.hpp" #include "sqlite3.h" @@ -32,14 +31,14 @@ #include #include -class MonsterManager: public Singleton { +class MonsterManager { public: + MonsterManager(); + ~MonsterManager(); + //common public methods int Create(std::string); - int Load(std::string); - int Save(int uid); void Unload(int uid); - void Delete(int uid); void UnloadAll(); void UnloadIf(std::function)> fn); @@ -47,25 +46,19 @@ public: //accessors & mutators MonsterData* Get(int uid); int GetLoadedCount(); - int GetTotalCount(); std::map* GetContainer(); //hooks - sqlite3* SetDatabase(sqlite3* db); - sqlite3* GetDatabase(); lua_State* SetLuaState(lua_State* L); lua_State* GetLuaState(); + sqlite3* SetDatabase(sqlite3* db); + sqlite3* GetDatabase(); private: - friend Singleton; - - MonsterManager() = default; - ~MonsterManager() = default; - //members std::map elementMap; - sqlite3* database = nullptr; lua_State* lua = nullptr; + sqlite3* database = nullptr; }; #endif \ No newline at end of file diff --git a/server/monsters/monster_system_api.cpp b/server/monsters/monster_system_api.cpp new file mode 100644 index 0000000..2ecbf71 --- /dev/null +++ b/server/monsters/monster_system_api.cpp @@ -0,0 +1,55 @@ +/* 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. +*/ +#include "monster_system_api.hpp" + +//all monster API headers +#include "monster_api.hpp" +#include "monster_manager_api.hpp" + +//useful "globals" +//... + +//This mimics linit.c to create a nested collection of all monster modules. +static const luaL_Reg funcs[] = { + {nullptr, nullptr} +}; + +static const luaL_Reg libs[] = { + {"Monster", openMonsterAPI}, + {"MonsterManager", openMonsterManagerAPI}, + {nullptr, nullptr} +}; + +int openMonsterSystemAPI(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/common/map/tile_sheet_api.hpp b/server/monsters/monster_system_api.hpp similarity index 84% rename from common/map/tile_sheet_api.hpp rename to server/monsters/monster_system_api.hpp index 57c812e..843a5e7 100644 --- a/common/map/tile_sheet_api.hpp +++ b/server/monsters/monster_system_api.hpp @@ -19,12 +19,12 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#ifndef TILESHEETAPI_HPP_ -#define TILESHEETAPI_HPP_ +#ifndef MONSTERSYSTEMAPI_HPP_ +#define MONSTERSYSTEMAPI_HPP_ #include "lua.hpp" -#define TORTUGA_TILE_SHEET_NAME "tile_sheet" -LUAMOD_API int openTileSheetAPI(lua_State* L); +#define TORTUGA_MONSTER_SYSTEM_API "monster_system" +LUAMOD_API int openMonsterSystemAPI(lua_State* L); -#endif +#endif \ No newline at end of file diff --git a/server/rooms/makefile b/server/rooms/makefile index 514e483..a0dda5d 100644 --- a/server/rooms/makefile +++ b/server/rooms/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../entities ../server_utilities ../../common/map ../../common/utilities +INCLUDES+=. ../entities ../monsters ../server_utilities ../waypoints ../../common/map ../../common/utilities LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/server/rooms/room_api.cpp b/server/rooms/room_api.cpp index b6606f8..19b3a95 100644 --- a/server/rooms/room_api.cpp +++ b/server/rooms/room_api.cpp @@ -53,11 +53,21 @@ static int getPager(lua_State* L) { return 1; } +static int getMonsterMgr(lua_State* L) { + RoomData* room = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushlightuserdata(L, reinterpret_cast(room->GetMonsterMgr()) ); + return 1; +} + +static int getWaypointMgr(lua_State* L) { + RoomData* room = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushlightuserdata(L, reinterpret_cast(room->GetWaypointMgr()) ); + return 1; +} + static int initialize(lua_State* L) { - //set the members of the given room + //TODO: This could fit into the room system's globals RoomData* room = static_cast(lua_touserdata(L, 1)); - 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,11 +80,15 @@ static int initialize(lua_State* L) { } static const luaL_Reg roomLib[] = { - {"GetPager",getPager}, {"SetName", setRoomName}, {"GetName", getRoomName}, {"SetTileset", setTilesetName}, {"GetTileset", getTilesetName}, + + {"GetPager",getPager}, + {"GetMonsterMgr",getMonsterMgr}, + {"GetWaypointMgr",getWaypointMgr}, + {"Initialize", initialize}, {nullptr, nullptr} }; diff --git a/server/rooms/room_data.cpp b/server/rooms/room_data.cpp index 8919564..87a9502 100644 --- a/server/rooms/room_data.cpp +++ b/server/rooms/room_data.cpp @@ -41,6 +41,14 @@ RegionPagerLua* RoomData::GetPager() { return &pager; } +MonsterManager* RoomData::GetMonsterMgr() { + return &monsterMgr; +} + +WaypointManager* RoomData::GetWaypointMgr() { + return &waypointMgr; +} + std::list* RoomData::GetEntityList() { return &entityList; } diff --git a/server/rooms/room_data.hpp b/server/rooms/room_data.hpp index 8a8e094..b5d9d9f 100644 --- a/server/rooms/room_data.hpp +++ b/server/rooms/room_data.hpp @@ -23,7 +23,9 @@ #define ROOMDATA_HPP_ #include "entity.hpp" +#include "monster_manager.hpp" #include "region_pager_lua.hpp" +#include "waypoint_manager.hpp" #include "lua.hpp" @@ -43,6 +45,8 @@ public: std::string GetTileset(); RegionPagerLua* GetPager(); + MonsterManager* GetMonsterMgr(); + WaypointManager* GetWaypointMgr(); std::list* GetEntityList(); //TODO: triggers for unload, save, per-second, player enter, player exit, etc. @@ -55,6 +59,8 @@ private: std::string tilesetName; RegionPagerLua pager; + MonsterManager monsterMgr; + WaypointManager waypointMgr; std::list entityList; }; diff --git a/server/rooms/room_manager.cpp b/server/rooms/room_manager.cpp index 56a3f65..65df378 100644 --- a/server/rooms/room_manager.cpp +++ b/server/rooms/room_manager.cpp @@ -36,6 +36,9 @@ int RoomManager::Create(std::string roomName, std::string tileset) { newRoom->SetTileset(tileset); newRoom->pager.SetLuaState(lua); + newRoom->monsterMgr.SetLuaState(lua); + newRoom->monsterMgr.SetDatabase(database); + newRoom->waypointMgr.SetLuaState(lua); //finish the routine return counter++; @@ -57,6 +60,37 @@ void RoomManager::UnloadIf(std::functionGetRoomIndex()); + + if (!room) { + throw(std::runtime_error("Failed to push an entity to a non-existant room")); + } + + room->entityList.push_back(entity); +} + +void RoomManager::PopEntity(Entity const* entity) { + //NOTE: to pop an entity from a room, the entity must first exist + if (!entity) { + throw(std::runtime_error("Failed to pop a null entity to a room")); + } + + RoomData* room = Get(entity->GetRoomIndex()); + + if (!room) { + throw(std::runtime_error("Failed to pop an entity to a non-existant room")); + } + + room->entityList.remove_if([entity](Entity* ptr) { + return entity == ptr; + }); +} + RoomData* RoomManager::Get(int uid) { std::map::iterator it = elementMap.find(uid); @@ -91,3 +125,11 @@ lua_State* RoomManager::SetLuaState(lua_State* L) { lua_State* RoomManager::GetLuaState() { return lua; } + +sqlite3* RoomManager::SetDatabase(sqlite3* db) { + return database = db; +} + +sqlite3* RoomManager::GetDatabase() { + return database; +} diff --git a/server/rooms/room_manager.hpp b/server/rooms/room_manager.hpp index aeac14b..1b51c23 100644 --- a/server/rooms/room_manager.hpp +++ b/server/rooms/room_manager.hpp @@ -22,10 +22,12 @@ #ifndef ROOMMANAGER_HPP_ #define ROOMMANAGER_HPP_ +#include "entity.hpp" #include "room_data.hpp" #include "singleton.hpp" #include "lua.hpp" +#include "sqlite3.h" #include #include @@ -38,6 +40,9 @@ public: void UnloadAll(); void UnloadIf(std::function)> fn); + void PushEntity(Entity* entity); + void PopEntity(Entity const* entity); + //accessors and mutators RoomData* Get(int uid); RoomData* Get(std::string name); @@ -47,6 +52,8 @@ public: //hooks lua_State* SetLuaState(lua_State* L); lua_State* GetLuaState(); + sqlite3* SetDatabase(sqlite3* db); + sqlite3* GetDatabase(); private: friend Singleton; @@ -57,6 +64,7 @@ private: //members std::map elementMap; lua_State* lua = nullptr; + sqlite3* database = nullptr; int counter = 0; }; diff --git a/server/server_application.hpp b/server/server_application.hpp index f8c6d32..2756be3 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -28,7 +28,6 @@ #include "client_manager.hpp" #include "monster_manager.hpp" #include "room_manager.hpp" -#include "waypoint_manager.hpp" //utilities #include "config_utility.hpp" @@ -115,12 +114,10 @@ private: lua_State* luaState = nullptr; //ugly references; I hate this + ClientManager& clientMgr = ClientManager::GetSingleton(); AccountManager& accountMgr = AccountManager::GetSingleton(); CharacterManager& characterMgr = CharacterManager::GetSingleton(); - ClientManager& clientMgr = ClientManager::GetSingleton(); - MonsterManager& monsterMgr = MonsterManager::GetSingleton(); RoomManager& roomMgr = RoomManager::GetSingleton(); - WaypointManager& waypointMgr = WaypointManager::GetSingleton(); ConfigUtility& config = ConfigUtility::GetSingleton(); UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton(); diff --git a/server/server_character_methods.cpp b/server/server_character_methods.cpp index d123d8e..610ec2d 100644 --- a/server/server_character_methods.cpp +++ b/server/server_character_methods.cpp @@ -45,6 +45,9 @@ void ServerApplication::HandleCharacterCreate(CharacterPacket* const argPacket) return; } + //push to the rooms + roomMgr.PushEntity(characterMgr.Get(characterIndex)); + //pump this character to all clients CharacterPacket newPacket; CopyCharacterToPacket(&newPacket, characterIndex); @@ -86,6 +89,9 @@ void ServerApplication::HandleCharacterDelete(CharacterPacket* const argPacket) return; } + //pop from the rooms + roomMgr.PopEntity(characterMgr.Get(characterIndex)); + //delete the character characterMgr.Delete(characterIndex); @@ -119,6 +125,9 @@ void ServerApplication::HandleCharacterLoad(CharacterPacket* const argPacket) { return; } + //push to the rooms + roomMgr.PushEntity(characterMgr.Get(characterIndex)); + //pump this character to all clients CharacterPacket newPacket; CopyCharacterToPacket(&newPacket, characterIndex); @@ -149,6 +158,9 @@ void ServerApplication::HandleCharacterUnload(CharacterPacket* const argPacket) return; } + //pop from the rooms + roomMgr.PopEntity(characterData); + //unload the character characterMgr.Unload(argPacket->characterIndex); @@ -190,11 +202,17 @@ void ServerApplication::HandleCharacterSetRoom(CharacterPacket* const argPacket) return; } + //pop from the old room + roomMgr.PopEntity(characterData); + //set the character's room, zero it's origin, zero it's motion characterData->SetRoomIndex(argPacket->roomIndex); characterData->SetOrigin({0, 0}); characterData->SetMotion({0, 0}); + //push to the new room + roomMgr.PushEntity(characterData); + //update the clients CharacterPacket newPacket; CopyCharacterToPacket(&newPacket, argPacket->characterIndex); diff --git a/server/server_logic.cpp b/server/server_logic.cpp index ab3eb2b..d4d96fa 100644 --- a/server/server_logic.cpp +++ b/server/server_logic.cpp @@ -105,7 +105,7 @@ void ServerApplication::Init(int argc, char* argv[]) { characterMgr.SetDatabase(database); roomMgr.SetLuaState(luaState); - waypointMgr.SetLuaState(luaState); + roomMgr.SetDatabase(database); std::cout << "Internal managers initialized" << std::endl; @@ -202,9 +202,7 @@ void ServerApplication::Quit() { accountMgr.UnloadAll(); characterMgr.UnloadAll(); clientMgr.UnloadAll(); - monsterMgr.UnloadAll(); roomMgr.UnloadAll(); - waypointMgr.UnloadAll(); //APIs lua_close(luaState); diff --git a/server/server_methods.cpp b/server/server_methods.cpp index e8f197f..7222ef0 100644 --- a/server/server_methods.cpp +++ b/server/server_methods.cpp @@ -149,6 +149,9 @@ void ServerApplication::FullCharacterUnload(int index) { return false; } + //pop from the rooms + roomMgr.PopEntity(&character.second); + //pump character unload CharacterPacket newPacket; newPacket.type = SerialPacketType::CHARACTER_DELETE; diff --git a/server/waypoints/waypoint_api.cpp b/server/waypoints/waypoint_api.cpp index 6059f69..cfc8191 100644 --- a/server/waypoints/waypoint_api.cpp +++ b/server/waypoints/waypoint_api.cpp @@ -23,8 +23,65 @@ #include "waypoint_data.hpp" -//TODO: Can I alias the entity API for this? +//origin +static int setOrigin(lua_State* L) { + WaypointData* waypoint = static_cast(lua_touserdata(L, 1)); + waypoint->SetOrigin(Vector2(lua_tonumber(L, 2), lua_tonumber(L, 3))); + return 0; +} + +static int getOrigin(lua_State* L) { + WaypointData* waypoint = static_cast(lua_touserdata(L, 1)); + lua_pushnumber(L, waypoint->GetOrigin().x); + lua_pushnumber(L, waypoint->GetOrigin().y); + return 2; +} + +//bounds +static int setBoundingBox(lua_State* L) { + WaypointData* waypoint = static_cast(lua_touserdata(L, 1)); + waypoint->SetBoundingBox(BoundingBox( + lua_tonumber(L, 2), + lua_tonumber(L, 3), + lua_tonumber(L, 4), + lua_tonumber(L, 5) + )); + return 0; +} + +static int getBoundingBox(lua_State* L) { + WaypointData* waypoint = static_cast(lua_touserdata(L, 1)); + lua_pushnumber(L, waypoint->GetBoundingBox().x); + lua_pushnumber(L, waypoint->GetBoundingBox().y); + lua_pushnumber(L, waypoint->GetBoundingBox().w); + lua_pushnumber(L, waypoint->GetBoundingBox().h); + return 4; +} + +//triggers +static int setTriggerReference(lua_State* L) { + WaypointData* waypoint = static_cast(lua_touserdata(L, 1)); + luaL_unref(L, LUA_REGISTRYINDEX, waypoint->GetTriggerReference()); + waypoint->SetTriggerReference(luaL_ref(L, LUA_REGISTRYINDEX)); + return 0; +} + +static int getTriggerReference(lua_State* L) { + WaypointData* waypoint = static_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, waypoint->GetTriggerReference()); + lua_gettable(L, LUA_REGISTRYINDEX); + return 1; +} + static const luaL_Reg waypointLib[] = { + {"SetOrigin",setOrigin}, + {"GetOrigin",getOrigin}, + + {"SetBounds",setBoundingBox}, + {"GetBounds",getBoundingBox}, + + {"SetTrigger",setTriggerReference}, + {"GetTrigger",getTriggerReference}, {nullptr, nullptr} }; diff --git a/server/waypoints/waypoint_data.cpp b/server/waypoints/waypoint_data.cpp index b720e1d..3225834 100644 --- a/server/waypoints/waypoint_data.cpp +++ b/server/waypoints/waypoint_data.cpp @@ -27,4 +27,20 @@ int WaypointData::SetTriggerReference(int i) { int WaypointData::GetTriggerReference() { return triggerRef; -} \ No newline at end of file +} + +BoundingBox WaypointData::SetBoundingBox(BoundingBox b) { + return bounds = b; +} + +BoundingBox WaypointData::GetBoundingBox() { + return bounds; +} + +Vector2 WaypointData::SetOrigin(Vector2 v) { + return origin = v; +} + +Vector2 WaypointData::GetOrigin() { + return origin; +} diff --git a/server/waypoints/waypoint_data.hpp b/server/waypoints/waypoint_data.hpp index 68e4b0b..6104847 100644 --- a/server/waypoints/waypoint_data.hpp +++ b/server/waypoints/waypoint_data.hpp @@ -22,23 +22,32 @@ #ifndef WAYPOINTDATA_HPP_ #define WAYPOINTDATA_HPP_ -#include "entity.hpp" +#include "bounding_box.hpp" +#include "vector2.hpp" #include "lua.hpp" #include -class WaypointData: public Entity { +class WaypointData { public: WaypointData() = default; ~WaypointData() = default; + Vector2 SetOrigin(Vector2 v); + Vector2 GetOrigin(); + + BoundingBox SetBoundingBox(BoundingBox b); + BoundingBox GetBoundingBox(); + int SetTriggerReference(int i); int GetTriggerReference(); private: friend class WaypointManager; + Vector2 origin; + BoundingBox bounds; int triggerRef = LUA_NOREF; }; diff --git a/server/waypoints/waypoint_manager.cpp b/server/waypoints/waypoint_manager.cpp index a89165b..f81ad90 100644 --- a/server/waypoints/waypoint_manager.cpp +++ b/server/waypoints/waypoint_manager.cpp @@ -21,46 +21,78 @@ */ #include "waypoint_manager.hpp" +WaypointManager::WaypointManager() { + //EMPTY +} + +WaypointManager::~WaypointManager() { + UnloadAll(); +} + int WaypointManager::Create() { - //TODO + //implicitly creates the element + WaypointData& waypointData = elementMap[counter]; + + //no real values set + waypointData.origin = {0, 0}; + waypointData.bounds = {0, 0, 0, 0}; + + return counter++; } -int WaypointManager::Load() { - //TODO -} +int WaypointManager::Create(Vector2 origin, BoundingBox bounds) { + //implicitly creates the element + WaypointData& waypointData = elementMap[counter]; -int WaypointManager::Save(int uid) { - //TODO + waypointData.origin = origin; + waypointData.bounds = bounds; + + return counter++; } void WaypointManager::Unload(int uid) { - //TODO -} - -void WaypointManager::Delete(int uid) { - //TODO + elementMap.erase(uid); } void WaypointManager::UnloadAll() { - //TODO + elementMap.clear(); } void WaypointManager::UnloadIf(std::function)> fn) { - //TODO + std::map::iterator it = elementMap.begin(); + while (it != elementMap.end()) { + if (fn(*it)) { + it = elementMap.erase(it); + } + else { + ++it; + } + } } WaypointData* WaypointManager::Get(int uid) { - //TODO + std::map::iterator it = elementMap.find(uid); + + if (it == elementMap.end()) { + return nullptr; + } + + return &it->second; } int WaypointManager::GetLoadedCount() { - //TODO -} - -int WaypointManager::GetTotalCount() { - //TODO + return elementMap.size(); } std::map* WaypointManager::GetContainer() { - //TODO + return &elementMap; } + +//hooks +lua_State* WaypointManager::SetLuaState(lua_State* L) { + return lua = L; +} + +lua_State* WaypointManager::GetLuaState() { + return lua; +} \ No newline at end of file diff --git a/server/waypoints/waypoint_manager.hpp b/server/waypoints/waypoint_manager.hpp index b364c27..91bc3d0 100644 --- a/server/waypoints/waypoint_manager.hpp +++ b/server/waypoints/waypoint_manager.hpp @@ -22,9 +22,9 @@ #ifndef WAYPOINTMANAGER_HPP_ #define WAYPOINTMANAGER_HPP_ -#include "waypoint_data.hpp" -#include "singleton.hpp" +#include "bounding_box.hpp" #include "vector2.hpp" +#include "waypoint_data.hpp" #include "lua.hpp" @@ -32,15 +32,15 @@ #include #include -//TODO: should waypoints be managed on a per-room basis? -class WaypointManager: public Singleton { +class WaypointManager { public: + WaypointManager(); + ~WaypointManager(); + //common public methods int Create(); - int Load(); - int Save(int uid); + int Create(Vector2 origin, BoundingBox bounds); void Unload(int uid); - void Delete(int uid); void UnloadAll(); void UnloadIf(std::function)> fn); @@ -48,19 +48,13 @@ public: //accessors & mutators 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; } + lua_State* SetLuaState(lua_State* L); + lua_State* GetLuaState(); private: - friend Singleton; - - WaypointManager() = default; - ~WaypointManager() = default; - //members std::map elementMap; lua_State* lua = nullptr; diff --git a/server/waypoints/waypoint_manager_api.cpp b/server/waypoints/waypoint_manager_api.cpp index c99782a..447c666 100644 --- a/server/waypoints/waypoint_manager_api.cpp +++ b/server/waypoints/waypoint_manager_api.cpp @@ -23,7 +23,35 @@ #include "waypoint_manager.hpp" +//TODO: figure out a way to iterate through elements of managers from lua + +static int create(lua_State* L) { + WaypointManager* mgr = static_cast(lua_touserdata(L, 1)); + //TODO +} + +static int unload(lua_State* L) { + WaypointManager* mgr = static_cast(lua_touserdata(L, 1)); + //TODO +} + +static int getWaypoint(lua_State* L) { + WaypointManager* mgr = static_cast(lua_touserdata(L, 1)); + lua_pushlightuserdata(L, mgr->Get(lua_tointeger(L, 2))); + return 1; +} + +static int getLoadedCount(lua_State* L) { + WaypointManager* mgr = static_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, mgr->GetLoadedCount()); + return 1; +} + static const luaL_Reg waypointManagerLib[] = { + {"Create",create}, + {"Unload",unload}, + {"GetWaypoint",getWaypoint}, + {"GetCount",getLoadedCount}, {nullptr, nullptr} }; diff --git a/todo.txt b/todo.txt index 2a51e6b..3e19264 100644 --- a/todo.txt +++ b/todo.txt @@ -17,3 +17,4 @@ TODO: Make a way for the server owner to control the server directly TODO: The TileSheet class should implement the surface itself TODO: Time delay for requesting region packets TODO: A proper logging system +TODO: Fix the const-ness of accessors \ No newline at end of file