DESCRIPTION:
Creates 6 fireballs escort/pet that rotates around and follows the caster, nearby enemy units shall be hit by focused fire from the fireballs. All fireballs will return to follow the caster when enemy dies or when the caster is far away.
Spell lasts 60 seconds or when the caster dies.
|cffffcc00Level 1|r - Each hit damages 5.
|cffffcc00Level 2|r - Each hit damages 7.
|cffffcc00Level 3|r - Each hit damages 9.
|cffffcc00Level 4|r - Each hit damages 11.
|cffffcc00Level 5|r - Each hit damages 13.
Code
Jass:
/*
=====Spell Name: Fire Escort v1.0
=====Created by: Mckill2009
REQUIRES:
- JassNewGenPack by Vexorian
REQUIRED LIBRARIES and CREDITS:
- CTL by Nesthaurus (http://www.hiveworkshop.com/forums/jass-resources-412/snippet-constant-timer-loop-32-a-201381/)
- Table by Bribe (http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/)
HOW TO USE: Step by Step
- Copy ALL the custom units and abilities from the object editor.
- Copy ALL that is inside the folder 'FireEscort' to your trigger editor.
- If you want to make your own units and abilities, make sure you change the rawID indicated in the code.
- If you change the DUMMY_SPELL_ID rawID, make sure it will be casted by ORDER_ID.
- To view rawID, press CTRL+D in the object editor.
- Save and Done!
YOU MAY:
- Change the model of the fireballs.
- Change the firebolt into slow, nova, purge but you MUST change also the ORDER_ID for it.
- Change the confugurations below.
*/library FireEscort uses CTL, Table
globalsprivateconstantinteger SPELL_ID ='A002'//Howl of Terror(rawID)privateconstantinteger DUMMY_SPELL_ID ='A000'//Firebolt(rawID)privateconstantinteger ORDER_ID =852231//Fireboltprivateconstantinteger DUMMY_ID ='h000'//rawIDprivateconstantinteger BOMB_ID ='h001'//rawIDprivateconstantreal INTERVAL =0.03125endglobalsnative UnitAlive takesunit u returnsboolean//! textmacro SE takes UNTset x =GetUnitX($UNT$)set y =GetUnitY($UNT$)set angle =Atan2(y-yDum, x-xDum)set distance = getDistance(x,y,xDum,yDum)loopexitwhen index==maxbombs
set bomb = TBA[index].unit[dumID]set gap = TBA[2000+index].real[dumID]callSetUnitX(bomb, xDum+.offset*Cos(gap))callSetUnitY(bomb, yDum+.offset*Sin(gap))callSetUnitFlyHeight(bomb,.flyheight,0)set TBA[2000+index].real[dumID]= gap+gapdist
set bomb =nullset index = index +1endloopif distance > distancetoreach thencallSetUnitX(.dummy, xDum+followspeed*Cos(angle))callSetUnitY(.dummy, yDum+followspeed*Sin(angle))endif//! endtextmacroprivatefunction LoadFirst takesnothingreturnsnothinglocalunit u =CreateUnit(Player(15), DUMMY_ID,0,0,0)callUnitAddAbility(u, DUMMY_SPELL_ID)callKillUnit(u)set u =nullendfunctionprivatestruct FE extendsarrayunit caster
unit target
unit dummy
real duration
real offset
real search
real flyheight
player owner
static TableArray TBA
//Configurables:staticinteger maxbombs =6staticreal rotationspeed =1staticreal followspeed =7staticreal gapdist =1//recommended for 6 bombsstaticreal raisespeed =2staticreal offsetspeed =2staticreal maxoffset =300staticreal aoe =900staticreal searchinterval =2staticreal maxheight =400//this should not be greater than your CAST RANGEstaticreal maxduration =60//sets the life of the dummy captainstaticreal distancetofollow =640000//SquareRoot is 800staticreal distancetoreach =3600//Squareroot is 60//==========method getDistance takesreal x1,real y1,real x2,real y2 returnsrealreturn(x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)endmethodmethod filterThem takesunit caster,unit target returnsbooleanreturn UnitAlive(target)andIsUnitEnemy(caster,GetOwningPlayer(target))andnot(IsUnitType(target,UNIT_TYPE_STRUCTURE)and/*
*/IsUnitType(target,UNIT_TYPE_MECHANICAL)andIsUnitType(target,UNIT_TYPE_MAGIC_IMMUNE))endmethodimplement CTL
localunit bomb
localunit first
localreal x
localreal y
localreal xDum
localreal yDum
localreal gap
localreal angle
localreal distance
localreal distance2
localinteger index
localinteger dumID
implement CTLExpire
set index =0set dumID =GetHandleId(.dummy)if UnitAlive(.caster)and.duration>0thenset.duration=.duration- INTERVAL
set xDum =GetUnitX(.dummy)set yDum =GetUnitY(.dummy)if.offset< maxoffset thenset.offset=.offset+ offsetspeed
endifif.flyheight< maxheight thenset.flyheight=.flyheight+ raisespeed
endifif.target==nullthen//! runtextmacro SE(".caster")set.search= search + INTERVAL
if.search> searchinterval and distance <4000thencallGroupEnumUnitsInRange(bj_lastCreatedGroup,xDum,yDum,aoe,null)loopset first =FirstOfGroup(bj_lastCreatedGroup)exitwhen first==nullif filterThem(.caster, first)thenset.target= first
endifcallGroupRemoveUnit(bj_lastCreatedGroup, first)endloopset searchinterval =0endifelseif UnitAlive(.target)then//! runtextmacro SE(".target")if.flyheight>= maxheight thenset distance2 = getDistance(GetUnitX(.caster),GetUnitY(.caster),xDum,yDum)if distance2 < distancetofollow thenset index =0loopexitwhen index==maxbombs
callIssueTargetOrderById(TBA[index].unit[dumID],ORDER_ID,.target)set index = index +1endloopelseset.target=nullendifendifelseset.target=nullendifendifelse//End the SpellcallKillUnit(.dummy)loopexitwhen index==maxbombs
callKillUnit(TBA[index].unit[dumID])set index = index +1endloopset.caster=nullset.target=nullset.dummy=nullcall.destroy()endifimplement CTLNull
set bomb =nullimplement CTLEnd
staticmethod setup takesunit u,player p returnsnothinglocalthistypethis= create()localinteger lvl =GetUnitAbilityLevel(u, SPELL_ID)localinteger index =0localreal g =0localinteger dumID
localunit bomb
localreal gap
set.caster= u
set.target=nullset.duration= maxduration
set.owner= p
set.dummy=CreateUnit(p,DUMMY_ID,GetUnitX(u),GetUnitY(u),0)set.offset=0set.flyheight=0set.search=0set dumID =GetHandleId(.dummy)loopexitwhen index==maxbombs
set bomb =CreateUnit(p,BOMB_ID,0,0,0)set gap = g
set TBA[index].unit[dumID]= bomb
set TBA[2000+index].real[dumID]= gap
callSetUnitFlyHeight(bomb,0,0)callUnitAddAbility(bomb, DUMMY_SPELL_ID)callSetUnitAbilityLevel(bomb,DUMMY_SPELL_ID, lvl)set g = g + gapdist
set index = index +1endloopendmethodstaticmethod cast takesnothingreturnsbooleanifGetSpellAbilityId()==SPELL_ID thencall setup(GetTriggerUnit(),GetTriggerPlayer())endifreturnfalseendmethodstaticmethod onInit takesnothingreturnsnothinglocaltrigger t =CreateTrigger()callTriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)callTriggerAddCondition(t,functionthistype.cast)call LoadFirst()set t =nullset TBA = TableArray[5000]endmethodendstructendlibrary
CREDITS:
- Nesthaurus (CTL)
- Bribe (Table)
Rating - 0.00 (0 votes)
(Hover and click)
Moderator Comments
Recommended
21st May 2012
Bribe: I recommend that you prefix the "SE" textmacro for the sake of relevance.
Just like Wisp's Spirits,is it??
Hey,do you want to join me to make Wisp's(dota)Spell Pack???
i know how to make Relocate and Tether...i made them Months ago(its mui i think cause it doesnt have any waits)
would you like too?
for that ill give it 4/5 because its like you got it from other Spells
After 10 days actually ^^
The Fireballs move quite "un-smoothy"
And i think i would prefer to use the Locust ability if it doesn't have some more advances :D Like:
The caster has a sub-ability to call the balls to target a unit
Or
Switching them between defensive and offensive. In defensive, they heal allies. Offensive, they attack
etc...
Just my opinion to improve the spell. Hope you welcome it :D
PM me when the next update comes, cause i don't want to vote for a bad result :P
=======Edit=======
Oh... and i think i found a bug. When the balls goes out the borders of the map (playable area), my warcraft III crashes. (it happens twice so... check out for it :D) (but maybe it because my comp is sucks :( )
__________________
Wanna see DotA heroes on paper? ===> Click to visit <===
Nothing is IMPOSSIBLE but Nothing is EASY
Its not really a bug coz any unit that goes beyond map boundaries will cause a map to crash, its normal, but you may use BoundSentinel library to fix the crash...
I am open and considerate enough to any suggestions and thank you for that :)...