gref
New Member
- Reaction score
- 33
Magic Missile
MUI: Yes.
Leakless: Yes.
Lagless: Yes.
JESP: Yes.
Jass/GUI: Jass
Screenshot:
Description:
This is a spell in the spirit of the Baldur's Gate spell Magic Missile. This spell creates one missile per level of the ability, which darts forth from the wizard's finger-tip to unerringly strikes its target, dealing X damage per missile.
This will go up to at least 100 missiles. I tested that, but thought going any further was ridiculous.
Made in Jass
How to Implement:
MUI: Yes.
Leakless: Yes.
Lagless: Yes.
JESP: Yes.
Jass/GUI: Jass
Screenshot:
Description:
This is a spell in the spirit of the Baldur's Gate spell Magic Missile. This spell creates one missile per level of the ability, which darts forth from the wizard's finger-tip to unerringly strikes its target, dealing X damage per missile.
This will go up to at least 100 missiles. I tested that, but thought going any further was ridiculous.
Made in Jass
JASS:
//===============================>
// Magic Missile by gref.
//===============================>
scope MagicMissile
// Follows JESP
//===========================>
//Constants
//===========================>
globals
private constant integer AbilCode = 039;A000039; //Name of triggering ability
private constant integer UnitCode = 039;h000039; //Name of unit used for missile
private constant real width_factor = .002 // width of flight factor
private constant real distance_per_tick = 30.0 // speed
private constant real damage_amount = 100.0 //Amount of damage per missile
// The effect used when the missile hits the target.
private constant string missile_effect = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl"
endglobals
//===========================>
//Data Types
//===========================>
struct MissileStruct
unit missile
real factor
real covered
real distance
real angle
real speed
unit target
real x
real y
method onDestroy takes nothing returns nothing
call UnitDamageTarget(.missile, .target, damage_amount, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
call DestroyEffect(AddSpecialEffect(missile_effect, GetUnitX(.missile), GetUnitY(.missile)))
call CleanAttachedVars(.missile)
call RemoveUnit(.missile)
set .missile = null
set .target = null
endmethod
static method create takes unit missile, real distance, real angle, unit target returns MissileStruct
local MissileStruct m = MissileStruct.allocate()
set m.distance = distance
set m.missile = missile
set m.covered = 0
set m.x = GetUnitX(missile)
set m.y = GetUnitY(missile)
set m.angle = angle
set m.target = target
set m.speed = 1
return m
endmethod
method advance takes nothing returns boolean
local real x
local real y
local real offset
local real angle
if(.covered < .distance/2) then
set .covered = .covered + distance_per_tick*.speed
set offset = -1*.factor*(.covered*.covered-.distance*.covered)
set x = .x + .covered*Cos(.angle*bj_DEGTORAD)
set y = .y + .covered*Sin(.angle*bj_DEGTORAD)
set x = x + offset*Cos((.angle+90)*bj_DEGTORAD)
set y = y + offset*Sin((.angle+90)*bj_DEGTORAD)
call SetUnitPosition(.missile, x, y)
else
set angle = bj_RADTODEG * Atan2(GetUnitY(.target) - GetUnitY(.missile), GetUnitX(.target) - GetUnitX(.missile))
set x = GetUnitX(.missile)+distance_per_tick*.speed*Cos(angle*bj_DEGTORAD)
set y = GetUnitY(.missile)+distance_per_tick*.speed*Sin(angle*bj_DEGTORAD)
call SetUnitPosition(.missile, x, y)
endif
set .speed = .speed*1.025
set y = (GetUnitY(.missile)-GetUnitY(.target))
set x = (GetUnitX(.missile)-GetUnitX(.target))
if(SquareRoot(x*x+y*y) < 50.0) then
return true
endif
return false
endmethod
endstruct
struct SpellStruct
group g
method onDestroy takes nothing returns nothing
call DestroyGroup(.g)
set .g = null
endmethod
static method create takes player owner, unit target, real distance, real x, real y, integer number, real angle returns SpellStruct
local SpellStruct s = SpellStruct.allocate()
local unit u
local real factor
local MissileStruct m
local integer i = 1
set s.g = CreateGroup()
//Create the right number of missiles.
loop
exitwhen i > number
set u = CreateUnit(owner, UnitCode, x, y, 0 )
call GroupAddUnit(s.g, u)
set m = MissileStruct.create(u, distance, angle, target)
if(((number/2)*2) != number) then //Number is odd
if(i == (number/2+1)) then //Center missile
set m.factor = 0
else
set m.factor = (((number/2+1)-i)*width_factor)/((distance/500) )
endif
else
if(i <= (number/2)) then
set m.factor = (((number/2+1)-i)*width_factor)/((distance/500) )
else
set m.factor = (((number/2)-i)*width_factor)/((distance/500) )
endif
endif
//Large number error checking.
if(number>10) then
set m.factor = m.factor*.3
endif
call AttachInt(u, "MissileStruct", m)
set i = i + 1
endloop
set u = null
return s
endmethod
endstruct
//===========================>
//Private Functions
//===========================>
function TimerTick takes nothing returns nothing
local timer t = GetExpiredTimer()
local SpellStruct s = GetAttachedInt(t, "SpellStruct")
local MissileStruct m
local unit u
local group g = CreateGroup()
loop
set u = FirstOfGroup(s.g)
exitwhen u == null
set m = GetAttachedInt(u, "MissileStruct")
if(m.advance()) then
call MissileStruct.destroy(m)
else
call GroupAddUnit(g, u)
endif
call GroupRemoveUnit(s.g, u)
endloop
if (FirstOfGroup(g) == null) then //all missiles hit.
call SpellStruct.destroy(s)
call CleanAttachedVars(t)
call DestroyTimer(t)
else
call DestroyGroup(s.g)
set s.g = g
endif
set u = null
set g = null
set t = null
endfunction
//===========================>
//Trigger Functions
//===========================>
function Trig_MagicMissile_Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilCode
endfunction
function Trig_MagicMissile_Actions takes nothing returns nothing
local timer t = CreateTimer()
local real face = GetUnitFacing(GetTriggerUnit())
local real x = GetUnitX(GetTriggerUnit()) + 100*Cos(face*bj_DEGTORAD)
local real y = GetUnitY(GetTriggerUnit()) + 100*Sin(face*bj_DEGTORAD)
local real x1 = GetUnitX(GetSpellTargetUnit())
local real y1 = GetUnitY(GetSpellTargetUnit())
local real distance = SquareRoot((x1-x)*(x1-x)+(y1-y)*(y1-y))
local SpellStruct s = SpellStruct.create(GetOwningPlayer(GetTriggerUnit()), GetSpellTargetUnit(), distance, x, y, GetUnitAbilityLevel(GetTriggerUnit(), AbilCode), face)
call AttachInt(t, "SpellStruct", s)
call TimerStart(t, 0.05, true, function TimerTick)
set t = null
endfunction
endscope
//===========================================================================
function InitTrig_MagicMissile takes nothing returns nothing
set gg_trg_MagicMissile = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_MagicMissile, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_MagicMissile, Condition(function Trig_MagicMissile_Conditions))
call TriggerAddAction( gg_trg_MagicMissile, function Trig_MagicMissile_Actions )
endfunction
Spell Requirements:
1. A vJass preprocessor (If you don't have one you can download one from wc3campaigns.net)
How to implement this in your map:
1. Copy the CSCache and MagicMissile triggers to your map. (If you have CSCache, don't worry about it)
2. Copy the unit called Missile in the object editor.
3. Copy the ability called Magic Missile in the object editor.
1. A vJass preprocessor (If you don't have one you can download one from wc3campaigns.net)
How to implement this in your map:
1. Copy the CSCache and MagicMissile triggers to your map. (If you have CSCache, don't worry about it)
2. Copy the unit called Missile in the object editor.
3. Copy the ability called Magic Missile in the object editor.