diff --git a/client/gameplay_scenes/world_characters.cpp b/client/gameplay_scenes/world_characters.cpp index b0ada57..8a7628f 100644 --- a/client/gameplay_scenes/world_characters.cpp +++ b/client/gameplay_scenes/world_characters.cpp @@ -87,6 +87,15 @@ void World::hCharacterCreate(CharacterPacket* const argPacket) { //focus on this character's info characterIndex = argPacket->characterIndex; roomIndex = argPacket->roomIndex; + + //query the world state + CharacterPacket newPacket; + memset(&newPacket, 0, MAX_PACKET_SIZE); + newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS; //TODO: (2) the EXISTS and LOCATION queries are backwards? + newPacket.roomIndex = roomIndex; + network.SendTo(Channels::SERVER, &newPacket); + newPacket.type = SerialPacketType::QUERY_MONSTER_EXISTS; + network.SendTo(Channels::SERVER, &newPacket); } //debug @@ -110,10 +119,14 @@ void World::hCharacterDelete(CharacterPacket* const argPacket) { //clear the room roomIndex = -1; + regionPager.UnloadAll(); + characterMap.clear(); + monsterMap.clear(); + } + else { + //remove this character + characterMap.erase(characterIt); } - - //remove this character - characterMap.erase(characterIt); //debug std::cout << "Character Delete, total: " << characterMap.size() << std::endl; @@ -121,9 +134,9 @@ void World::hCharacterDelete(CharacterPacket* const argPacket) { void World::hQueryCharacterExists(CharacterPacket* const argPacket) { //prevent a double message about this player's character - if (argPacket->accountIndex == accountIndex) { - return; - } +// if (argPacket->accountIndex == accountIndex) { +// return; +// } //ignore characters in a different room (sub-optimal) if (argPacket->roomIndex != roomIndex) { diff --git a/client/gameplay_scenes/world_logic.cpp b/client/gameplay_scenes/world_logic.cpp index 1085e84..5d7df57 100644 --- a/client/gameplay_scenes/world_logic.cpp +++ b/client/gameplay_scenes/world_logic.cpp @@ -71,6 +71,7 @@ World::World(int* const argClientIndex, int* const argAccountIndex): newPacket.accountIndex = accountIndex; network.SendTo(Channels::SERVER, &newPacket); + //TODO: (2) replace this duplication with a request for just this player's character //query the world state memset(&newPacket, 0, MAX_PACKET_SIZE); newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS; diff --git a/rsc/scripts/map_maker.lua b/rsc/scripts/map_maker.lua index d24f056..7b1cbfd 100644 --- a/rsc/scripts/map_maker.lua +++ b/rsc/scripts/map_maker.lua @@ -93,4 +93,16 @@ function mapMaker.DebugIsland(r) mapMaker.SmoothEdgesSimple(r) end +function mapMaker.DebugGrassland(r) + --all dirt + for i = 1, regionAPI.GetWidth(r) do + for j = 1, regionAPI.GetHeight(r) do + regionAPI.SetTile(r, i, j, 1, mapMaker.grass) + end + end + + --A generic edge system +-- mapMaker.SmoothEdgesSimple(r) +end + return mapMaker \ No newline at end of file diff --git a/rsc/scripts/setup_server.lua b/rsc/scripts/setup_server.lua index ebceded..c251851 100644 --- a/rsc/scripts/setup_server.lua +++ b/rsc/scripts/setup_server.lua @@ -17,7 +17,7 @@ roomManagerAPI.SetOnCreate(function(room, index) roomAPI.SetOnTick(room, function(room) roomAPI.ForEachCharacter(room, function(character) - characterAPI.SetRoomIndex(character, 0) + -- end) end) end) @@ -27,8 +27,10 @@ roomManagerAPI.SetOnUnload(function(room, index) end) --NOTE: room 0 is the first that the client asks for, therefore it must exist -local overworld, uid = roomManagerAPI.CreateRoom("overworld", "overworld.bmp") +local overworld, uidOne = roomManagerAPI.CreateRoom("overworld", "overworld.bmp") roomAPI.Initialize(overworld, mapSaver.Load, mapSaver.Save, mapMaker.DebugIsland, mapSaver.Save) +local underworld, uidTwo = roomManagerAPI.CreateRoom("underworld", "overworld.bmp") +roomAPI.Initialize(underworld, mapSaver.Load, mapSaver.Save, mapMaker.DebugGrassland, mapSaver.Save) --debug: test the trigger system regionPagerAPI = require("region_pager") @@ -38,9 +40,9 @@ function createTrigger(handle, room, x, y, script) local pager = roomAPI.GetPager(room) --place the indicator tile - regionPagerAPI.SetTile(pager, x, y, 0, mapMaker.dirt) - regionPagerAPI.SetTile(pager, x, y, 1, mapMaker.blank) - regionPagerAPI.SetTile(pager, x, y, 2, mapMaker.blank) + regionPagerAPI.SetTile(pager, x / 32, y / 32, 0, mapMaker.dirt) + regionPagerAPI.SetTile(pager, x / 32, y / 32, 1, mapMaker.blank) + regionPagerAPI.SetTile(pager, x / 32, y / 32, 2, mapMaker.blank) --create the trigger object triggerManagerAPI.Create( @@ -50,14 +52,41 @@ function createTrigger(handle, room, x, y, script) ) end ---simple teleporter -createTrigger("trigger 1", overworld, 0, 0, function(entity) +--simple door pair +createTrigger("door 1", overworld, 128, -128, function(entity) if entityAPI.GetType(entity) ~= "character" then return end + + print("mark 1") local x, y = characterAPI.GetOrigin(entity) - characterAPI.SetOrigin(entity, x, y + 128) + print("mark 2") + characterAPI.SetRoomIndex(entity, uidTwo) --TODO: (1) take exit coordinates as a parameter + print("mark 3") + characterAPI.SetOrigin(entity, 0, 0) + print("mark 4") networkAPI.PumpCharacterUpdate(entity) + print("mark 5") + + return false +end) + +createTrigger("door 1", underworld, 128, -128, function(entity) + if entityAPI.GetType(entity) ~= "character" then + return + end + + print("mark 6") + local x, y = characterAPI.GetOrigin(entity) + print("mark 7") + characterAPI.SetRoomIndex(entity, uidOne) + print("mark 8") + characterAPI.SetOrigin(entity, 0, 0) + print("mark 9") + networkAPI.PumpCharacterUpdate(entity) + print("mark 10") + + return false end) print("Finished the lua script") diff --git a/server/characters/character_api.cpp b/server/characters/character_api.cpp index 229d297..985366b 100644 --- a/server/characters/character_api.cpp +++ b/server/characters/character_api.cpp @@ -22,14 +22,37 @@ #include "character_api.hpp" #include "character_data.hpp" +#include "character_manager.hpp" #include "entity_api.hpp" #include "room_manager.hpp" #include "server_utilities.hpp" -static int setRoomIndex(lua_State* L) { +#include + +static int setRoomIndex(lua_State* L) { //TODO: (1) take the room userdata as a parameter //NOTE: type-dependant calls to various API functions, see bug #43 + + //reverse engineer the character index + int characterIndex = -1; CharacterData* character = static_cast(lua_touserdata(L, 1)); - pumpAndChangeRooms(character, lua_tointeger(L, 2), -1); //TODO: (0) undefined behavior without character index + int roomIndex = lua_tointeger(L, 2); + RoomData* roomData = RoomManager::GetSingleton().Get(roomIndex); + + CharacterManager& characterMgr = CharacterManager::GetSingleton(); + + for (auto& it : *characterMgr.GetContainer()) { + if (character == &it.second) { + characterIndex = it.first; + break; + } + } + + //error checking + if (characterIndex == -1) { + throw(std::runtime_error("Failed to find character index by reference")); + } + + pumpAndChangeRooms(character, lua_tointeger(L, 2), characterIndex); return 0; } diff --git a/server/characters/makefile b/server/characters/makefile index 998ca93..f686f51 100644 --- a/server/characters/makefile +++ b/server/characters/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../entities ../monsters ../rooms ../server_utilities ../triggers ../../common/gameplay ../../common/map ../../common/utilities +INCLUDES+=. ../entities ../monsters ../rooms ../server_utilities ../triggers ../../common/gameplay ../../common/map ../../common/network ../../common/network/packet_types ../../common/utilities LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/server/rooms/room_data.cpp b/server/rooms/room_data.cpp index 1148a53..911e9e7 100644 --- a/server/rooms/room_data.cpp +++ b/server/rooms/room_data.cpp @@ -54,13 +54,25 @@ void RoomData::RunFrame() { if ( itBox.CheckOverlap(hitBox) ) { //trigger script lua_rawgeti(lua, LUA_REGISTRYINDEX, it.second.GetScriptReference()); - lua_pushlightuserdata(lua, character); //TODO: (1) entity type + lua_pushlightuserdata(lua, character); + + //BUG: (0) + + std::cout << "running scripts" << std::endl; //run the script - if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { + //BUGFIX: changing the character's room via lua invalidates the list, therefore, the script much signal for an early exit + //TODO: (2) fix this somehow (operate on a stack?) + if (lua_pcall(lua, 1, 1, 0) != LUA_OK) { //error throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } + + //true = safe to continue, false = exit early + if (!lua_toboolean(lua, -1)) { + std::cout << "Warning!: Early abort" << std::endl; + return; + } } } // for (auto& monster : *monsterMgr.GetContainer()) {