Triggers now support exclusion lists
This commit is contained in:
@@ -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")
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user