diff --git a/include/vcmi/EntityService.h b/include/vcmi/EntityService.h index 96c90ca5d..58f49647c 100644 --- a/include/vcmi/EntityService.h +++ b/include/vcmi/EntityService.h @@ -29,6 +29,7 @@ class DLL_LINKAGE EntityServiceT : public EntityService public: virtual const EntityType * getById(const IdType & id) const = 0; virtual const EntityType * getByIndex(const int32_t index) const = 0; + virtual const EntityType * getByName(const std::string & name) const = 0; virtual void forEach(const std::function & cb) const = 0; }; diff --git a/include/vcmi/scripting/Service.h b/include/vcmi/scripting/Service.h index 5670f4c23..5b5901fe8 100644 --- a/include/vcmi/scripting/Service.h +++ b/include/vcmi/scripting/Service.h @@ -33,7 +33,6 @@ public: virtual void run(ServerCallback * server, const JsonNode & initialState) = 0; virtual JsonNode callGlobal(const std::string & name, const JsonNode & parameters) = 0; - virtual JsonNode callGlobal(ServerCallback * server, const std::string & name, const JsonNode & parameters) = 0; virtual void setGlobal(const std::string & name, int value) = 0; virtual void setGlobal(const std::string & name, const std::string & value) = 0; diff --git a/lib/IHandlerBase.cpp b/lib/IHandlerBase.cpp index 618f09087..2bb207e36 100644 --- a/lib/IHandlerBase.cpp +++ b/lib/IHandlerBase.cpp @@ -41,4 +41,9 @@ void IHandlerBase::registerObject(const std::string & scope, const std::string & } } +std::optional IHandlerBase::resolveIdentifier(const std::string & scope, const std::string & typeName, const std::string & name) const +{ + return LIBRARY->identifiersHandler->getIdentifier(scope, typeName, name); +} + VCMI_LIB_NAMESPACE_END diff --git a/lib/IHandlerBase.h b/lib/IHandlerBase.h index ae93e1b03..21c7cd972 100644 --- a/lib/IHandlerBase.h +++ b/lib/IHandlerBase.h @@ -24,6 +24,7 @@ protected: void registerObject(const std::string & scope, const std::string & typeName, const std::string & name, const JsonNode & data, si32 index); void registerObject(const std::string & scope, const std::vector & typeNames, const std::string & name, const JsonNode & data, si32 index); + std::optional resolveIdentifier(const std::string & scope, const std::string & typeName, const std::string & name) const; public: /// loads all original game data in vector of json nodes /// dataSize - is number of items that must be loaded (normally - constant from GameConstants) @@ -79,6 +80,16 @@ public: return getObjectImpl(index); } + const _ObjectBase * getByName(const std::string & name) const override + { + // TODO: provide actual scope? Perhaps pass it as json node? + auto index = resolveIdentifier(getScopeBuiltin(), getTypeNames().front(), name); + if (index) + return getByIndex(*index); + else + return nullptr; + } + void forEachBase(const std::function & cb) const override { forEachT(cb); diff --git a/luascript/LuaContext.cpp b/luascript/LuaContext.cpp index c968d031d..85c710f6e 100644 --- a/luascript/LuaContext.cpp +++ b/luascript/LuaContext.cpp @@ -217,20 +217,6 @@ JsonNode LuaContext::callGlobal(const std::string & name, const JsonNode & param return ret; } -JsonNode LuaContext::callGlobal(ServerCallback * cb, const std::string & name, const JsonNode & parameters) -{ - LuaStack S(L); - S.push(cb); - lua_setglobal(L, "SERVER"); - - auto ret = callGlobal(name, parameters); - - S.pushNil(); - lua_setglobal(L, "SERVER"); - - return ret; -} - void LuaContext::getGlobal(const std::string & name, int & value) { LuaStack S(L); diff --git a/luascript/LuaContext.h b/luascript/LuaContext.h index fac8a1c25..2d2a844bd 100644 --- a/luascript/LuaContext.h +++ b/luascript/LuaContext.h @@ -36,7 +36,6 @@ public: int errorRetVoid(const std::string & message); JsonNode callGlobal(const std::string & name, const JsonNode & parameters) override; - JsonNode callGlobal(ServerCallback * cb, const std::string & name, const JsonNode & parameters) override; template JsonNode callGlobalWithParameters(const std::string & name, Args&& ... parameters); diff --git a/scripts/SpellEffectSummon.lua b/scripts/SpellEffectSummon.lua index ffe6352c3..8964a1d38 100644 --- a/scripts/SpellEffectSummon.lua +++ b/scripts/SpellEffectSummon.lua @@ -20,25 +20,28 @@ end local function summonedCreatureHealth(parameters, mechanics) local valueWithBonus = summonedEffectValue(parameters, mechanics) + local creature = SERVICES.creatures.getByName(parameters.creature) if parameters.summonByHealth then return valueWithBonus else - return valueWithBonus * parameters.creature:getMaxHealth() + return valueWithBonus * creature:getMaxHealth() end end local function summonedCreatureAmount(parameters, mechanics) local valueWithBonus = summonedEffectValue(parameters, mechanics) + local creature = SERVICES.creatures.getByName(parameters.creature) if parameters.summonByHealth then - return math.floor(valueWithBonus / parameters.creature:getMaxHealth()) + return math.floor(valueWithBonus / creature:getMaxHealth()) else return valueWithBonus end end applicable = function(parameters, mechanics, problem) - if parameters.creature == "nil" then + local creature = SERVICES.creatures.getByName(parameters.creature) + if creature == "nil" then return false -- mechanics:adaptGenericProblem(problem) end @@ -83,8 +86,7 @@ applicable = function(parameters, mechanics, problem) end apply = function(parameters, mechanics, server, target) - local pack = BattleUnitsChanged.new() - pack.battleID = mechanics:getBattleID() + local creature = SERVICES.creatures.getByName(parameters.creature) for _, dest in ipairs(target) do if dest.unitValue then @@ -99,6 +101,7 @@ apply = function(parameters, mechanics, server, target) ) server:battleUnitChanged( + mechanics:getBattleID(), summoned:unitId(), UnitChanges.EOperation.UPDATE, state:save() @@ -106,6 +109,7 @@ apply = function(parameters, mechanics, server, target) else server:battleUnitChanged( + mechanics:getBattleID(), mechanics:getBattle():getNextUnitId(), UnitChanges.EOperation.ADD, { @@ -125,6 +129,7 @@ apply = function(parameters, mechanics, server, target) end transformTarget = function(parameters, mechanics, aimPoint, spellTarget) + local creature = SERVICES.creatures.getByName(parameters.creature) local sameSummoned = mechanics:getBattle():getAnyUnitIf(function(unit) return (unit:getOwner() == mechanics:getCasterColor()) and (unit:isSummoned())