mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
!?OB WIP
This commit is contained in:
parent
a59e12ca5f
commit
ec6f7b88fe
@ -182,6 +182,7 @@
|
|||||||
<Unit filename="../scripts/lib/erm/MA.lua" />
|
<Unit filename="../scripts/lib/erm/MA.lua" />
|
||||||
<Unit filename="../scripts/lib/erm/MF.lua" />
|
<Unit filename="../scripts/lib/erm/MF.lua" />
|
||||||
<Unit filename="../scripts/lib/erm/MF_T.lua" />
|
<Unit filename="../scripts/lib/erm/MF_T.lua" />
|
||||||
|
<Unit filename="../scripts/lib/erm/OB_T.lua" />
|
||||||
<Unit filename="../scripts/lib/erm/OW.lua" />
|
<Unit filename="../scripts/lib/erm/OW.lua" />
|
||||||
<Unit filename="../scripts/lib/erm/PI_T.lua" />
|
<Unit filename="../scripts/lib/erm/PI_T.lua" />
|
||||||
<Unit filename="../scripts/lib/erm/ReceiverBase.lua" />
|
<Unit filename="../scripts/lib/erm/ReceiverBase.lua" />
|
||||||
|
@ -211,16 +211,38 @@ public:
|
|||||||
bool tryGet(int position, double & value);
|
bool tryGet(int position, double & value);
|
||||||
bool tryGet(int position, std::string & value);
|
bool tryGet(int position, std::string & value);
|
||||||
|
|
||||||
template<typename T, typename std::enable_if<detail::IsRegularClass<T>::value, int>::type = 0>
|
template<typename T, typename std::enable_if<detail::IsRegularClass<T>::value && std::is_const<T>::value, int>::type = 0>
|
||||||
bool tryGet(int position, T * & value)
|
STRONG_INLINE bool tryGet(int position, T * & value)
|
||||||
{
|
{
|
||||||
return tryGetUData(position, value);
|
using NCValue = typename std::remove_const<T>::type;
|
||||||
|
|
||||||
|
using UData = NCValue *;
|
||||||
|
using CUData = T *;
|
||||||
|
|
||||||
|
return tryGetCUData<T *, UData, CUData>(position, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename std::enable_if<detail::IsRegularClass<T>::value, int>::type = 0>
|
template<typename T, typename std::enable_if<detail::IsRegularClass<T>::value && !std::is_const<T>::value, int>::type = 0>
|
||||||
bool tryGet(int position, std::shared_ptr<T> & value)
|
STRONG_INLINE bool tryGet(int position, T * & value)
|
||||||
{
|
{
|
||||||
return tryGetUData(position, value);
|
return tryGetUData<T *>(position, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename std::enable_if<detail::IsRegularClass<T>::value && std::is_const<T>::value, int>::type = 0>
|
||||||
|
STRONG_INLINE bool tryGet(int position, std::shared_ptr<T> & value)
|
||||||
|
{
|
||||||
|
using NCValue = typename std::remove_const<T>::type;
|
||||||
|
|
||||||
|
using UData = std::shared_ptr<NCValue>;
|
||||||
|
using CUData = std::shared_ptr<T>;
|
||||||
|
|
||||||
|
return tryGetCUData<std::shared_ptr<T>, UData, CUData>(position, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename std::enable_if<detail::IsRegularClass<T>::value && !std::is_const<T>::value, int>::type = 0>
|
||||||
|
STRONG_INLINE bool tryGet(int position, std::shared_ptr<T> & value)
|
||||||
|
{
|
||||||
|
return tryGetUData<std::shared_ptr<T>>(position, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
@ -228,13 +250,67 @@ public:
|
|||||||
{
|
{
|
||||||
static auto KEY = api::TypeRegistry::get()->getKey<U>();
|
static auto KEY = api::TypeRegistry::get()->getKey<U>();
|
||||||
|
|
||||||
void * raw = luaL_checkudata(L, position, KEY);
|
void * raw = lua_touserdata(L, position);
|
||||||
|
|
||||||
if(!raw)
|
if(!raw)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
value = *(static_cast<U *>(raw));
|
if(lua_getmetatable(L, position) == 0)
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, KEY);
|
||||||
|
|
||||||
|
if(lua_rawequal(L, -1, -2) == 1)
|
||||||
|
{
|
||||||
|
value = *(static_cast<U *>(raw));
|
||||||
|
lua_pop(L, 2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop(L, 2);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename U, typename CU>
|
||||||
|
bool tryGetCUData(int position, T & value)
|
||||||
|
{
|
||||||
|
static auto KEY = api::TypeRegistry::get()->getKey<U>();
|
||||||
|
static auto C_KEY = api::TypeRegistry::get()->getKey<CU>();
|
||||||
|
|
||||||
|
void * raw = lua_touserdata(L, position);
|
||||||
|
|
||||||
|
if(!raw)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(lua_getmetatable(L, position) == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//top is metatable
|
||||||
|
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, KEY);
|
||||||
|
|
||||||
|
if(lua_rawequal(L, -1, -2) == 1)
|
||||||
|
{
|
||||||
|
value = *(static_cast<U *>(raw));
|
||||||
|
lua_pop(L, 2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
//top is metatable
|
||||||
|
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, C_KEY);
|
||||||
|
|
||||||
|
if(lua_rawequal(L, -1, -2) == 1)
|
||||||
|
{
|
||||||
|
value = *(static_cast<CU *>(raw));
|
||||||
|
lua_pop(L, 2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop(L, 2);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tryGet(int position, JsonNode & value);
|
bool tryGet(int position, JsonNode & value);
|
||||||
|
@ -161,13 +161,16 @@ class OpaqueWrapper : public RegistarBase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using ObjectType = typename std::remove_cv<T>::type;
|
using ObjectType = typename std::remove_cv<T>::type;
|
||||||
using UDataType = T *;
|
using UDataType = ObjectType *;
|
||||||
|
using CUDataType = const ObjectType *;
|
||||||
|
|
||||||
using RegType = detail::RegType<UDataType>;
|
using RegType = detail::RegType<UDataType>;
|
||||||
using CustomRegType = detail::CustomRegType;
|
using CustomRegType = detail::CustomRegType;
|
||||||
|
|
||||||
void pushMetatable(lua_State * L) const override final
|
void pushMetatable(lua_State * L) const override final
|
||||||
{
|
{
|
||||||
static auto KEY = api::TypeRegistry::get()->getKey<UDataType>();
|
static auto KEY = api::TypeRegistry::get()->getKey<UDataType>();
|
||||||
|
static auto S_KEY = api::TypeRegistry::get()->getKey<CUDataType>();
|
||||||
|
|
||||||
LuaStack S(L);
|
LuaStack S(L);
|
||||||
|
|
||||||
@ -176,6 +179,11 @@ public:
|
|||||||
|
|
||||||
S.balance();
|
S.balance();
|
||||||
|
|
||||||
|
if(luaL_newmetatable(L, S_KEY) != 0)
|
||||||
|
adjustMetatable(L);
|
||||||
|
|
||||||
|
S.balance();
|
||||||
|
|
||||||
detail::Dispatcher<Proxy, UDataType>::pushStaticTable(L);
|
detail::Dispatcher<Proxy, UDataType>::pushStaticTable(L);
|
||||||
|
|
||||||
adjustStaticTable(L);
|
adjustStaticTable(L);
|
||||||
|
@ -26,8 +26,6 @@ VCMI_REGISTER_CORE_SCRIPT_API(CreatureProxy, "Creature");
|
|||||||
|
|
||||||
const std::vector<CreatureProxy::RegType> CreatureProxy::REGISTER =
|
const std::vector<CreatureProxy::RegType> CreatureProxy::REGISTER =
|
||||||
{
|
{
|
||||||
{"accessBonuses", LuaCallWrapper<const EntityWithBonuses<CreatureID>>::createFunctor(&EntityWithBonuses<CreatureID>::accessBonuses)},
|
|
||||||
|
|
||||||
{"getCost", LuaCallWrapper<const Creature>::createFunctor(&Creature::getCost)},
|
{"getCost", LuaCallWrapper<const Creature>::createFunctor(&Creature::getCost)},
|
||||||
{"isDoubleWide", LuaCallWrapper<const Creature>::createFunctor(&Creature::isDoubleWide)},
|
{"isDoubleWide", LuaCallWrapper<const Creature>::createFunctor(&Creature::isDoubleWide)},
|
||||||
};
|
};
|
||||||
|
@ -21,10 +21,10 @@ namespace scripting
|
|||||||
namespace api
|
namespace api
|
||||||
{
|
{
|
||||||
|
|
||||||
class ObjectInstanceProxy : public OpaqueWrapper<const IObjectInterface, ObjectInstanceProxy>
|
class ObjectInstanceProxy : public OpaqueWrapper<const CGObjectInstance, ObjectInstanceProxy>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Wrapper = OpaqueWrapper<const IObjectInterface, ObjectInstanceProxy>;
|
using Wrapper = OpaqueWrapper<const CGObjectInstance, ObjectInstanceProxy>;
|
||||||
static const std::vector<typename Wrapper::RegType> REGISTER;
|
static const std::vector<typename Wrapper::RegType> REGISTER;
|
||||||
static const std::vector<typename Wrapper::CustomRegType> REGISTER_CUSTOM;
|
static const std::vector<typename Wrapper::CustomRegType> REGISTER_CUSTOM;
|
||||||
};
|
};
|
||||||
|
@ -39,6 +39,21 @@ const std::vector<ObjectVisitStartedProxy::CustomRegType> ObjectVisitStartedProx
|
|||||||
&SubscriptionRegistryProxy<ObjectVisitStartedProxy>::subscribeAfter,
|
&SubscriptionRegistryProxy<ObjectVisitStartedProxy>::subscribeAfter,
|
||||||
true
|
true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"getPlayer",
|
||||||
|
LuaMethodWrapper<ObjectVisitStarted, PlayerColor(ObjectVisitStarted:: *)()const, &ObjectVisitStarted::getPlayer>::invoke,
|
||||||
|
false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"getHero",
|
||||||
|
LuaMethodWrapper<ObjectVisitStarted, ObjectInstanceID(ObjectVisitStarted:: *)()const, &ObjectVisitStarted::getHero>::invoke,
|
||||||
|
false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"getObject",
|
||||||
|
LuaMethodWrapper<ObjectVisitStarted, ObjectInstanceID(ObjectVisitStarted:: *)()const, &ObjectVisitStarted::getObject>::invoke,
|
||||||
|
false
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ end
|
|||||||
!?TL client only? depends on time limit feature
|
!?TL client only? depends on time limit feature
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local supportedTriggers = {"PI", "FU", "GM", "MF", "TM"}
|
local supportedTriggers = {"PI", "FU", "GM", "MF", "OB", "TM"}
|
||||||
|
|
||||||
local TriggerLoaders = {}
|
local TriggerLoaders = {}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ local trigger = TriggerBase:new()
|
|||||||
|
|
||||||
function trigger:new(o)
|
function trigger:new(o)
|
||||||
o = TriggerBase.new(self, o)
|
o = TriggerBase.new(self, o)
|
||||||
o.sub = ApplyDamage.subscribeBefore(EVENT_BUS, function(event)
|
o.sub = ApplyDamage.subscribeBefore(eventBus, function(event)
|
||||||
o:call(event)
|
o:call(event)
|
||||||
end)
|
end)
|
||||||
return o
|
return o
|
||||||
|
27
scripts/lib/erm/OB_T.lua
Normal file
27
scripts/lib/erm/OB_T.lua
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
local TriggerBase = require("core:erm.TriggerBase")
|
||||||
|
local ObjectVisitStarted = require("events.ObjectVisitStarted")
|
||||||
|
local eventBus = EVENT_BUS
|
||||||
|
local game = GAME
|
||||||
|
|
||||||
|
local trigger = TriggerBase:new()
|
||||||
|
|
||||||
|
function trigger:new(o)
|
||||||
|
o = TriggerBase.new(self, o)
|
||||||
|
|
||||||
|
local id1 = tonumber(o.id[1])
|
||||||
|
|
||||||
|
o.sub = ObjectVisitStarted.subscribeBefore(eventBus,
|
||||||
|
function(event)
|
||||||
|
local objIndex = event:getObject()
|
||||||
|
|
||||||
|
local obj = game:getObj(objIndex, false)
|
||||||
|
|
||||||
|
if obj:getObjGroupIndex() == id1 then
|
||||||
|
o:call(event)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
return o
|
||||||
|
end
|
||||||
|
|
||||||
|
return trigger
|
@ -42,23 +42,26 @@ protected:
|
|||||||
|
|
||||||
TEST_F(ERM_OB_T, ByTypeIndex)
|
TEST_F(ERM_OB_T, ByTypeIndex)
|
||||||
{
|
{
|
||||||
EXPECT_CALL(infoMock, getObj(Eq(ObjectInstanceID(234)), _)).WillRepeatedly(Return(&objectMock));
|
EXPECT_CALL(infoMock, getObj(Eq(ObjectInstanceID(234)), _)).Times(AtLeast(1)).WillRepeatedly(Return(&objectMock));
|
||||||
EXPECT_CALL(objectMock, getObjGroupIndex()).WillRepeatedly(Return(420));
|
EXPECT_CALL(objectMock, getObjGroupIndex()).Times(AtLeast(1)).WillRepeatedly(Return(420));
|
||||||
|
|
||||||
loadScript(VLC->scriptHandler->erm,
|
loadScript(VLC->scriptHandler->erm,
|
||||||
"VERM\n"
|
"VERM\n"
|
||||||
"!?OB420;\n"
|
"!?OB420;\n"
|
||||||
"!!VRv42:S4;\n"
|
"!!VRv42:S4;\n"
|
||||||
|
"!?OB421;\n"
|
||||||
|
"!!VRv43:S5;\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
SCOPED_TRACE("\n" + subject->code);
|
SCOPED_TRACE("\n" + subject->code);
|
||||||
runClientServer();
|
runClientServer();
|
||||||
|
|
||||||
events::ObjectVisitStarted::defaultExecute(&eventBus, nullptr, PlayerColor(2), ObjectInstanceID(234), ObjectInstanceID(235));
|
events::ObjectVisitStarted::defaultExecute(&eventBus, nullptr, PlayerColor(2), ObjectInstanceID(235), ObjectInstanceID(234));
|
||||||
|
|
||||||
const JsonNode actualState = context->saveState();
|
const JsonNode actualState = context->saveState();
|
||||||
|
|
||||||
EXPECT_EQ(actualState["ERM"]["v"]["42"], JsonUtils::floatNode(4)) << actualState.toJson();
|
EXPECT_EQ(actualState["ERM"]["v"]["42"], JsonUtils::floatNode(4)) << actualState.toJson();
|
||||||
|
EXPECT_TRUE(actualState["ERM"]["v"]["43"].isNull()) << actualState.toJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user