[Tutorial] Make a magic missile (or other projectile) spell
Posted: Fri Oct 26, 2012 11:08 pm
Due to limitations of current custom spell support I had to invent a workaround for making projectile spells.
See this thread: viewtopic.php?f=14&t=3846
So I made a small tutorial about it as I promised
I will post this to grimwiki too.
how to make a properly working magic missile (or other projectile spell)
First we have to make a spell projectile model, for that a blue gem retextured with white_light material works nicely, this tutorial will not cover retexturing process, but you can download already retextured spell_projectile.model from here:
https://docs.google.com/open?id=0B7cR7s ... ENwRG5zamM
Save the spell_projectile.model file to your mods mod_assest/models/ directory
Next phase is to define an object which uses that model
mod_assets/scripts/objects.lua
Now lets clone it as a magic missile
Define white glowing particle effect for magic missile
Ok, now we have an item that can be used as a projectile and looks like a white glowing ball of light.
But now it's time to do the real magic, so lets do some scripting.
Define the magic_missle spell
onCast-hook calls a function castMagicMissile from script entity named as mymod_spells(you can change that).
Of course the mymod_spells script entity does not exist yet so we have to create it in editor.
mymod_spells script entity
Now we can cast the magic missile (rune A). That was pretty easy right? BUT the caster or party will never get XP for kills made by magic missile spell.
So if we wan't to implement that, things do get bit trickier. For that we have to setup a onParticleHit hook for EVERY monster, but on this tutorial I will set it up for snail only.
mod_assets/scripts/monsters.lua
You can use a for loop to define that hook to all monsters. You just need a list of monsters.
Now we have to extend the mymod_spells script entity and add that function called from onProjectileHit-hook.
See this post about the damageTile flags argument: viewtopic.php?f=14&t=3861#p40130
See this thread: viewtopic.php?f=14&t=3846
So I made a small tutorial about it as I promised

I will post this to grimwiki too.
how to make a properly working magic missile (or other projectile spell)
First we have to make a spell projectile model, for that a blue gem retextured with white_light material works nicely, this tutorial will not cover retexturing process, but you can download already retextured spell_projectile.model from here:
https://docs.google.com/open?id=0B7cR7s ... ENwRG5zamM
Save the spell_projectile.model file to your mods mod_assest/models/ directory
Next phase is to define an object which uses that model
mod_assets/scripts/objects.lua
Code: Select all
--general spell projectile object
defineObject{
name = "spell_projectile",
class = "Item",
uiName = "Spell projectile",
model = "mod_assets/models/spell_projectile.fbx",
gfxIndex = 109,
attackPower = 1,
impactSound = "fireball_hit",
stackable = false,
sharpProjectile = false,
projectileRotationY = 0,
weight = 0,
}
Code: Select all
cloneObject{
name = "magic_missile",
baseObject = "spell_projectile",
uiName = "Magic missile",
particleEffect = "magic_missile",
}
Code: Select all
defineParticleSystem{
name = "magic_missile",
emitters = {
-- glow
{
spawnBurst = true,
emissionRate = 1,
emissionTime = 0,
maxParticles = 1,
boxMin = {-0.0, -0.0, 0.0},
boxMax = { 0.0, 0.0, -0.0},
sprayAngle = {0,30},
velocity = {0,0},
texture = "assets/textures/particles/glow.tga",
lifetime = {1000000, 1000000},
colorAnimation = false,
color0 = {1, 1, 1},
opacity = 1,
fadeIn = 0.1,
fadeOut = 0.1,
size = {0.8, 0.8},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 2,
blendMode = "Additive",
objectSpace = true,
}
}
}
But now it's time to do the real magic, so lets do some scripting.
Define the magic_missle spell
Code: Select all
defineSpell{
name = "magic_missile",
uiName = "Magic missile",
skill = "fire_magic",
level = 1,
runes = "A",
manaCost = 15,
description = "The mage creates a bolt of magic force that unerringly strikes one target.",
onCast = function(caster,x,y,direction,skill)
mymod_spells.castMagicMissile(caster,x,y,direction,skill)
end
}
Of course the mymod_spells script entity does not exist yet so we have to create it in editor.
mymod_spells script entity
Code: Select all
function castMagicMissile(caster,x,y,direction,skill)
shootProjectile('magic_missile', party.level, x, y, direction, 14, 0, 0, 0, 0, 0,10, party, true)
end
So if we wan't to implement that, things do get bit trickier. For that we have to setup a onParticleHit hook for EVERY monster, but on this tutorial I will set it up for snail only.
mod_assets/scripts/monsters.lua
Code: Select all
cloneObject{
name = "snail",
baseObject = "snail",
onProjectileHit = function(monster,projectile)
return mymod_spells.magicMissileOnProjectileHitHook(monster,projectile)
end
}
Now we have to extend the mymod_spells script entity and add that function called from onProjectileHit-hook.
Code: Select all
-- we have to store the caster ordinal here
-- so that we can calculate the right originator for damageTile on magicMissileOnProjectileHitHook
spellCasters = 0
function castMagicMissile(caster,x,y,direction,skill)
shootProjectile('magic_missile', party.level, x, y, direction, 14, 0, 0, 0, 0, 0,100, party, true)
spellCaster = caster:getOrdinal()
end
-- we have to use damageTile to deal the spell damage to monsters because that is the only way to give xp for the spell caster for kills
function magicMissileOnProjectileHitHook(monster,projectile)
if projectile.name == 'magic_missile' then
local originator = 2 ^ (spellCaster+1) -- calculate the originator of the spell
local damage = math.random(2,10) --
damageTile(monster.level,monster.x,monster.y,(monster.facing + 2)%4,originator+1, 'physical',damage)
playSoundAt("fireball_hit",monster.level,monster.x,monster.y)
return false
end
end