Compare commits

...

6 Commits

Author SHA1 Message Date
Kayne Ruse f9936f6107 Fixed bin directory 2016-04-15 00:22:53 +10:00
Kayne Ruse 905af46731 Adjusted file names for case sensitivity 2016-04-15 00:17:13 +10:00
Kayne Ruse 8b0bc76a9f Fixed a script 2016-04-14 23:42:11 +10:00
Kayne Ruse fb2d49f1e0 Added respawning rabbits 2016-04-14 23:33:39 +10:00
Kayne Ruse cc6981e35f Refined culling logic, added periodic query 2016-04-14 22:56:15 +10:00
Kayne Ruse f9a5f60969 Try a different approach for creature deletion
This works almost instantly, as opposed to the refactored version, which
takes nearly a second, or more.
2016-04-14 21:52:44 +10:00
33 changed files with 164 additions and 51 deletions
+21 -9
View File
@@ -22,7 +22,7 @@
#include "barrier_manager.hpp" #include "barrier_manager.hpp"
void BarrierManager::DrawTo(SDL_Renderer* const dest, Sint16 x, Sint16 y, double scaleX, double scaleY) { void BarrierManager::DrawTo(SDL_Renderer* const dest, Sint16 x, Sint16 y, double scaleX, double scaleY) {
for (auto& it : barrierMap) { for (auto& it : elementMap) {
it.second.DrawTo(dest, x, y); it.second.DrawTo(dest, x, y);
} }
} }
@@ -47,26 +47,38 @@ void BarrierManager::UnloadTemplateImages() {
} }
BaseBarrier* BarrierManager::Create(int index) { BaseBarrier* BarrierManager::Create(int index) {
barrierMap.emplace(index, BaseBarrier(baseImage, templateImages)); elementMap.emplace(index, BaseBarrier(baseImage, templateImages));
return &barrierMap[index]; return &elementMap[index];
} }
void BarrierManager::Unload(int i) { void BarrierManager::Unload(int i) {
barrierMap.erase(i); elementMap.erase(i);
} }
void BarrierManager::UnloadAll() { void BarrierManager::UnloadAll() {
barrierMap.clear(); elementMap.clear();
}
void BarrierManager::UnloadIf(std::function<bool(std::pair<const int, BaseBarrier const&>)> fn) {
std::map<int, BaseBarrier>::iterator it = elementMap.begin();
while (it != elementMap.end()) {
if (fn(*it)) {
it = elementMap.erase(it);
}
else {
++it;
}
}
} }
int BarrierManager::Size() { int BarrierManager::Size() {
return barrierMap.size(); return elementMap.size();
} }
BaseBarrier* BarrierManager::Find(int i) { BaseBarrier* BarrierManager::Find(int i) {
std::map<int, BaseBarrier>::iterator it = barrierMap.find(i); std::map<int, BaseBarrier>::iterator it = elementMap.find(i);
if (it == barrierMap.end()) { if (it == elementMap.end()) {
return nullptr; return nullptr;
} }
@@ -74,7 +86,7 @@ BaseBarrier* BarrierManager::Find(int i) {
} }
std::map<int, BaseBarrier>* BarrierManager::GetContainer() { std::map<int, BaseBarrier>* BarrierManager::GetContainer() {
return &barrierMap; return &elementMap;
} }
std::map<std::string, Image>* BarrierManager::GetTemplateContainer() { std::map<std::string, Image>* BarrierManager::GetTemplateContainer() {
+2 -1
View File
@@ -42,6 +42,7 @@ public:
BaseBarrier* Create(int index); BaseBarrier* Create(int index);
void Unload(int i); void Unload(int i);
void UnloadAll(); void UnloadAll();
void UnloadIf(std::function<bool(std::pair<const int, BaseBarrier const&>)> fn);
int Size(); int Size();
@@ -52,5 +53,5 @@ public:
private: private:
Image baseImage; Image baseImage;
std::map<std::string, Image> templateImages; std::map<std::string, Image> templateImages;
std::map<int, BaseBarrier> barrierMap; std::map<int, BaseBarrier> elementMap;
}; };
+42 -29
View File
@@ -116,8 +116,8 @@ World::World(int* const argClientIndex, int* const argAccountIndex):
"slot 7 red.png", "slot 7 red.png",
"slot 8 red.png" "slot 8 red.png"
}; };
barrierMgr.LoadBaseImage(GetRenderer(), config["dir.sprites"] + "/barrier/base.png"); barrierMgr.LoadBaseImage(GetRenderer(), config["dir.sprites"] + "barrier/base.png");
barrierMgr.LoadTemplateImages(GetRenderer(), config["dir.sprites"] + "/barrier/", slotNames); barrierMgr.LoadTemplateImages(GetRenderer(), config["dir.sprites"] + "barrier/", slotNames);
std::cout << "Templates loaded: " << barrierMgr.GetTemplateContainer()->size() << std::endl; std::cout << "Templates loaded: " << barrierMgr.GetTemplateContainer()->size() << std::endl;
} }
@@ -185,7 +185,27 @@ void World::Update() {
return; return;
} }
//TODO: (1) regular query interval //TODO: (0) regular query interval
if (Clock::now() - queryTime > std::chrono::seconds(3)) {
queryTime = Clock::now();
//query the world state (room)
CharacterPacket characterPacket;
memset(&characterPacket, 0, MAX_PACKET_SIZE);
characterPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS;
characterPacket.roomIndex = roomIndex;
network.SendTo(Channels::SERVER, &characterPacket);
CreaturePacket creaturePacket;
creaturePacket.type = SerialPacketType::QUERY_CREATURE_EXISTS;
creaturePacket.roomIndex = roomIndex;
network.SendTo(Channels::SERVER, &creaturePacket);
BarrierPacket barrierPacket;
barrierPacket.type = SerialPacketType::QUERY_BARRIER_EXISTS;
barrierPacket.roomIndex = roomIndex;
network.SendTo(Channels::SERVER, &barrierPacket);
}
//cull creatures //cull creatures
for (std::map<int, BaseCreature>::iterator it = creatureMap.begin(); it != creatureMap.end(); /* */) { for (std::map<int, BaseCreature>::iterator it = creatureMap.begin(); it != creatureMap.end(); /* */) {
if ( (localCharacter->GetOrigin() - it->second.GetOrigin()).Length() > INFLUENCE_RADIUS) { if ( (localCharacter->GetOrigin() - it->second.GetOrigin()).Length() > INFLUENCE_RADIUS) {
@@ -196,7 +216,10 @@ void World::Update() {
} }
} }
//TODO: cull barriers //cull barriers
barrierMgr.UnloadIf([&](std::pair<const int, BaseBarrier const&> barrierIt) -> bool {
return (localCharacter->GetOrigin() - barrierIt.second.GetOrigin()).Length() > INFLUENCE_RADIUS;
});
//get the collidable boxes //get the collidable boxes
std::list<BoundingBox> boxList = GenerateCollisionGrid(localCharacter, tileSheet.GetTileW(), tileSheet.GetTileH()); std::list<BoundingBox> boxList = GenerateCollisionGrid(localCharacter, tileSheet.GetTileW(), tileSheet.GetTileH());
@@ -727,6 +750,9 @@ void World::hCharacterCreate(CharacterPacket* const argPacket) {
if (character->GetOwner() == accountIndex) { if (character->GetOwner() == accountIndex) {
localCharacter = static_cast<LocalCharacter*>(character); localCharacter = static_cast<LocalCharacter*>(character);
//reset queries
queryTime = Clock::now() - std::chrono::seconds(4); //back 4 seconds to trigger automatically
//focus the camera on this character's sprite //focus the camera on this character's sprite
camera.marginX = (camera.width / 2 - localCharacter->GetSprite()->GetClipW() / 2); camera.marginX = (camera.width / 2 - localCharacter->GetSprite()->GetClipW() / 2);
camera.marginY = (camera.height/ 2 - localCharacter->GetSprite()->GetClipH() / 2); camera.marginY = (camera.height/ 2 - localCharacter->GetSprite()->GetClipH() / 2);
@@ -734,23 +760,6 @@ 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 (room)
CharacterPacket characterPacket;
memset(&characterPacket, 0, MAX_PACKET_SIZE);
characterPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS;
characterPacket.roomIndex = roomIndex;
network.SendTo(Channels::SERVER, &characterPacket);
CreaturePacket creaturePacket;
creaturePacket.type = SerialPacketType::QUERY_CREATURE_EXISTS;
creaturePacket.roomIndex = roomIndex;
network.SendTo(Channels::SERVER, &creaturePacket);
BarrierPacket barrierPacket;
barrierPacket.type = SerialPacketType::QUERY_BARRIER_EXISTS;
barrierPacket.roomIndex = roomIndex;
network.SendTo(Channels::SERVER, &barrierPacket);
} }
//debug //debug
@@ -791,12 +800,12 @@ void World::hCharacterUnload(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
//TODO: why is this commented out? //TODO: why is this commented out?
// 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 || (localCharacter->GetOrigin() - argPacket->origin).Length() > INFLUENCE_RADIUS) {
return; return;
} }
@@ -913,10 +922,12 @@ void World::hCreatureUnload(CreaturePacket* const argPacket) {
} }
void World::hQueryCreatureExists(CreaturePacket* const argPacket) { void World::hQueryCreatureExists(CreaturePacket* const argPacket) {
std::cout << "Creature Query" << std::endl; if (!localCharacter) {
return;
}
//ignore creatures in a different room (sub-optimal) //ignore creatures in a different room (sub-optimal)
if (argPacket->roomIndex != roomIndex) { if (argPacket->roomIndex != roomIndex || (localCharacter->GetOrigin() - argPacket->origin).Length() > INFLUENCE_RADIUS) {
return; return;
} }
@@ -1021,10 +1032,12 @@ void World::hBarrierUnload(BarrierPacket* const argPacket) {
} }
void World::hQueryBarrierExists(BarrierPacket* const argPacket) { void World::hQueryBarrierExists(BarrierPacket* const argPacket) {
std::cout << "Barrier Query" << std::endl; if (!localCharacter) {
return;
}
//ignore barriers in a different room (sub-optimal) //ignore barriers in a different room (sub-optimal)
if (argPacket->roomIndex != roomIndex) { if (argPacket->roomIndex != roomIndex || (localCharacter->GetOrigin() - argPacket->origin).Length() > INFLUENCE_RADIUS) {
return; return;
} }
+1
View File
@@ -168,6 +168,7 @@ private:
//TODO: (2) Heartbeat needs it's own utility //TODO: (2) Heartbeat needs it's own utility
typedef std::chrono::steady_clock Clock; typedef std::chrono::steady_clock Clock;
Clock::time_point lastBeat = Clock::now(); Clock::time_point lastBeat = Clock::now();
Clock::time_point queryTime = Clock::now() - std::chrono::seconds(4); //back 4 seconds to trigger automatically
int attemptedBeats = 0; int attemptedBeats = 0;
//ugly references; I hate this //ugly references; I hate this
Binary file not shown.

Before

Width:  |  Height:  |  Size: 680 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 738 B

After

Width:  |  Height:  |  Size: 738 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 763 B

After

Width:  |  Height:  |  Size: 763 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 B

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 B

After

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 305 B

After

Width:  |  Height:  |  Size: 305 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 B

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 423 B

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 422 B

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 B

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 B

After

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 385 B

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 B

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 B

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 431 B

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 B

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 407 B

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 400 B

After

Width:  |  Height:  |  Size: 400 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 656 B

After

Width:  |  Height:  |  Size: 656 B

+15 -3
View File
@@ -130,14 +130,14 @@ roomManagerAPI.SetOnCreate(function(room, index)
-- --
end) end)
creatureManagerAPI.Create(roomAPI.GetCreatureMgr(room), "anibunny.png", bunnySquare)
--creatureManager with SetOnCreate, SetOnUnload & create & unload --creatureManager with SetOnCreate, SetOnUnload & create & unload
barrierManagerAPI.SetOnCreate(roomAPI.GetBarrierMgr(room), function(barrier) barrierManagerAPI.SetOnCreate(roomAPI.GetBarrierMgr(room), function(barrier)
barrierAPI.SetScript(barrier, barrierTick) barrierAPI.SetScript(barrier, barrierTick)
end) end)
roomAPI.SetOnTick(room, function(room) roomAPI.SetOnTick(room, function(room)
ret = 0
--placeholders
roomAPI.ForEachCharacter(room, function(character) roomAPI.ForEachCharacter(room, function(character)
-- --
end) end)
@@ -146,7 +146,19 @@ roomManagerAPI.SetOnCreate(function(room, index)
-- --
end) end)
--TODO: for each barrier roomAPI.ForEachBarrier(room, function(creature)
--
end)
--respawn a new rabbit when needed
if creatureManagerAPI.GetLoadedCount(roomAPI.GetCreatureMgr(room)) < 1 and
barrierManagerAPI.GetLoadedCount(roomAPI.GetBarrierMgr(room)) < 2
then
--make a new creature
creatureManagerAPI.Create(roomAPI.GetCreatureMgr(room), "anibunny.png", bunnySquare)
ret = 1
end
return ret
end) end)
end) end)
+2 -2
View File
@@ -32,11 +32,11 @@ BarrierManager::~BarrierManager() {
} }
//arg: a list of barriers to be updated in the clients //arg: a list of barriers to be updated in the clients
void BarrierManager::Update(std::list<std::pair<const int, BarrierData*>>* barrierList) { void BarrierManager::Update(std::list<std::pair<const int, BarrierData*>>* barrierList, bool updateAll) {
int ret; int ret;
for (auto& it : elementMap) { for (auto& it : elementMap) {
ret = it.second.Update(lua); ret = it.second.Update(lua);
if (ret) { if (ret || updateAll) {
barrierList->push_back(std::pair<const int, BarrierData*>(it.first, &it.second)); barrierList->push_back(std::pair<const int, BarrierData*>(it.first, &it.second));
} }
} }
+1 -1
View File
@@ -36,7 +36,7 @@ public:
~BarrierManager(); ~BarrierManager();
//common public methods //common public methods
void Update(std::list<std::pair<const int, BarrierData*>>* barrierList); void Update(std::list<std::pair<const int, BarrierData*>>* barrierList, bool updateAll);
int Create(int instanceIndex); int Create(int instanceIndex);
void Unload(int uid); void Unload(int uid);
+2 -2
View File
@@ -32,11 +32,11 @@ CreatureManager::~CreatureManager() {
} }
//arg: a list of creatures to be updated in the clients //arg: a list of creatures to be updated in the clients
void CreatureManager::Update(std::list<std::pair<const int, CreatureData*>>* creatureList) { void CreatureManager::Update(std::list<std::pair<const int, CreatureData*>>* creatureList, bool updateAll) {
int ret; int ret;
for (auto& it : elementMap) { for (auto& it : elementMap) {
ret = it.second.Update(lua); ret = it.second.Update(lua);
if (ret) { if (ret || updateAll) {
creatureList->push_back(std::pair<const int, CreatureData*>(it.first, &it.second)); creatureList->push_back(std::pair<const int, CreatureData*>(it.first, &it.second));
} }
} }
+1 -1
View File
@@ -37,7 +37,7 @@ public:
~CreatureManager(); ~CreatureManager();
//common public methods //common public methods
void Update(std::list<std::pair<const int, CreatureData*>>* creatureList); void Update(std::list<std::pair<const int, CreatureData*>>* creatureList, bool updateAll);
int Create(std::string avatar, int scriptRef); int Create(std::string avatar, int scriptRef);
void Unload(int uid); void Unload(int uid);
+35
View File
@@ -109,6 +109,24 @@ static int forEachCreature(lua_State* L) {
return 0; return 0;
} }
static int forEachBarrier(lua_State* L) {
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
BarrierManager* barrierMgr = room->GetBarrierMgr();
//pass each barrier to the given function
for (auto& it : *barrierMgr->GetContainer()) {
lua_pushvalue(L, -1);
lua_pushlightuserdata(L, static_cast<void*>(&it.second));
//call each iteration, throwing an exception if something happened
if (lua_pcall(L, 1, 0, 0) != LUA_OK) {
std::ostringstream os;
os << "Lua error: ";
os << lua_tostring(L, -1);
throw(std::runtime_error(os.str()));
}
}
return 0;
}
static int setOnTick(lua_State* L) { static int setOnTick(lua_State* L) {
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1)); RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
luaL_unref(L, LUA_REGISTRYINDEX, room->GetTickReference()); luaL_unref(L, LUA_REGISTRYINDEX, room->GetTickReference());
@@ -122,6 +140,19 @@ static int getOnTick(lua_State* L) {
return 1; return 1;
} }
//TODO: autogen docs
static int setTag(lua_State* L) {
RoomData* room = static_cast<RoomData*>(lua_touserdata(L, 1));
room->SetTag(lua_tostring(L, 2), lua_tostring(L, 3));
return 0;
}
static int getTag(lua_State* L) {
RoomData* room = static_cast<RoomData*>(lua_touserdata(L, 1));
lua_pushstring(L, room->GetTag(lua_tostring(L, 2)).c_str());
return 1;
}
static int initialize(lua_State* L) { static int initialize(lua_State* L) {
RoomData* room = static_cast<RoomData*>(lua_touserdata(L, 1)); RoomData* room = static_cast<RoomData*>(lua_touserdata(L, 1));
@@ -148,10 +179,14 @@ static const luaL_Reg roomLib[] = {
{"ForEachCharacter", forEachCharacter}, {"ForEachCharacter", forEachCharacter},
{"ForEachCreature", forEachCreature}, {"ForEachCreature", forEachCreature},
{"ForEachBarrier", forEachBarrier},
{"SetOnTick", setOnTick}, {"SetOnTick", setOnTick},
{"GetOnTick", getOnTick}, {"GetOnTick", getOnTick},
{"SetTag", setTag},
{"GetTag", getTag},
{"Initialize", initialize}, {"Initialize", initialize},
{nullptr, nullptr} {nullptr, nullptr}
}; };
+38 -3
View File
@@ -36,12 +36,21 @@ void RoomData::RunFrame() {
//get the hook //get the hook
lua_rawgeti(lua, LUA_REGISTRYINDEX, tickRef); lua_rawgeti(lua, LUA_REGISTRYINDEX, tickRef);
//returning 1 means pump all
bool updateAll = false;
if (!lua_isnil(lua, -1)) { if (!lua_isnil(lua, -1)) {
//call the tick function, with this as a parameter //call the tick function, with this as a parameter
lua_pushlightuserdata(lua, this); lua_pushlightuserdata(lua, this);
if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { if (lua_pcall(lua, 1, 1, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
} }
//pump creatures & barriers
if (lua_tonumber(lua, -1)) {
updateAll = true;
}
lua_pop(lua, 1);
} }
else { else {
lua_pop(lua, 1); lua_pop(lua, 1);
@@ -55,8 +64,8 @@ void RoomData::RunFrame() {
for (auto& it : characterList) { for (auto& it : characterList) {
it->Update(); it->Update();
} }
creatureMgr.Update(&creatureList); creatureMgr.Update(&creatureList, updateAll);
barrierMgr.Update(&barrierList); barrierMgr.Update(&barrierList, updateAll);
//build a list of entities for use with the triggers //build a list of entities for use with the triggers
std::stack<Entity*> entityStack; std::stack<Entity*> entityStack;
@@ -71,6 +80,8 @@ void RoomData::RunFrame() {
for (auto characterIt : characterList) { for (auto characterIt : characterList) {
BoundingBox characterBox = characterIt->GetBounds() + characterIt->GetOrigin(); BoundingBox characterBox = characterIt->GetBounds() + characterIt->GetOrigin();
std::list<int> creatureUnloadList;
for (auto creatureIt : *creatureMgr.GetContainer()) { for (auto creatureIt : *creatureMgr.GetContainer()) {
BoundingBox creatureBox = creatureIt.second.GetBounds() + creatureIt.second.GetOrigin(); BoundingBox creatureBox = creatureIt.second.GetBounds() + creatureIt.second.GetOrigin();
@@ -88,8 +99,24 @@ void RoomData::RunFrame() {
copyBarrierToPacket(&barrierPacket, barrierData, barrierIndex); copyBarrierToPacket(&barrierPacket, barrierData, barrierIndex);
pumpPacketProximity(reinterpret_cast<SerialPacket*>(&barrierPacket), roomIndex, characterIt->GetOrigin(), INFLUENCE_RADIUS); pumpPacketProximity(reinterpret_cast<SerialPacket*>(&barrierPacket), roomIndex, characterIt->GetOrigin(), INFLUENCE_RADIUS);
//delete this creature
creatureUnloadList.push_back(creatureIt.first);
} }
} }
//actually unload these creatures
for (auto& it : creatureUnloadList) {
CreatureData* creatureData = creatureMgr.Find(it);
CreaturePacket creaturePacket;
creaturePacket.type = SerialPacketType::CREATURE_UNLOAD;
copyCreatureToPacket(&creaturePacket, creatureData, it);
pumpPacketProximity(reinterpret_cast<SerialPacket*>(&creaturePacket), roomIndex, creatureData->GetOrigin(), INFLUENCE_RADIUS);
creatureMgr.Unload(it);
}
} }
//send the creature updates //send the creature updates
@@ -184,4 +211,12 @@ int RoomData::SetTickReference(int i) {
int RoomData::GetTickReference() { int RoomData::GetTickReference() {
return tickRef; return tickRef;
}
std::string RoomData::SetTag(std::string key, std::string value) {
return tags[key] = value;
}
std::string RoomData::GetTag(std::string key) {
return tags[key];
} }
+4
View File
@@ -70,6 +70,9 @@ public:
int GetTickReference(); int GetTickReference();
//TODO: other triggers like player entry & exit, etc. //TODO: other triggers like player entry & exit, etc.
std::string SetTag(std::string key, std::string value);
std::string GetTag(std::string key);
private: private:
//metadata //metadata
std::string roomName; std::string roomName;
@@ -90,4 +93,5 @@ private:
//hooks //hooks
int tickRef = LUA_NOREF; int tickRef = LUA_NOREF;
std::map<std::string, std::string> tags;
}; };