mirror of
https://github.com/vcmi/vcmi.git
synced 2026-05-22 09:55:17 +02:00
179 lines
5.6 KiB
Lua
179 lines
5.6 KiB
Lua
meta = {
|
|
type = spellEffect,
|
|
spellEffectSchema = {
|
|
required = { "id" },
|
|
properties = {
|
|
type = {},
|
|
indirect = {},
|
|
optional = {},
|
|
id = { type = "string" }, -- type of creature that can be summoned by the spell
|
|
permanent = { type = "boolean" }, -- if true, summoned units persists after combat
|
|
exclusive = { type = "boolean" }, -- if true, spell can only be used if there are no summoned units of another typee
|
|
summonByHealth = { type = "boolean" }, -- if true, spell effect power represents summoned health, if not - summoned amount
|
|
summonSameUnit = { type = "boolean" } -- if true, spell will increase stack size of existing summon, if available, instead of summoning a separate stack
|
|
},
|
|
additionalProperties = false
|
|
}
|
|
}
|
|
|
|
local function summonedEffectValue(parameters, mechanics)
|
|
local effectPower = mechanics:getEffectPower()
|
|
local rawEffectPower = mechanics:calculateRawEffectValue(0, effectPower)
|
|
local finalEffectPower = mechanics:applySpecificSpellBonus(rawEffectPower)
|
|
|
|
return finalEffectPower
|
|
end
|
|
|
|
local function summonedCreatureHealth(parameters, mechanics)
|
|
local valueWithBonus = summonedEffectValue(parameters, mechanics)
|
|
local creature = LIBRARY:getCreatureByName(parameters.id)
|
|
if parameters.summonByHealth then
|
|
return valueWithBonus
|
|
else
|
|
return valueWithBonus * creature:getMaxHealth()
|
|
end
|
|
end
|
|
|
|
local function summonedCreatureAmount(parameters, mechanics)
|
|
local valueWithBonus = summonedEffectValue(parameters, mechanics)
|
|
local creature = LIBRARY:getCreatureByName(parameters.id)
|
|
if parameters.summonByHealth then
|
|
return math.floor(valueWithBonus / creature:getMaxHealth())
|
|
else
|
|
return valueWithBonus
|
|
end
|
|
end
|
|
|
|
-- TODO
|
|
-- initializes parameters of the script using spell effect json
|
|
-- returns converted parameters that contain resolved identifiers
|
|
initialize = function(parameters)
|
|
parameters.creature = LIBRARY:getCreatureByName(parameters.id)
|
|
return parameters
|
|
end
|
|
|
|
--- Returns true if specified target can be affected by the spell
|
|
--- if target can not be affected, script needs to call `problem:add`
|
|
--- to explain the reason to the player
|
|
applicableTarget = function(parameters, mechanics, problem, target)
|
|
return true
|
|
end
|
|
|
|
--- Returns true if spell can be casted in general
|
|
--- if no valid targets exist, script needs to call `problem:add`
|
|
--- to explain the reason to the player
|
|
applicable = function(parameters, mechanics, problem)
|
|
local creature = LIBRARY:getCreatureByName(parameters.id)
|
|
|
|
if summonedCreatureAmount(parameters, mechanics) == 0 then
|
|
print("SpellEffectSummon: zero summoned creatures!")
|
|
return problem:addGeneric(mechanics:getCasterNameTextID())
|
|
end
|
|
|
|
-- check if there are summoned creatures of other type
|
|
if parameters.exclusive then
|
|
local elemental = mechanics:getBattle():getAnyUnitIf(function(unit)
|
|
return (unit:getOwner() == mechanics:getCasterColor())
|
|
and (unit:isSummoned())
|
|
and (not unit:isClone())
|
|
and (unit:getCreature():getJsonKey() ~= creature:getJsonKey())
|
|
end)
|
|
|
|
print("SpellEffectSummon - summoning:", creature:getJsonKey(), " elemental is ", elemental)
|
|
if elemental ~= nil then
|
|
local hero = mechanics:getHeroCaster()
|
|
local himHer = "core.genrltxt.539"
|
|
if hero ~= nil and hero.isFemale() then
|
|
himHer = "core.genrltxt.540"
|
|
end
|
|
|
|
if hero ~= nil then
|
|
problem:add({
|
|
append = "core.genrltxt.538",
|
|
replace = {
|
|
hero:getNameTextID(),
|
|
elemental:getNamePluralTextID(),
|
|
himHer
|
|
}
|
|
})
|
|
else
|
|
problem:add({
|
|
append = "core.genrltxt.538"
|
|
})
|
|
end
|
|
print("SpellEffectSummon - summoning:", creature:getJsonKey(), " already summoned: ", elemental:getCreature():getJsonKey())
|
|
return false
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
--- Actually casts the spells and applies all changes caused by spell
|
|
--- use `server` parameter to apply changes on specified target(s)
|
|
apply = function(parameters, mechanics, server, target)
|
|
local creature = LIBRARY:getCreatureByName(parameters.id)
|
|
|
|
for _, dest in ipairs(target) do
|
|
if dest.unit ~= nil then
|
|
server:healUnit(
|
|
mechanics:getBattleID(),
|
|
dest.unit,
|
|
summonedCreatureHealth(parameters, mechanics),
|
|
ENUM.HealLevel.overheal,
|
|
parameters.permanent and ENUM.HealPower.permanent or ENUM.HealPower.oneBattle
|
|
)
|
|
else
|
|
print("SpellEffectSummon. Hex: ", dest.hex)
|
|
assert(dest.hex ~= nil)
|
|
server:createUnit(
|
|
mechanics:getBattleID(),
|
|
mechanics:getBattle():getNextUnitId(),
|
|
{
|
|
count = summonedCreatureAmount(parameters, mechanics),
|
|
type = creature:getJsonKey(),
|
|
side = mechanics:getCasterSide(),
|
|
position = dest.hex:toInteger(),
|
|
summoned = not parameters.permanent
|
|
}
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
--- converts specified range into actual list of affected targets
|
|
--- for example, area damage spells should locate all units on affected hexes
|
|
--- and return list of affected units
|
|
transformTarget = function(parameters, mechanics, aimPoint, spellTarget)
|
|
local creature = LIBRARY:getCreatureByName(parameters.id)
|
|
local sameSummoned = mechanics:getBattle():getAnyUnitIf(function(unit)
|
|
return (unit:getOwner() == mechanics:getCasterColor())
|
|
and (unit:isSummoned())
|
|
and (not unit:isClone())
|
|
and (unit:getCreature():getJsonKey() == creature:getJsonKey())
|
|
and (unit:isAlive())
|
|
end)
|
|
|
|
if sameSummoned == nil or not parameters.summonSameUnit then
|
|
local hex = mechanics:getBattle():getAvailableHex(creature, mechanics:getCasterSide())
|
|
if not hex:isValid() then
|
|
return {} -- no free space. FIXME: should be in isApplicable
|
|
else
|
|
return {
|
|
{
|
|
hex = hex,
|
|
unit = nil
|
|
}
|
|
}
|
|
end
|
|
else
|
|
return {
|
|
{
|
|
hex = sameSummoned:getPosition(),
|
|
unit = sameSummoned
|
|
}
|
|
}
|
|
end
|
|
end
|
|
|
|
|