DotA Spell Pack 1
My first attempt at using ABC and TT, with some abilities not found in DotA Heroes. Toss and Black Hole were requested.
Includes:
Includes:
- Toss
- Ice Path
- Wild Axes
- Black Hole
Toss:
JASS:
scope Toss
//******************************************************************************************
//*
//* Toss - By emjlr3, Original seen in DotA Allstars
//*
//* Toss a friend or foe from here to there by targeting on a unit, and grabbing
//* a random target in the area, launching them towards the targeted area.
//*
//* Requires:
//* - "TT" trigger copied to your map, if not already there
//* - The "Toss" ability copied to your map
//* - A vJASS Preprocessor
//*
//******************************************************************************************
globals
// Config Globals:
private constant integer abil_id = 039;A001039; // Toss ability rawcode
private constant integer fly_id = 039;Amrf039; // Rawcode of ability to use for fly trick, if you have not touched Crow Form, this doesn't need changing
private constant real impact_damage = .20 // Percent of toss damage dealt to tossed unit
private constant real time = 1. // Flight time for tossed unit (seconds)
private constant string fly_sfx = "Abilities\\Spells\\Undead\\Cripple\\CrippleTarget.mdl" // Effect created on target during toss
private constant string end_sfx = "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl" // Effect created on target at end of toss
private constant boolean kill_trees = true // Whether trees are destroyed upon target landing
private constant attacktype attack_type = ATTACK_TYPE_NORMAL // Attack type used for damage
private constant damagetype damage_type = DAMAGE_TYPE_DEMOLITION // Damage type used for damage
// Needed Globals:
private group G = CreateGroup()
private unit U = null
private rect R = null
private location L = null
public trigger Trigger = null // Output trigger will be Toss_Trigger, which can be used publically
endglobals
// Config. Functions:
private function Damage takes integer lvl returns real
return 75.*lvl // Damage/lvl
endfunction
private function Area takes integer lvl returns real
return 275. // Area within to grab units and damage units/lvl
endfunction
//========================================================================================
private struct data
unit u
unit targ
player p
real xt
real yt
real xl
real yl
real dist
real ang
real cos
real sin
real speed
real hc
integer lvl
integer count = 1
effect e
static method FiltIsEnemy takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(), bj_groupEnumOwningPlayer) and GetUnitState(GetFilterUnit(),UNIT_STATE_LIFE)>.405
endmethod
static method DamageGroup takes unit damager, real radius, real x, real y, real amount returns nothing
local unit u
set bj_groupEnumOwningPlayer = GetOwningPlayer(damager)
call GroupClear(G)
call GroupEnumUnitsInRange(G, x, y, radius, Condition(function data.FiltIsEnemy))
loop
set u = FirstOfGroup(G)
exitwhen u == null
call GroupRemoveUnit(G,u)
call UnitDamageTarget(damager,u,amount,false,false,attack_type,damage_type,null)
endloop
endmethod
static method KillTrees_Child takes nothing returns nothing
call KillDestructable(GetEnumDestructable())
endmethod
static method KillTrees takes real x, real y, real radius returns nothing
set R = Rect(x - radius,y - radius,x + radius,y + radius)
call EnumDestructablesInRect(R,null,function data.KillTrees_Child)
call RemoveRect(R)
endmethod
method onDestroy takes nothing returns nothing
call SetUnitFlyHeight(.targ,GetUnitDefaultFlyHeight(.targ),0.)
call PauseUnit(.targ,false)
call SetUnitPathing(.targ,true)
call DestroyEffect(.e)
call UnitDamageTarget(.u,.targ,Damage(.lvl)*impact_damage,false,false,attack_type,damage_type,null)
call DestroyEffect(AddSpecialEffectTarget(end_sfx,.targ,"origin"))
call data.DamageGroup(.u,Area(.lvl),.xl,.yl,Damage(.lvl))
if kill_trees then
call data.KillTrees(.xl,.yl,Area(.lvl))
endif
endmethod
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == abil_id
endfunction
private function Filt takes nothing returns boolean
return GetFilterUnit()!=U and GetWidgetLife(GetFilterUnit())>.405 and not IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) and not IsUnitType(GetFilterUnit(),UNIT_TYPE_FLYING)
endfunction
private function GetSpeed takes real dist returns real
return dist/(1./TT_PERIOD)
endfunction
private function GetCountConversion takes integer count returns real
return (50./(time/TT_PERIOD))*count
endfunction
private function Movement takes nothing returns boolean
local data d = TT_GetData()
local real conv
local real height
local real speed
local real x
local real y
if d.count<=time/TT_PERIOD then
set conv = GetCountConversion(d.count)
set height = (conv-25.)*(conv-25.)
set speed = d.count*d.speed
set x = d.xt+speed*d.cos
set y = d.yt+speed*d.sin
call SetUnitX(d.targ,x)
call SetUnitY(d.targ,y)
call SetUnitFlyHeight(d.targ,625.-height,0.)
set d.count = d.count + 1
return false
else
call d.destroy()
return true
endif
endfunction
private function Actions takes nothing returns nothing
local data d = data.create()
set d.u = GetTriggerUnit()
set d.p = GetOwningPlayer(d.u)
set d.lvl = GetUnitAbilityLevel(d.u,abil_id)
call GroupClear(G)
set U = d.u
call GroupEnumUnitsInRange(G,GetUnitX(d.u),GetUnitY(d.u),Area(d.lvl),Condition(function Filt))
set d.targ = GroupPickRandomUnit(G)
if d.targ==null then
call d.destroy()
return
endif
set d.xt = GetUnitX(d.targ)
set d.yt = GetUnitY(d.targ)
set L = GetSpellTargetLoc()
set d.xl = GetLocationX(L)
set d.yl = GetLocationY(L)
set d.ang = Atan2(d.yl-d.yt,d.xl-d.xt)
set d.cos = Cos(d.ang)
set d.sin = Sin(d.ang)
set d.dist = SquareRoot((d.xt-d.xl)*(d.xt-d.xl) + (d.yt-d.yl)*(d.yt-d.yl))
set d.speed = GetSpeed(d.dist)
call PauseUnit(d.targ,true)
call SetUnitPathing(d.targ,false)
call UnitAddAbility(d.targ,fly_id)
call UnitRemoveAbility(d.targ,fly_id)
set d.e = AddSpecialEffectTarget(fly_sfx,d.targ,"origin")
call TT_Start(function Movement,d)
call RemoveLocation(L)
endfunction
//===========================================================================
public function InitTrig takes nothing returns nothing
set Trigger = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( Trigger, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( Trigger, Condition( function Conditions ) )
call TriggerAddAction( Trigger, function Actions )
endfunction
endscope
Ice Path:
JASS:
scope IcePath
//******************************************************************************************
//*
//* Ice Path - By emjlr3 - Original seen in DotA Allstars
//*
//* Creates a path of ice in front of the caster, which promptly explodes, freezing
//* units nearby.
//*
//* Requires:
//* - "TT", "PUI", "ABC" and "ABCT" triggers copied to your map, if not already there
//* - The "Ice Path" ability copied to your map
//* - The "Ice Path" unit copied to your map
//* - A vJASS Preprocessor
//*
//******************************************************************************************
globals
private constant integer abil_id = 039;A004039; // Ice Path ability rawcode
private constant integer dummy_id = 039;e001039; // Ice Path unit rawcode
private constant real space = 100. // Space between each ice block
private constant real life = .75 // Duration of each created ice block (seconds)
private constant integer counter = 2 // How many timer runs must pass before a new ice block is created, added this in since with TT you cannot specificy dynamically timer speed, and speed is not a physical value in the spell, so this allows you to create blocks at multiples of your TT_PERIOD
private constant string create_sfx = "Abilities\\Weapons\\FrostWyrmMissile\\FrostWyrmMissile.mdl" // Effect on ice blocks when created
private constant string death_sfx = "Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathMissile.mdl" // Effect during ice blocks death
private constant string pause_sfx = "Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathTargetArt.mdl" // Effect created on paused units
private location L = null
private unit Dum = null
private integer Lvl
private group G = CreateGroup()
public trigger Trigger = null // Output trigger will be IcePath_Trigger, which can be used publically
private effect array SFX // Use PUI to return the effect attached to an affected unit
private integer array LVL // Use PUI to return the level of the ability for the dummy ice block
endglobals
private function Number takes integer lvl returns integer
return 10 // Ice blocks created/lvl
endfunction
private function Area takes integer lvl returns real
return 175. // Stun area/lvl
endfunction
private function Duration takes integer lvl returns real
return .5*lvl // Stun duration/lvl
endfunction
private struct data
unit u
player p
real x
real y
real xl
real yl
real ang
real cos
real sin
integer count = 0
integer total
integer lvl
group grp
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId()==abil_id
endfunction
private function Movement takes nothing returns boolean
local data d = TT_GetData()
local real x
local real y
set d.count = d.count + 1
if d.count>(d.total*counter)+counter then
call d.destroy()
return true
endif
if ModuloInteger(d.count,counter)!=1 or d.count/counter==0 then
return false
endif
set x = d.x+((d.count/counter)*space)*d.cos
set y = d.y+((d.count/counter)*space)*d.sin
set Dum = CreateUnit(d.p,dummy_id,x,y,GetRandomReal(0.,360.))
call UnitApplyTimedLife(Dum,039;BTLF039;,life)
//call SetUnitUserData(Dum,d.lvl)
set LVL[GetUnitIndex(Dum)] = d.lvl
call DestroyEffect(AddSpecialEffect(create_sfx,x,y))
return false
endfunction
private function Actions takes nothing returns nothing
local data d = data.create()
set L = GetSpellTargetLoc()
set d.u = GetTriggerUnit()
set d.p = GetOwningPlayer(d.u)
set d.x = GetUnitX(d.u)
set d.y = GetUnitY(d.u)
set d.xl = GetLocationX(L)
set d.yl = GetLocationY(L)
set d.ang = Atan2(d.yl - d.y, d.xl - d.x)
set d.cos = Cos(d.ang)
set d.sin = Sin(d.ang)
set d.lvl = GetUnitAbilityLevel(d.u,abil_id)
set d.total = Number(d.lvl)
call TT_Start(function Movement,d)
call RemoveLocation(L)
endfunction
private function Death_Conditions takes nothing returns boolean
return GetUnitTypeId(GetTriggerUnit())==dummy_id
endfunction
private function Filt takes nothing returns boolean
return GetWidgetLife(GetFilterUnit())>.405 and not IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) and not IsUnitType(GetFilterUnit(),UNIT_TYPE_MAGIC_IMMUNE) and IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(GetTriggerUnit()))
endfunction
private function UnStun_Child takes nothing returns nothing
local integer pui = GetUnitIndex(GetEnumUnit())
call PauseUnit(GetEnumUnit(),false)
call SetUnitTimeScale(GetEnumUnit(),1.)
call DestroyEffect(SFX[pui])
set SFX[pui] = null
endfunction
private function UnStun takes nothing returns boolean
local data d = ABCT_GetData()
call ForGroup(d.grp,function UnStun_Child)
call DestroyGroup(d.grp)
call d.destroy()
return true
endfunction
private function Stun takes nothing returns nothing
local integer pui = GetUnitIndex(GetEnumUnit())
call PauseUnit(GetEnumUnit(),true)
call SetUnitTimeScale(GetEnumUnit(),0.)
if SFX[pui]==null then
set SFX[pui] = AddSpecialEffectTarget(pause_sfx,GetEnumUnit(),"origin")
endif
endfunction
private function Death_Actions takes nothing returns nothing
local data d = data.create()
set Dum = GetTriggerUnit()
//set Lvl = GetUnitUserData(Dum)
set Lvl = LVL[GetUnitIndex(Dum)]
set d.grp = CreateGroup()
call GroupEnumUnitsInRange(d.grp,GetUnitX(Dum),GetUnitY(Dum),Area(Lvl),Condition(function Filt))
call ForGroup(d.grp,function Stun)
call ABCT_Start(function UnStun,d,Duration(Lvl))
call DestroyEffect(AddSpecialEffect(death_sfx,GetUnitX(Dum),GetUnitY(Dum)))
endfunction
//===========================================================================
public function InitTrig takes nothing returns nothing
local trigger trig = CreateTrigger()
set Trigger = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(Trigger , EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddAction(Trigger, function Actions)
call TriggerAddCondition(Trigger , Condition(function Conditions))
call TriggerRegisterAnyUnitEventBJ(trig , EVENT_PLAYER_UNIT_DEATH)
call TriggerAddAction(trig , function Death_Actions)
call TriggerAddCondition(trig , Condition(function Death_Conditions))
endfunction
endscope
Wild Axes
JASS:
scope WildAxes
//******************************************************************************************
//*
//* Wild Axes - By emjlr3, Original seen in DotA Allstars
//*
//* Hurl two axes outward, which then intersect and return. Each axe can
//* only damage a unit once and destroys trees in its wake.
//*
//* Requires:
//* - "TT" trigger copied to your map, if not already there
//* - The "Wild Axes" ability copied to your map
//* - The "Wild Axes" unit copied to your map
//* - A vJASS Preprocessor
//*
//******************************************************************************************
globals
// Config. Globals:
private constant integer abil_id = 039;A003039; // Wild Axes ability rawcode
private constant integer dummy_id = 039;e000039; // Wild Axes unit rawcode
private constant real speed = .028 // Speed for axes, this is an arbitrary value, increasing it increases the axes speed, while decreasing it decreases their speed
private constant real width = 375. // Width for bezier curve, larger values give a wider arc, and vice versa
private constant real area = 150. // Area to damage units around axes and destroy trees
private constant string sfx = "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl" // Effect created on hit units
private constant attacktype attack_type = ATTACK_TYPE_NORMAL // Attack type for damage
private constant damagetype damage_type = DAMAGE_TYPE_NORMAL // Damage type for damage
// Needed Globals:
public trigger Trigger = null // Output trigger will be WildAxes_Trigger, which can be used publically
private group G = CreateGroup()
private group TempG = null
private player P = null
private location L = null
private rect R = null
endglobals
// Config. Functions:
private function Damage takes integer lvl returns real
return 50.+(lvl*30.) // Damage/lvl
endfunction
private struct data
unit u
unit axe
player p
group grp
real x
real y
real xl
real yl
real a = 1.
real outx
real outy
real ang
integer lvl
boolean first = true
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId()==abil_id
endfunction
private function Filt takes nothing returns boolean
return not IsUnitInGroup(GetFilterUnit(),TempG) and GetWidgetLife(GetFilterUnit())>.405 and not IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) and IsUnitEnemy(GetFilterUnit(),P)
endfunction
private function Kill_Trees takes nothing returns nothing
call KillDestructable(GetEnumDestructable())
endfunction
private function Effects takes unit u, real x, real y, group grp, integer lvl returns nothing
local unit dum
set R = Rect(x-150.,y-150.,x+150.,y+150.)
call EnumDestructablesInRect(R,null,function Kill_Trees)
call RemoveRect(R)
call GroupClear(G)
set P = GetOwningPlayer(u)
set TempG = grp
call GroupEnumUnitsInRange(G,x,y,area,Condition(function Filt))
loop
set dum = FirstOfGroup(G)
exitwhen dum==null
call GroupRemoveUnit(G,dum)
call UnitDamageTarget(u,dum,Damage(lvl),false,false,attack_type,damage_type,null)
call DestroyEffect(AddSpecialEffectTarget(sfx,dum,"chest"))
call GroupAddUnit(grp,dum)
endloop
endfunction
private function Movement takes nothing returns boolean
local data d = TT_GetData()
local real b = 1.-d.a
call SetUnitX(d.axe,d.x*d.a*d.a+d.outx*2*d.a*b+d.xl*b*b)
call SetUnitY(d.axe,d.y*d.a*d.a+d.outy*2*d.a*b+d.yl*b*b)
call Effects(d.u,GetUnitX(d.axe),GetUnitY(d.axe),d.grp,d.lvl)
if d.first then
set d.a = d.a-speed
else
set d.a = d.a+speed
set d.x = GetUnitX(d.u)
set d.y = GetUnitY(d.u)
endif
if d.a<0. and d.first then
set d.first = false
set d.outx = d.x+width*Cos(Atan2(d.yl-d.y,d.xl-d.x)+d.ang)
set d.outy = d.y+width*Sin(Atan2(d.yl-d.y,d.xl-d.x)+d.ang)
endif
if d.a>1. and d.first==false then
call DestroyGroup(d.grp)
call RemoveUnit(d.axe)
call d.destroy()
return true
endif
return false
endfunction
private function Actions takes nothing returns nothing
local data d1 = data.create()
local data d2 = data.create()
set d1.u = GetTriggerUnit()
set d2.u = d1.u
set d1.x = GetUnitX(d1.u)
set d2.x = d1.x
set d1.y = GetUnitY(d1.u)
set d2.y = d1.y
set d1.p = GetOwningPlayer(d1.u)
set d2.p = d1.p
set d1.axe = CreateUnit(d1.p,dummy_id,d1.x,d1.y,0.)
set d2.axe = CreateUnit(d1.p,dummy_id,d1.x,d1.y,0.)
set d1.grp = CreateGroup()
set d2.grp = CreateGroup()
set d1.lvl = GetUnitAbilityLevel(d1.u,abil_id)
set d2.lvl = d1.lvl
set L = GetSpellTargetLoc()
set d1.xl = GetLocationX(L)
set d2.xl = d1.xl
set d1.yl = GetLocationY(L)
set d2.yl = d1.yl
set d1.outx = d1.x+width*Cos(Atan2(d1.yl-d1.y,d1.xl-d1.x)+45.)
set d1.outy = d1.y+width*Sin(Atan2(d1.yl-d1.y,d1.xl-d1.x)+45.)
set d2.outx = d1.x+width*Cos(Atan2(d1.yl-d1.y,d1.xl-d1.x)-45.)
set d2.outy = d1.y+width*Sin(Atan2(d1.yl-d1.y,d1.xl-d1.x)-45.)
set d1.ang = -45.
set d2.ang = 45.
call TT_Start(function Movement,d1)
call TT_Start(function Movement,d2)
call RemoveLocation(L)
endfunction
//===========================================================================
public function InitTrig takes nothing returns nothing
set Trigger = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( Trigger, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( Trigger, Condition( function Conditions ) )
call TriggerAddAction( Trigger, function Actions )
endfunction
endscope
Black Hole
JASS:
scope BlackHole
//******************************************************************************************
//*
//* Blackhole - By emjlr3, Original seen in DotA Allstars
//*
//* Summon a black hole from the darkest abyss, which sucks enemy units into
//* its center, dealing damage over time.
//*
//* Requires:
//* - "TT" trigger copied to your map, if not already there
//* - The "Black Hole" ability copied to your map
//* - The "Black Hole (Dummy)" ability copied to your map
//* - The "Black Hole" buff copied to your map, set as the previous abilities buff
//* - The "Black Hole" unit copied to your map, with the "Black Hole (Dummy)" ability added to it
//* - A vJASS Preprocessor
//*
//******************************************************************************************
globals
// Config. Globals:
private constant integer abil_id = 039;A002039; // Black Hole ability rawcode
private constant integer dummy_id = 039;u000039; // Black Hole unit rawcode
private constant real pull = 1.75 // Distance pulled/interval
private constant boolean fight = false // Whether units can fight against the pull
private constant string sfx = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl" // Effect created on pulled units
// Needed Globals:
public trigger Trigger = null // Output trigger will be BlackHole_Trigger, which can be used publically
private group G = CreateGroup()
private player P = null
private real X
private real Y
endglobals
// Config. Functions:
private function Range takes integer lvl returns real
return 400. // Area for pull/lvl
endfunction
// Damage is found on the Black Hole (Dummy) ability
private struct data
unit hole
unit u
player p
integer lvl
real x
real y
endstruct
private function Conditions takes nothing returns boolean
return GetUnitTypeId(GetSummonedUnit())==dummy_id
endfunction
private function Filt takes nothing returns boolean
return GetWidgetLife(GetFilterUnit())>.405 and not IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) and IsUnitEnemy(GetFilterUnit(),P)
endfunction
private function Effects takes nothing returns nothing
local real x
local real y
local real ang
set bj_ghoul[25] = GetEnumUnit()
set x = GetUnitX(bj_ghoul[25])
set y = GetUnitY(bj_ghoul[25])
set ang = Atan2(Y-y,X-x)
if fight then
call SetUnitX(bj_ghoul[25],x+pull*Cos(ang))
call SetUnitY(bj_ghoul[25],y+pull*Sin(ang))
else
call SetUnitPosition(bj_ghoul[25],x+pull*Cos(ang),y+pull*Sin(ang))
endif
call DestroyEffect(AddSpecialEffectTarget(sfx,bj_ghoul[25],"origin"))
endfunction
private function Movement takes nothing returns boolean
local data d = TT_GetData()
if GetWidgetLife(d.hole)<.405 then
call d.destroy()
return true
endif
call GroupClear(G)
set P = d.p
set X = d.x
set Y = d.y
call GroupEnumUnitsInRange(G,d.x,d.y,Range(d.lvl),Condition(function Filt))
call ForGroup(G,function Effects)
return false
endfunction
private function Actions takes nothing returns nothing
local data d = data.create()
set d.hole = GetSummonedUnit()
set d.x = GetUnitX(d.hole)
set d.y = GetUnitY(d.hole)
set d.u = GetSummoningUnit()
set d.p = GetOwningPlayer(d.u)
set d.lvl = GetUnitAbilityLevel(d.u,abil_id)
call TT_Start(function Movement,d)
endfunction
//===========================================================================
public function InitTrig takes nothing returns nothing
set Trigger = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( Trigger, EVENT_PLAYER_UNIT_SUMMON )
call TriggerAddCondition( Trigger, Condition( function Conditions ) )
call TriggerAddAction( Trigger, function Actions )
endfunction
endscope
Enjoy, and please comment
Version 3