Setting origin for projectile - AUTOMATIC1111/IntoTheBreachLua GitHub Wiki
Function GetSkillEffect(p1,p2) defines what should happen when you use a weapon.
An example:
function SAMPLE_Grenade_Launcher:GetSkillEffect(p1, p2)
local ret = SkillEffect()
local damage = SpaceDamage(p2, DAMAGE_DEATH)
ret:AddProjectile(damage, "effects/shot_fist", FULL_DELAY)
return ret
endThis creates a projectile that goes from the pawn that is using the weapon to the target pawn, dealing lethal damage. The origin of the projectile attack is pawn at p1, even though this is never specified in the code.
Suppose you want the projectile attack to originate from the side of the map, and not from your pawn at p1.
We know that SkillEffect has piOrigin propery, which specifies exactly what we want - where the projectile attack originates from. In file env_volcano.lua you can find effect.piOrigin = Point(0,0), which sets the origin point for the fireball for the volcano in the last mission.
Alas, just setting ret.piOrigin = <...> in GetSkillEffect(p1,p2) does not work - presumably, the game overwrites this property after GetSkillEffect(p1,p2) returns.
The solution is to create SkillEffect() object, but instad of returning it from function, apply it to game by executing Board:AddEffect(effect).
function SAMPLE_Grenade_Launcher:GetSkillEffect(p1, p2)
local ret = SkillEffect()
local effect = SkillEffect()
local damage = SpaceDamage(p2, DAMAGE_DEATH)
effect.piOrigin = Point(0,p2.y)
effect:AddProjectile(damage, "effects/shot_fist", FULL_DELAY)
Board:AddEffect(effect)
return ret
endUnfortunately, with this code, the projectile will fire when you hover the mouse over the enemy, which is definitely something we don't want. The reason for that is that game calls GetSkillEffect(p1, p2) even before you use the weapon, to find out how much damage it would do and how it will affect the board (pushing, smoke, ...). So it's incorrect to use Board:AddEffect() directly in this function.
The solution to this is to use SkillEffect:AddScript() function, which lets you execute arbitrary code when the effect happens:
function SAMPLE_Grenade_Launcher:GetSkillEffect(p1, p2)
local ret = SkillEffect()
local damage = SpaceDamage(p2, DAMAGE_DEATH)
ret:AddProjectile(damage, "effects/shot_fist", FULL_DELAY)
ret:AddScript("LOG('Got em!')")
return ret
endThe code above will add a message to game console when the weapon is fired.
A common practice is to create a global function that executes your effect, and add a call to this function using ret:AddScript().
function SAMPLE_Grenade_Launcher.Shoot_The_Thing(p2)
local effect = SkillEffect()
effect.iOwner = ENV_EFFECT
effect.piOrigin = Point(0,p2.y)
effect:AddSound("/weapons/fireball")
local damage = SpaceDamage(p2, DAMAGE_DEATH)
damage.iFire = 1
damage.sAnimation = "explo_fire1"
effect:AddProjectile(damage, "effects/shot_fist", FULL_DELAY)
Board:AddEffect(effect)
end
function SAMPLE_Grenade_Launcher:GetSkillEffect(p1, p2)
local ret = SkillEffect()
ret:AddScript("SAMPLE_Grenade_Launcher.Shoot_The_Thing("..p2:GetString()..")")
-- alternatively:
-- ret:AddScript("SAMPLE_Grenade_Launcher.Shoot_The_Thing(Point("..p2.x..","..p2.y.."))")
return ret
end