Room transitions are working smoothly, read more

Although the room transitions are working fairly well, it is still heavy
handed, and a number of optimizations can be done. On the whole, this
needs a review.
This commit is contained in:
Kayne Ruse
2015-03-09 23:26:37 +11:00
parent 81b3769188
commit 4d71d4cc40
7 changed files with 109 additions and 19 deletions
+17 -4
View File
@@ -87,6 +87,15 @@ void World::hCharacterCreate(CharacterPacket* const argPacket) {
//focus on this character's info //focus on this character's info
characterIndex = argPacket->characterIndex; characterIndex = argPacket->characterIndex;
roomIndex = argPacket->roomIndex; 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 //debug
@@ -110,10 +119,14 @@ void World::hCharacterDelete(CharacterPacket* const argPacket) {
//clear the room //clear the room
roomIndex = -1; roomIndex = -1;
regionPager.UnloadAll();
characterMap.clear();
monsterMap.clear();
} }
else {
//remove this character //remove this character
characterMap.erase(characterIt); characterMap.erase(characterIt);
}
//debug //debug
std::cout << "Character Delete, total: " << characterMap.size() << std::endl; 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) { void World::hQueryCharacterExists(CharacterPacket* const argPacket) {
//prevent a double message about this player's character //prevent a double message about this player's character
if (argPacket->accountIndex == accountIndex) { // if (argPacket->accountIndex == accountIndex) {
return; // return;
} // }
//ignore characters in a different room (sub-optimal) //ignore characters in a different room (sub-optimal)
if (argPacket->roomIndex != roomIndex) { if (argPacket->roomIndex != roomIndex) {
+1
View File
@@ -71,6 +71,7 @@ World::World(int* const argClientIndex, int* const argAccountIndex):
newPacket.accountIndex = accountIndex; newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket); network.SendTo(Channels::SERVER, &newPacket);
//TODO: (2) replace this duplication with a request for just this player's character
//query the world state //query the world state
memset(&newPacket, 0, MAX_PACKET_SIZE); memset(&newPacket, 0, MAX_PACKET_SIZE);
newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS; newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS;
+12
View File
@@ -93,4 +93,16 @@ function mapMaker.DebugIsland(r)
mapMaker.SmoothEdgesSimple(r) mapMaker.SmoothEdgesSimple(r)
end 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 return mapMaker
+37 -8
View File
@@ -17,7 +17,7 @@ roomManagerAPI.SetOnCreate(function(room, index)
roomAPI.SetOnTick(room, function(room) roomAPI.SetOnTick(room, function(room)
roomAPI.ForEachCharacter(room, function(character) roomAPI.ForEachCharacter(room, function(character)
characterAPI.SetRoomIndex(character, 0) --
end) end)
end) end)
end) end)
@@ -27,8 +27,10 @@ roomManagerAPI.SetOnUnload(function(room, index)
end) end)
--NOTE: room 0 is the first that the client asks for, therefore it must exist --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) 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 --debug: test the trigger system
regionPagerAPI = require("region_pager") regionPagerAPI = require("region_pager")
@@ -38,9 +40,9 @@ function createTrigger(handle, room, x, y, script)
local pager = roomAPI.GetPager(room) local pager = roomAPI.GetPager(room)
--place the indicator tile --place the indicator tile
regionPagerAPI.SetTile(pager, x, y, 0, mapMaker.dirt) regionPagerAPI.SetTile(pager, x / 32, y / 32, 0, mapMaker.dirt)
regionPagerAPI.SetTile(pager, x, y, 1, mapMaker.blank) regionPagerAPI.SetTile(pager, x / 32, y / 32, 1, mapMaker.blank)
regionPagerAPI.SetTile(pager, x, y, 2, mapMaker.blank) regionPagerAPI.SetTile(pager, x / 32, y / 32, 2, mapMaker.blank)
--create the trigger object --create the trigger object
triggerManagerAPI.Create( triggerManagerAPI.Create(
@@ -50,14 +52,41 @@ function createTrigger(handle, room, x, y, script)
) )
end end
--simple teleporter --simple door pair
createTrigger("trigger 1", overworld, 0, 0, function(entity) createTrigger("door 1", overworld, 128, -128, function(entity)
if entityAPI.GetType(entity) ~= "character" then if entityAPI.GetType(entity) ~= "character" then
return return
end end
print("mark 1")
local x, y = characterAPI.GetOrigin(entity) 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) 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) end)
print("Finished the lua script") print("Finished the lua script")
+25 -2
View File
@@ -22,14 +22,37 @@
#include "character_api.hpp" #include "character_api.hpp"
#include "character_data.hpp" #include "character_data.hpp"
#include "character_manager.hpp"
#include "entity_api.hpp" #include "entity_api.hpp"
#include "room_manager.hpp" #include "room_manager.hpp"
#include "server_utilities.hpp" #include "server_utilities.hpp"
static int setRoomIndex(lua_State* L) { #include <stdexcept>
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 //NOTE: type-dependant calls to various API functions, see bug #43
//reverse engineer the character index
int characterIndex = -1;
CharacterData* character = static_cast<CharacterData*>(lua_touserdata(L, 1)); CharacterData* character = static_cast<CharacterData*>(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; return 0;
} }
+1 -1
View File
@@ -1,5 +1,5 @@
#config #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+= LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+14 -2
View File
@@ -54,13 +54,25 @@ void RoomData::RunFrame() {
if ( itBox.CheckOverlap(hitBox) ) { if ( itBox.CheckOverlap(hitBox) ) {
//trigger script //trigger script
lua_rawgeti(lua, LUA_REGISTRYINDEX, it.second.GetScriptReference()); 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 //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 //error
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); 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()) { // for (auto& monster : *monsterMgr.GetContainer()) {