Triggers now support exclusion lists

This commit is contained in:
Kayne Ruse
2015-03-13 20:43:20 +11:00
parent 954213f1ff
commit d82e3a8b79
6 changed files with 97 additions and 10 deletions
+46 -4
View File
@@ -11,6 +11,10 @@ characterAPI = require("character")
entityAPI = require("entity") entityAPI = require("entity")
networkAPI = require("network") networkAPI = require("network")
regionPagerAPI = require("region_pager")
triggerAPI = require("trigger")
triggerManagerAPI = require("trigger_manager")
--test the room hooks --test the room hooks
roomManagerAPI.SetOnCreate(function(room, index) roomManagerAPI.SetOnCreate(function(room, index)
print("", "Creating room: ", roomAPI.GetName(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) roomAPI.Initialize(underworld, mapSaver.Load, mapSaver.Save, mapMaker.DebugGrassland, mapSaver.Save)
--NOTE: test the trigger system --NOTE: test the trigger system
regionPagerAPI = require("region_pager")
triggerManagerAPI = require("trigger_manager")
function createTrigger(handle, room, x, y, script) function createTrigger(handle, room, x, y, script)
local pager = roomAPI.GetPager(room) local pager = roomAPI.GetPager(room)
@@ -52,13 +54,52 @@ function createTrigger(handle, room, x, y, script)
) )
end 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 --simple door pair
createTrigger("door 1", overworld, 128, -128, 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
local x, y = characterAPI.GetOrigin(entity) --move the character
characterAPI.SetRoomIndex(entity, uidTwo) characterAPI.SetRoomIndex(entity, uidTwo)
characterAPI.SetOrigin(entity, 0, 0) characterAPI.SetOrigin(entity, 0, 0)
networkAPI.PumpCharacterUpdate(entity) networkAPI.PumpCharacterUpdate(entity)
@@ -69,10 +110,11 @@ createTrigger("door 1", underworld, 128, -128, function(entity)
return return
end end
local x, y = characterAPI.GetOrigin(entity) --move the character
characterAPI.SetRoomIndex(entity, uidOne) characterAPI.SetRoomIndex(entity, uidOne)
characterAPI.SetOrigin(entity, 0, 0) characterAPI.SetOrigin(entity, 0, 0)
networkAPI.PumpCharacterUpdate(entity) networkAPI.PumpCharacterUpdate(entity)
end) end)
--]]
print("Finished the lua script") print("Finished the lua script")
+1 -1
View File
@@ -29,7 +29,7 @@
#include <stdexcept> #include <stdexcept>
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 //NOTE: type-dependant calls to various API functions, see bug #43
//reverse engineer the character index //reverse engineer the character index
+23 -4
View File
@@ -21,6 +21,7 @@
*/ */
#include "room_data.hpp" #include "room_data.hpp"
#include <algorithm>
#include <iostream> #include <iostream>
#include <stack> #include <stack>
#include <stdexcept> #include <stdexcept>
@@ -61,19 +62,37 @@ void RoomData::RunFrame() {
Entity* entity = entityStack.top(); Entity* entity = entityStack.top();
BoundingBox entityBox = entity->GetBounds() + entity->GetOrigin(); BoundingBox entityBox = entity->GetBounds() + entity->GetOrigin();
//get the trigger & hitbox //get the trigger pair & hitbox
for (auto& it : *triggerMgr.GetContainer()) { for (auto& triggerPair : *triggerMgr.GetContainer()) {
BoundingBox triggerBox = it.second.GetBoundingBox() + it.second.GetOrigin(); BoundingBox triggerBox = triggerPair.second.GetBoundingBox() + triggerPair.second.GetOrigin();
//find all collisions
if (entityBox.CheckOverlap(triggerBox)) { 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 //run the trigger script
lua_rawgeti(lua, LUA_REGISTRYINDEX, it.second.GetScriptReference()); lua_rawgeti(lua, LUA_REGISTRYINDEX, triggerPair.second.GetScriptReference());
lua_pushlightuserdata(lua, entity); lua_pushlightuserdata(lua, entity);
if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { if (lua_pcall(lua, 1, 0, 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) ));
} }
//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;
});
} }
} }
+18
View File
@@ -86,6 +86,21 @@ static int getReference(lua_State* L) {
return 1; return 1;
} }
static int pushExclusionEntity(lua_State* L) {
TriggerData* trigger = static_cast<TriggerData*>(lua_touserdata(L, 1));
trigger->GetExclusionList()->push_back(static_cast<Entity*>(lua_touserdata(L, 2)));
return 0;
}
static int removeExclusionEntity(lua_State* L) {
TriggerData* trigger = static_cast<TriggerData*>(lua_touserdata(L, 1));
Entity* entity = static_cast<Entity*>(lua_touserdata(L, 2));
trigger->GetExclusionList()->remove_if([entity](Entity* ptr){
return entity == ptr;
});
return 0;
}
static const luaL_Reg triggerLib[] = { static const luaL_Reg triggerLib[] = {
{"SetHandle", setHandle}, {"SetHandle", setHandle},
{"GetHandle", getHandle}, {"GetHandle", getHandle},
@@ -99,6 +114,9 @@ static const luaL_Reg triggerLib[] = {
{"SetScript",setReference}, {"SetScript",setReference},
{"GetScript",getReference}, {"GetScript",getReference},
{"PushExclusionEntity", pushExclusionEntity},
{"RemoveExclusionEntity", removeExclusionEntity},
{nullptr, nullptr} {nullptr, nullptr}
}; };
+4
View File
@@ -51,4 +51,8 @@ int TriggerData::SetScriptReference(int i) {
int TriggerData::GetScriptReference() { int TriggerData::GetScriptReference() {
return scriptRef; return scriptRef;
}
std::list<Entity*>* TriggerData::GetExclusionList() {
return &exclusionList;
} }
+5 -1
View File
@@ -23,13 +23,14 @@
#define TRIGGERDATA_HPP_ #define TRIGGERDATA_HPP_
#include "bounding_box.hpp" #include "bounding_box.hpp"
#include "entity.hpp"
#include "vector2.hpp" #include "vector2.hpp"
#include "lua.hpp" #include "lua.hpp"
#include <list>
#include <string> #include <string>
//TODO: (0) state-system for preventing double triggering
class TriggerData { class TriggerData {
public: public:
TriggerData() = default; TriggerData() = default;
@@ -47,11 +48,14 @@ public:
int SetScriptReference(int i); int SetScriptReference(int i);
int GetScriptReference(); int GetScriptReference();
std::list<Entity*>* GetExclusionList();
private: private:
std::string handle; std::string handle;
Vector2 origin; Vector2 origin;
BoundingBox bounds; BoundingBox bounds;
int scriptRef = LUA_NOREF; int scriptRef = LUA_NOREF;
std::list<Entity*> exclusionList;
}; };
#endif #endif