Hello !
Here is a little update on my custom spells, with one example spell named Fire & Ice. It is supposed to launch several fireballs and frostbolts. To cast it, use the same gesture as the meteor spell, but replace the air rune with the water rune.
in spells.lua :
Code: Select all
defineSpell{
name = "fire_and_ice",
uiName = "Fire & Ice",
skill = "fire_magic",
requirements = {"fire_magic", 4, "water_magic", 4},
gesture = 14569,
manaCost = 80,
icon = 72,
spellIcon = 13,
description = "Unleashes a devastating storm of fire and ice on your foes.",
onCast = function(champion, x, y, direction, elevation, skillLevel)
delayedCall("script_center", 0, "multi", champion:getCurrentStat("willpower")*skillLevel/10, {"fireball", "frostbolt"}, 2)
end
}
in scripts.lua (the source file for the script entity "script_center") :
Code: Select all
function multi(power, tab, length)
power = quantum(power)
local start = math.random(length)
for i = 0, power do delayedCall("script_center", i/power, tab[1 + (start + i)%length]) end
end
function quantum(float)
local i = math.floor(float)
if math.random() < float-i then return i+1 else return i end
end
function checkEmpty()
local x = party.x
local y = party.y
local direction = party.facing
local elevation = party.elevation
local myx = x
local myy = y
if direction == 0 then myy = y-1 elseif direction == 1 then myx = x+1 elseif direction == 2 then myy = y+1 else myx = x-1 end
if party.map:checkLineOfFire(x,y,myx,myy,elevation) then return true else return false end
end
function fireball()
local x = party.x
local y = party.y
local direction = party.facing
local elevation = party.elevation - 0.25 + 0.5*math.random()
if checkEmpty() then
if direction == 0 then y = y-1 elseif direction == 1 then x = x+1 elseif direction == 2 then y = y+1 else x = x-1 end
end
local ball = spawn("fireball_medium_custom", party.level, x, y, direction, elevation)
ball:setSubtileOffset(math.random() - 0.5, math.random() - 0.5)
end
function frostbolt()
local x = party.x
local y = party.y
local direction = party.facing
local elevation = party.elevation - 0.25 + 0.5*math.random()
if checkEmpty() then
if direction == 0 then y = y-1 elseif direction == 1 then x = x+1 elseif direction == 2 then y = y+1 else x = x-1 end
end
local bolt = spawn("frostbolt_custom", party.level, x, y, direction, elevation)
bolt:setSubtileOffset(math.random() - 0.5, math.random() - 0.5)
end
finally, in objects.lua :
Code: Select all
defineObject{
name = "fireball_medium_custom",
baseObject = "base_spell",
components = {
{
class = "Particle",
particleSystem = "fireball_medium",
},
{
class = "Light",
color = vec(1, 0.5, 0.25),
brightness = 15,
range = 7,
castShadow = true,
},
{
class = "Projectile",
spawnOffsetY = 1.35,
velocity = 10,
radius = 0.1,
hitEffect = "fireball_blast_medium_custom",
},
{
class = "Sound",
sound = "fireball",
},
{
class = "Sound",
name = "launchSound",
sound = "fireball_launch",
},
},
}
defineObject{
name = "fireball_blast_medium_custom",
baseObject = "base_spell",
components = {
{
class = "Particle",
particleSystem = "fireball_blast_medium",
destroyObject = true,
},
{
class = "Light",
color = vec(1, 0.5, 0.25),
brightness = 40,
range = 10,
fadeOut = 0.5,
disableSelf = true,
},
{
class = "TileDamager",
attackPower = 50,
castByChampion = 1,
damageType = "fire",
sound = "fireball_hit",
screenEffect = "fireball_screen",
woundChance = 20,
},
},
}
defineObject{
name = "frostbolt_custom",
baseObject = "base_spell",
components = {
{
class = "Particle",
particleSystem = "frostbolt",
},
{
class = "Light",
color = vec(0.25, 0.5, 1),
brightness = 15,
range = 7,
},
{
class = "Projectile",
spawnOffsetY = 1.35,
velocity = 10,
radius = 0.1,
hitEffect = "frostbolt_blast_custom",
},
{
class = "Sound",
sound = "frostbolt",
},
{
class = "Sound",
name = "launchSound",
sound = "frostbolt_launch",
},
},
}
defineObject{
name = "frostbolt_blast_custom",
baseObject = "base_spell",
components = {
{
class = "Particle",
particleSystem = "frostbolt_hit",
destroyObject = true,
},
{
class = "Light",
color = vec(0.25, 0.5, 1),
brightness = 40,
range = 10,
fadeOut = 0.5,
disableSelf = true,
},
{
class = "TileDamager",
attackPower = 10,
castByChampion = 1,
damageType = "cold",
sound = "frostbolt_hit",
onHitMonster = function(self, monster)
if math.random() < 0.25 then
monster:setCondition("frozen", 4)
end
end,
},
},
}
As you can see, I don't use a fixed number of bolts as the meteor spell does, but a formula with skillLevel and the caster's willpower (the spell is probably not balanced with this exact formula but this is another debate).
Also, I still have to find better icons, and a way to set the correct value for the castByChampion variable of the TileDamager component. In this example if I could do that from the fireball function in scripts.lua I could also remove completely the object definitions that are copy/paste of the original game with just custom names and "castByChampion = 1".
Finally, in this example, the line "skill = "fire_magic"," seems a little wrong, what about multiple / new magic schools or damage types in mods ?
What do you think about this spell ? Any idea about the syntax used to access this castByChampion variable ?