/* * BonusSystem.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * * License: GNU General Public License v2.0 or later * Full text of license available in license.txt file, in main folder * */ #include "StdInc.h" #include "BonusSystem.h" #include "../../../lib/json/JsonNode.h" #include "../../../lib/bonuses/BonusList.h" #include "../../../lib/bonuses/Bonus.h" #include "../../../lib/bonuses/IBonusBearer.h" #include "Registry.h" #include "../LuaStack.h" #include "../LuaCallWrapper.h" VCMI_LIB_NAMESPACE_BEGIN namespace scripting { namespace api { VCMI_REGISTER_SCRIPT_API(BonusProxy, "Bonus"); const std::vector BonusProxy::REGISTER_CUSTOM = { {"getType", &BonusProxy::getType, false}, {"getSubtype", &BonusProxy::getSubtype, false}, {"getDuration", &BonusProxy::getDuration, false}, {"getTurns", &BonusProxy::getTurns, false}, {"getValueType", &BonusProxy::getValueType, false}, {"getVal", &BonusProxy::getVal, false}, {"getSource", &BonusProxy::getSource, false}, {"getSourceID", &BonusProxy::getSourceID, false}, {"getEffectRange", &BonusProxy::getEffectRange, false}, {"getStacking", &BonusProxy::getStacking, false}, {"getDescription", &BonusProxy::getDescription, false}, {"toJsonNode", &BonusProxy::toJsonNode, false} }; int BonusProxy::getType(lua_State * L) { LuaStack S(L); std::shared_ptr object; if(!S.tryGet(1, object)) return S.retNil(); return LuaStack::quickRetInt(L, object->type); } int BonusProxy::getSubtype(lua_State * L) { LuaStack S(L); std::shared_ptr object; if(!S.tryGet(1, object)) return S.retNil(); return LuaStack::quickRetInt(L, object->subtype.getNum()); } int BonusProxy::getDuration(lua_State * L) { LuaStack S(L); std::shared_ptr object; if(!S.tryGet(1, object)) return S.retNil(); return LuaStack::quickRetInt(L, object->duration); } int BonusProxy::getTurns(lua_State * L) { LuaStack S(L); std::shared_ptr object; if(!S.tryGet(1, object)) return S.retNil(); return LuaStack::quickRetInt(L, object->turnsRemain); } int BonusProxy::getValueType(lua_State * L) { LuaStack S(L); std::shared_ptr object; if(!S.tryGet(1, object)) return S.retNil(); return LuaStack::quickRetInt(L, object->valType); } int BonusProxy::getVal(lua_State * L) { LuaStack S(L); std::shared_ptr object; if(!S.tryGet(1, object)) return S.retNil(); return LuaStack::quickRetInt(L, object->val); } int BonusProxy::getSource(lua_State * L) { LuaStack S(L); std::shared_ptr object; if(!S.tryGet(1, object)) return S.retNil(); return LuaStack::quickRetInt(L, object->source); } int BonusProxy::getSourceID(lua_State * L) { LuaStack S(L); std::shared_ptr object; if(!S.tryGet(1, object)) return S.retNil(); return LuaStack::quickRetInt(L, object->sid.getNum()); } int BonusProxy::getEffectRange(lua_State * L) { LuaStack S(L); std::shared_ptr object; if(!S.tryGet(1, object)) return S.retNil(); return LuaStack::quickRetInt(L, object->effectRange); } int BonusProxy::getStacking(lua_State * L) { LuaStack S(L); std::shared_ptr object; if(!S.tryGet(1, object)) return S.retNil(); return LuaStack::quickRetStr(L, object->stacking); } int BonusProxy::getDescription(lua_State * L) { LuaStack S(L); std::shared_ptr object; if(!S.tryGet(1, object)) return S.retNil(); return LuaStack::quickRetStr(L, object->description.toString()); } int BonusProxy::toJsonNode(lua_State * L) { LuaStack S(L); std::shared_ptr object; if(!S.tryGet(1, object)) return S.retNil(); S.clear(); S.push(object->toJsonNode()); return 1; } template static void publishMap(lua_State * L, const std::map & map) { for(auto & p : map) { const std::string & name = p.first; auto id = static_cast(p.second); lua_pushstring(L, name.c_str()); lua_pushinteger(L, id); lua_rawset(L, -3); } } template static void publishMap(lua_State * L, const std::map> & map) { for(auto & p : map) { const std::string & name = p.first; auto id = static_cast(p.second.to_ulong()); lua_pushstring(L, name.c_str()); lua_pushinteger(L, id); lua_rawset(L, -3); } } void BonusProxy::adjustStaticTable(lua_State * L) const { publishMap(L, bonusNameMap); publishMap(L, bonusValueMap); publishMap(L, bonusSourceMap); publishMap(L, bonusDurationMap); } VCMI_REGISTER_SCRIPT_API(BonusListProxy, "BonusList"); const std::vector BonusListProxy::REGISTER_CUSTOM = { }; std::shared_ptr BonusListProxy::index(std::shared_ptr self, int key) { //field = __index(self, key) std::shared_ptr ret; if((key >= 1) && (key <= self->size())) ret = (*self)[key-1]; return ret; } void BonusListProxy::adjustMetatable(lua_State * L) const { lua_pushstring(L, "__index"); lua_pushcclosure(L, LuaFunctionWrapper::invoke, 0); lua_rawset(L, -3); } VCMI_REGISTER_SCRIPT_API(BonusBearerProxy, "BonusBearer"); const std::vector BonusBearerProxy::REGISTER_CUSTOM = { {"getBonuses", &BonusBearerProxy::getBonuses, false}, }; int BonusBearerProxy::getBonuses(lua_State * L) { LuaStack S(L); const IBonusBearer * object = nullptr; if(!S.tryGet(1, object)) return S.retNil(); TConstBonusListPtr ret; const bool hasSelector = S.isFunction(2); const bool hasRangeSelector = S.isFunction(3); if(hasSelector) { auto selector = [](const Bonus * b) { return false; //TODO: BonusBearerProxy::getBonuses selector }; if(hasRangeSelector) { auto rangeSelector = [](const Bonus * b) { return false;//TODO: BonusBearerProxy::getBonuses rangeSelector }; ret = object->getBonuses(selector, rangeSelector); } else { ret = object->getBonuses(selector, Selector::all); } } else { ret = object->getBonuses(Selector::all, Selector::all); } S.clear(); S.push(ret); return S.retPushed(); } } } VCMI_LIB_NAMESPACE_END