Well since alot of people asked for this and it got lost after the crash i decided to post it again. Look down for instructions on how to implement this.
Make a new trigger called Meathook, go to Edit -> Convert to Custom Text and press OK. Delete everything the trigger editor created for you and replace it with the jass code above.
Now you need to create a dummy unit that will be used to create the hook chain.
Base it of any unit (for example a footman) and change these fields:
Abilties - Normal
Delete all, add Locust.
Art - Model File
Change to Warden, Maiev under Units - Missiles.
Art - Scaling Value
Experiment a bit. I used 1.50.
Art - Shadow Image (Unit) = None.
Art - Special
Remove everything here.
Combat - Attacks Enabled = None.
Movement - Height
Also needs experimenting. I used 50.00.
Movement - Type = Fly.
Pathing - Collision Size
Set to 0 (although you probably don't need this because you have locust).
Stats - Can Flee = False
Stats - Food Cost = 0
Techtree - Upgrades Used
Remove everything.
All done! Now press Ctrl+D. Your chain unit's name should change.
For example Footman becomes h000:hfoo (Footman).
Write down the bold text (h000 in this case although it could be different for you), press Ctrl+D again to restore the old name and switch to the code in the trigger editor.
In the first lines you will see
If the text I marked bold wasn't h000 for you then change return 'h000' to something else.
Now you need to create the actual ability.
Base it of Channel (Neutral Hostile -> Heroes -> Channel) and change these fields:
Art - Animation Names
Remove all and add attack if you want it dota like. If you don't then put whatever you want.
Art - Caster, Art - Caster Attachment Point 1, Art - Effect, Art - Target, Art - Target Attachment Point 1
Remove everything from these.
Stats - Levels
Anything you want.
If the above is larger than 1 then you need to set these fields for every level:
Data - Art Duration = 0
Data - Disable Other Abilities = False
Data - Follow Through Time = 1.50, you can change this if you think its too long
Data - Options = check Visible and Physical Spell
Data - Target Type = Unit or Point Target
Stats - Cast Range = whatever you want
Again press Ctrl+D. You will see something like A000:ANcl (Meat Hook). Once again remember the bold part if it isn't A000 and press Ctrl+D again. Now in the trigger code find
and change return GetSpellAbilityId() == 'A000' if the bold part wasn't A000 for you.
Now you need to implement kattana's handle vars. Go here and copy the code to your map's header (its the first line in the left part of the trigger editor, has the same name as your map).
Now go to the variable editor (Ctrl+B) and add a new variable called GameCache of type Game Cache.
Find this function in the handle vars code:
and replace return InitGameCache("jasslocalvars.w3v") with return udg_GameCache.
Make a new trigger and add map initialization event. now add a custom script action and input this code:
And it's finally over! Now just add the spell to some unit and enjoy
Credit Daelin if you use this!!
The only thing I did here is the implementation guide. Hope you had no trouble understanding it.
Code:
//RAWCODE FUNCTIONS
constant function HookUnit takes nothing returns integer
return 'h000'
endfunction
constant function HookDistance_Limit takes nothing returns real
return 1000.00 //maximum range of hook
endfunction
constant function HookRange takes nothing returns real
return 75.00 //distance between chain and hooked unit
endfunction
constant function HookDistances takes nothing returns real
return 25.00 //distance between two chains of the hook
endfunction
//********************
//CONDITION FUNCTIONS
function HookFilter takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetHandleUnit(GetExpiredTimer(), "cast"))) and GetWidgetLife(GetFilterUnit())>0.00 and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)==false
endfunction
function Trig_Meathook_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A000'
endfunction
//*****************
//ACTION FUNCTIONS
function HookGrab takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit cast = GetHandleUnit(t, "cast")
local unit hook = GetHandleUnit(t, "hook")
local real dist = GetHandleReal(t, "dist")
local unit targ = GetHandleUnit(t, "targ")
local real angle = GetHandleReal(t, "angle")
local real PolarX = GetUnitX(cast) + dist * Cos(angle)
local real PolarY = GetUnitY(cast) + dist * Sin(angle)
call SetHandleHandle(t, "hook", GetHandleUnit(hook, "prev"))
call FlushHandleLocals(hook)
call RemoveUnit(hook)
set hook = null
call SetUnitPosition(targ, PolarX, PolarY)
if dist<=10.00 then
call FlushHandleLocals(t)
call PauseTimer(t)
call DestroyTimer(t)
else
call SetHandleReal(t, "dist", dist-HookDistances())
endif
set targ = null
set t = null
set cast = null
set hook = null
endfunction
function MeatHookCreate takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit prev = GetHandleUnit(t, "prev")
local unit cast = GetHandleUnit(t, "cast")
local real angle = GetHandleReal(t, "angle")
local real dist = GetHandleReal(t, "dist")
local real PolarX = GetUnitX(cast) + dist * Cos(angle)
local real PolarY = GetUnitY(cast) + dist * Sin(angle)
local unit hook = CreateUnit(GetOwningPlayer(cast), HookUnit(), PolarX, PolarY, bj_RADTODEG*angle)
local group aux = CreateGroup()
local timer trix
local real count
local unit targ = null
call SetHandleHandle(hook, "prev", prev)
call GroupEnumUnitsInRange(aux, PolarX, PolarY, HookRange(), Condition(function HookFilter))
set count = CountUnitsInGroup(aux)
if count>0 then
set targ = GroupPickRandomUnit(aux)
endif
if count>0 or dist>=HookDistance_Limit() then
call PauseTimer(t)
call DestroyTimer(t)
call FlushHandleLocals(t)
set trix = CreateTimer()
call SetHandleHandle(trix, "cast", cast)
call SetHandleHandle(trix, "targ", targ)
call SetHandleReal(trix, "dist", dist)
call SetHandleHandle(trix, "hook", hook)
call SetHandleReal(trix, "angle", angle)
call TimerStart(trix, 0.035, true, function HookGrab)
set trix = null
else
call SetHandleReal(t, "dist", dist+HookDistances())
call SetHandleHandle(t, "prev", hook)
endif
call DestroyGroup(aux)
set hook = null
set prev = null
set targ = null
set aux = null
set t = null
set cast = null
endfunction
function Trig_Meathook_Actions takes nothing returns nothing
local unit cast = GetTriggerUnit()
local real X = GetLocationX(GetSpellTargetLoc())
local real Y = GetLocationY(GetSpellTargetLoc())
local timer t = CreateTimer()
local real angle = Atan2(Y-GetUnitY(cast),X-GetUnitX(cast))
call SetHandleHandle(t, "cast", cast)
call SetHandleHandle(t, "prev", null)
call SetHandleReal(t, "angle", angle)
call SetHandleReal(t, "dist", 0.25)
call TimerStart(t, 0.035, true, function MeatHookCreate)
call RemoveLocation(GetSpellTargetLoc())
set cast = null
set t = null
endfunction
//===========================================================================
function InitTrig_Meathook takes nothing returns nothing
set gg_trg_Meathook = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Meathook, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Meathook, Condition( function Trig_Meathook_Conditions ) )
call TriggerAddAction( gg_trg_Meathook, function Trig_Meathook_Actions )
endfunction
How to implement:
Make a new trigger called Meathook, go to Edit -> Convert to Custom Text and press OK. Delete everything the trigger editor created for you and replace it with the jass code above.
Now you need to create a dummy unit that will be used to create the hook chain.
Base it of any unit (for example a footman) and change these fields:
Abilties - Normal
Delete all, add Locust.
Art - Model File
Change to Warden, Maiev under Units - Missiles.
Art - Scaling Value
Experiment a bit. I used 1.50.
Art - Shadow Image (Unit) = None.
Art - Special
Remove everything here.
Combat - Attacks Enabled = None.
Movement - Height
Also needs experimenting. I used 50.00.
Movement - Type = Fly.
Pathing - Collision Size
Set to 0 (although you probably don't need this because you have locust).
Stats - Can Flee = False
Stats - Food Cost = 0
Techtree - Upgrades Used
Remove everything.
All done! Now press Ctrl+D. Your chain unit's name should change.
For example Footman becomes h000:hfoo (Footman).
Write down the bold text (h000 in this case although it could be different for you), press Ctrl+D again to restore the old name and switch to the code in the trigger editor.
In the first lines you will see
Code:
constant function HookUnit takes nothing returns integer
return 'h000'
endfunction
Now you need to create the actual ability.
Base it of Channel (Neutral Hostile -> Heroes -> Channel) and change these fields:
Art - Animation Names
Remove all and add attack if you want it dota like. If you don't then put whatever you want.
Art - Caster, Art - Caster Attachment Point 1, Art - Effect, Art - Target, Art - Target Attachment Point 1
Remove everything from these.
Stats - Levels
Anything you want.
If the above is larger than 1 then you need to set these fields for every level:
Data - Art Duration = 0
Data - Disable Other Abilities = False
Data - Follow Through Time = 1.50, you can change this if you think its too long
Data - Options = check Visible and Physical Spell
Data - Target Type = Unit or Point Target
Stats - Cast Range = whatever you want
Again press Ctrl+D. You will see something like A000:ANcl (Meat Hook). Once again remember the bold part if it isn't A000 and press Ctrl+D again. Now in the trigger code find
Code:
function Trig_Meathook_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A000'
endfunction
Now you need to implement kattana's handle vars. Go here and copy the code to your map's header (its the first line in the left part of the trigger editor, has the same name as your map).
Now go to the variable editor (Ctrl+B) and add a new variable called GameCache of type Game Cache.
Find this function in the handle vars code:
Code:
function LocalVars takes nothing returns gamecache
// Replace InitGameCache("jasslocalvars.w3v") with a global variable!!
return InitGameCache("jasslocalvars.w3v")
endfunction
Make a new trigger and add map initialization event. now add a custom script action and input this code:
Code:
set udg_GameCache = InitGameCache("jasslocalvars.w3v")
And it's finally over! Now just add the spell to some unit and enjoy
Credit Daelin if you use this!!
The only thing I did here is the implementation guide. Hope you had no trouble understanding it.