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
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);
}
//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) {
+1
View File
@@ -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;
+12
View File
@@ -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
+37 -8
View File
@@ -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")
+25 -2
View File
@@ -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 <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
//reverse engineer the character index
int characterIndex = -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;
}
+1 -1
View File
@@ -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))
+14 -2
View File
@@ -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()) {