@Andakrainor, I agree with minmay with setting custom variables to game objects. You are asking for big trouble when you save, in the form of game crashes or warnings. I like your solutions but they still do not address that the spell looks like its cast from the tile and not the champion who cast it. Below I will detail a solution I figured out that does that and is enough for me to call this solved.
But first, @minmay, regarding why worry about the champion who cast the spell in TIleDamager. The game does for "poison_bolt". See this code from poison_bolt.lua:
Code: Select all
onHitMonster = function(self, monster)
monster:setCondition("poisoned", 25)
-- mark condition so that exp is awarded if monster is killed by the condition
local poisonedCondition = monster.go.poisoned
local ord = self:getCastByChampion()
if poisonedCondition and ord then
poisonedCondition:setCausedByChampion(ord)
end
end,
The above code will not work like that unless it is cast as a built-in spell. I experimented quite a bit on it.
So, here is my solution to this. In order to take advantage of proper setting of the Champion who cast the spell, both on the Projectile and on the TileDamager, and also to see proper casting from that Champion, I had to re-use a built-in spell. But I re-defined it. I created a "Green Fireball". It is the same as the default fireball but I changed all of the color vectors to a shade of green. NOTE, that the built-in "fireball" spell creates game object, "fireball_large".
First my spell (ignore all that test_skill stuff, that was another test)
Code: Select all
defineSpell{
name = "green_fireball",
uiName = "Green Fireball",
gesture = 125,
manaCost = 43,
onCast="fireball",
skill = "test_skill",
requirements = { "test_skill", 1},
icon = 61,
spellIcon = 7,
description = "A flaming ball of fire shoots from your hands.",
}
Then re-define of what the game calls for "FireBall":
Code: Select all
defineObject{
name = "fireball_large",
baseObject = "base_spell",
components = {
{
class = "Particle",
particleSystem = "fireball_large",
onInit =
function(self)
--print("in fireball override particle init")
local spell = party.data:get("castSpell")
if spell == "green_fireball" then
self:setParticleSystem("green_fireball")
end
end
},
{
class = "Light",
color = vec(1, 0.5, 0.25),
brightness = 15,
range = 7,
castShadow = true,
onInit =
function(self)
--print("in fireball override light init")
local spell = party.data:get("castSpell")
if spell == "green_fireball" then
self:setColor(vec(0.4, 1, 0.25))
end
end
},
{
class = "Projectile",
spawnOffsetY = 1.35,
velocity = 10,
radius = 0.1,
hitEffect = "fireball_blast_large",
onInit =
function(self)
--print("in fireball override projectile init")
local spell = party.data:get("castSpell")
if spell == "green_fireball" then
self:setHitEffect("green_fireball_blast")
end
end,
onProjectileHit =
function(self, what, entity)
local spell = party.data:get("castSpell")
if what == "entity" then
print("fireball_override onProjectileHit", spell, what, entity.name, self:getHitEffect(), self:getCastByChampion())
else
print("fireball_override onProjectileHit", spell, what, entity)
end
end
},
{
class = "Sound",
sound = "fireball",
},
{
class = "Sound",
name = "launchSound",
sound = "fireball_launch",
},
},
}
The key to this is overriding the default particleSystem, light and projectile behavior by using the onInit() hook. Also, you will see my solution to storing custom data on game objects. I am using a very cool "data" component that someone on the forum came up with. I'd give credit here if I could remember who. I use it everywhere and it works great. Its a "ScriptComponent" definition with built in getter and setters for any data you want to put on an object. Based on the value I get from this data, it determines how to customize the spell. Note that if I don't get anything, it implies the normal game fireball was cast and the defaults are used.
Here is the code from my party's onCastSpell() method where I set the "data" for "castSpell":
Code: Select all
onCastSpell =
function(self, champion, spell)
print("in party onCastSpell", champion:getOrdinal(), spell)
self.go.data:set("castSpell", spell)
end
And lastly, here is the definition of the custom fireball_blast, set by "hitEffect" in the projectile onInit():
Code: Select all
defineObject{
name = "green_fireball_blast",
baseObject = "base_spell",
components = {
{
class = "Particle",
particleSystem = "green_fireball_blast",
destroyObject = true,
},
{
class = "Light",
--color = vec(1, 0.5, 0.25),
color = vec(0.1, 1.0, 0.3),
brightness = 40,
range = 10,
fadeOut = 0.5,
disableSelf = true,
},
{
class = "TileDamager",
attackPower = 70,
damageType = "fire",
sound = "fireball_hit",
screenEffect = "green_fireball_screen",
woundChance = 40,
onHitObstacle = function(self, obstacle)
local ord = self:getCastByChampion()
print("in green_fireball onHitObstacle", obstacle.go.id, ord)
end,
onHitMonster = function(self, monster)
local ord = self:getCastByChampion()
print("in green_fireball onHitMonster", monster.go.id, ord, self:getDestroyObject())
end,
},
},
}
In this code you will see that the print statement with show the ordinal of who cast the spell. Because it started as a built-in spell, it works.
I didn't include the particle defines here. Just copy the ones for fireball and modify as you need.