From d82e3a8b7913828f25e9b034ac1982df855d0959 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 13 Mar 2015 20:43:20 +1100 Subject: [PATCH] Triggers now support exclusion lists --- rsc/scripts/setup_server.lua | 50 ++++++++++++++++++++++++++--- server/characters/character_api.cpp | 2 +- server/rooms/room_data.cpp | 27 +++++++++++++--- server/triggers/trigger_api.cpp | 18 +++++++++++ server/triggers/trigger_data.cpp | 4 +++ server/triggers/trigger_data.hpp | 6 +++- 6 files changed, 97 insertions(+), 10 deletions(-) diff --git a/rsc/scripts/setup_server.lua b/rsc/scripts/setup_server.lua index 2c4f31c..e0086ad 100644 --- a/rsc/scripts/setup_server.lua +++ b/rsc/scripts/setup_server.lua @@ -11,6 +11,10 @@ characterAPI = require("character") entityAPI = require("entity") networkAPI = require("network") +regionPagerAPI = require("region_pager") +triggerAPI = require("trigger") +triggerManagerAPI = require("trigger_manager") + --test the room hooks roomManagerAPI.SetOnCreate(function(room, index) print("", "Creating room: ", roomAPI.GetName(room), index) @@ -33,8 +37,6 @@ local underworld, uidTwo = roomManagerAPI.CreateRoom("underworld", "overworld.bm roomAPI.Initialize(underworld, mapSaver.Load, mapSaver.Save, mapMaker.DebugGrassland, mapSaver.Save) --NOTE: test the trigger system -regionPagerAPI = require("region_pager") -triggerManagerAPI = require("trigger_manager") function createTrigger(handle, room, x, y, script) local pager = roomAPI.GetPager(room) @@ -52,13 +54,52 @@ function createTrigger(handle, room, x, y, script) ) end +function createDoorPair(handle, roomOne, roomOneUID, Xone, Yone, roomTwo, roomTwoUID, Xtwo, Ytwo) + --create the scripts + local function scriptOne(entity) + if entityAPI.GetType(entity) ~= "character" then return end + + --move the character + characterAPI.SetRoomIndex(entity, roomTwoUID) + characterAPI.SetOrigin(entity, Xtwo, Ytwo-16) + networkAPI.PumpCharacterUpdate(entity) + + --disable the other trigger + local triggerTwo = triggerManagerAPI.GetTrigger(roomAPI.GetTriggerMgr(roomTwo), handle) + triggerAPI.PushExclusionEntity(triggerTwo, entity) + end + + local function scriptTwo(entity) + if entityAPI.GetType(entity) ~= "character" then return end + + --move the character + characterAPI.SetRoomIndex(entity, roomOneUID) + characterAPI.SetOrigin(entity, Xone, Yone-16) --NOTE: the 16 pixel margin for presentation + networkAPI.PumpCharacterUpdate(entity) + + --disable the other trigger + local triggerOne = triggerManagerAPI.GetTrigger(roomAPI.GetTriggerMgr(roomOne), handle) + triggerAPI.PushExclusionEntity(triggerOne, entity) + end + + --create the triggers proper + createTrigger(handle, roomOne, Xone, Yone, scriptOne) + createTrigger(handle, roomTwo, Xtwo, Ytwo, scriptTwo) +end + +--call the monstrosity +createDoorPair("pair 1", overworld, uidOne, 0, -64, underworld, uidTwo, 0, 0) +createDoorPair("pair 2", overworld, uidOne, 64, -64, underworld, uidTwo, 64, 0) +createDoorPair("pair 3", overworld, uidOne, 128, -64, underworld, uidTwo, 128, 0) + +--[[ --simple door pair createTrigger("door 1", overworld, 128, -128, function(entity) if entityAPI.GetType(entity) ~= "character" then return end - local x, y = characterAPI.GetOrigin(entity) + --move the character characterAPI.SetRoomIndex(entity, uidTwo) characterAPI.SetOrigin(entity, 0, 0) networkAPI.PumpCharacterUpdate(entity) @@ -69,10 +110,11 @@ createTrigger("door 1", underworld, 128, -128, function(entity) return end - local x, y = characterAPI.GetOrigin(entity) + --move the character characterAPI.SetRoomIndex(entity, uidOne) characterAPI.SetOrigin(entity, 0, 0) networkAPI.PumpCharacterUpdate(entity) end) +--]] print("Finished the lua script") diff --git a/server/characters/character_api.cpp b/server/characters/character_api.cpp index 632285a..38091c2 100644 --- a/server/characters/character_api.cpp +++ b/server/characters/character_api.cpp @@ -29,7 +29,7 @@ #include -static int setRoomIndex(lua_State* L) { //TODO: (1) take the room userdata as a parameter? +static int setRoomIndex(lua_State* L) { //TODO: (0) take the room userdata as a parameter //NOTE: type-dependant calls to various API functions, see bug #43 //reverse engineer the character index diff --git a/server/rooms/room_data.cpp b/server/rooms/room_data.cpp index 8b57466..fd0c7e7 100644 --- a/server/rooms/room_data.cpp +++ b/server/rooms/room_data.cpp @@ -21,6 +21,7 @@ */ #include "room_data.hpp" +#include #include #include #include @@ -61,19 +62,37 @@ void RoomData::RunFrame() { Entity* entity = entityStack.top(); BoundingBox entityBox = entity->GetBounds() + entity->GetOrigin(); - //get the trigger & hitbox - for (auto& it : *triggerMgr.GetContainer()) { - BoundingBox triggerBox = it.second.GetBoundingBox() + it.second.GetOrigin(); + //get the trigger pair & hitbox + for (auto& triggerPair : *triggerMgr.GetContainer()) { + BoundingBox triggerBox = triggerPair.second.GetBoundingBox() + triggerPair.second.GetOrigin(); + //find all collisions if (entityBox.CheckOverlap(triggerBox)) { + //skip members of the exclusion list + if (std::any_of(triggerPair.second.GetExclusionList()->begin(), triggerPair.second.GetExclusionList()->end(), [entity](Entity* ptr) -> bool { + return entity == ptr; + })) { + continue; + } + //run the trigger script - lua_rawgeti(lua, LUA_REGISTRYINDEX, it.second.GetScriptReference()); + lua_rawgeti(lua, LUA_REGISTRYINDEX, triggerPair.second.GetScriptReference()); lua_pushlightuserdata(lua, entity); if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { //error throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } + + //push to the exclusion list + triggerPair.second.GetExclusionList()->push_back(entity); + } + else { + //remove members of the exclusion list + //NOTE: characters in different rooms won't be removed, but that shouldn't be a problem + triggerPair.second.GetExclusionList()->remove_if([entity](Entity* ptr) -> bool { + return entity == ptr; + }); } } diff --git a/server/triggers/trigger_api.cpp b/server/triggers/trigger_api.cpp index 7ea007c..8f9089a 100644 --- a/server/triggers/trigger_api.cpp +++ b/server/triggers/trigger_api.cpp @@ -86,6 +86,21 @@ static int getReference(lua_State* L) { return 1; } +static int pushExclusionEntity(lua_State* L) { + TriggerData* trigger = static_cast(lua_touserdata(L, 1)); + trigger->GetExclusionList()->push_back(static_cast(lua_touserdata(L, 2))); + return 0; +} + +static int removeExclusionEntity(lua_State* L) { + TriggerData* trigger = static_cast(lua_touserdata(L, 1)); + Entity* entity = static_cast(lua_touserdata(L, 2)); + trigger->GetExclusionList()->remove_if([entity](Entity* ptr){ + return entity == ptr; + }); + return 0; +} + static const luaL_Reg triggerLib[] = { {"SetHandle", setHandle}, {"GetHandle", getHandle}, @@ -99,6 +114,9 @@ static const luaL_Reg triggerLib[] = { {"SetScript",setReference}, {"GetScript",getReference}, + {"PushExclusionEntity", pushExclusionEntity}, + {"RemoveExclusionEntity", removeExclusionEntity}, + {nullptr, nullptr} }; diff --git a/server/triggers/trigger_data.cpp b/server/triggers/trigger_data.cpp index f4edc80..32ce359 100644 --- a/server/triggers/trigger_data.cpp +++ b/server/triggers/trigger_data.cpp @@ -51,4 +51,8 @@ int TriggerData::SetScriptReference(int i) { int TriggerData::GetScriptReference() { return scriptRef; +} + +std::list* TriggerData::GetExclusionList() { + return &exclusionList; } \ No newline at end of file diff --git a/server/triggers/trigger_data.hpp b/server/triggers/trigger_data.hpp index d77433e..6064285 100644 --- a/server/triggers/trigger_data.hpp +++ b/server/triggers/trigger_data.hpp @@ -23,13 +23,14 @@ #define TRIGGERDATA_HPP_ #include "bounding_box.hpp" +#include "entity.hpp" #include "vector2.hpp" #include "lua.hpp" +#include #include -//TODO: (0) state-system for preventing double triggering class TriggerData { public: TriggerData() = default; @@ -47,11 +48,14 @@ public: int SetScriptReference(int i); int GetScriptReference(); + std::list* GetExclusionList(); + private: std::string handle; Vector2 origin; BoundingBox bounds; int scriptRef = LUA_NOREF; + std::list exclusionList; }; #endif \ No newline at end of file