Moderator
M
Moderator
17:43, 24th Sep 2009
Hanky:
You need to update the map since it's not working with 1.24b right now.
Hanky:
You need to update the map since it's not working with 1.24b right now.
Tentacle Attack![]() | The target gets impaled by a tentacle - multiple other tentacles spawn and attack the victim until the spell is over. If the victim dies, the tentacles attack random units nearby Damage: 3 per hit Range: 800 Type: Active Cooldown: 8s |
//==Tentacle Attack==
//2oo9 by Squiggy
//Spell needs jngp and TimerUtils
//Credits go to HINDYhat for teaching me jass
//The next spell will include methods, yes yes D:
scope TentacleAttack initializer Init
globals
private constant integer SPELLID = 'A000' //This is the spell's id
private constant string EFFPATH = "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl"
private constant string EFFPATH2 = "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl"
private constant integer DUMMYID = 'n000' //Here, we aet the dummy WITHOUT the attack which impales the enemy
private constant integer DUMMYID2 = 'n001' //Now we set the dummy WITH attack which rapes the target
private constant integer BUFFID = 'B000' //And the integer for the buff is set here
private constant real DURATION = 7 //Here goes the duration of the spell
private constant real FLYHEIGHT = 350 //Flying height to which the target is changed
private constant real RANDOM_MIN_X = 0 //Those are the random values for the tentacles' placement
private constant real RANDOM_MAX_X = 400
private constant real RANDOM_MIN_Y = 0
private constant real RANDOM_MAX_Y = 400
private constant real RANDOM_MIN_ANG = 0
private constant real RANDOM_MAX_ANG = 360
private constant real FALLRATE = 4000 //And here's the speed at which the target falls down
endglobals
private struct tentacle //We define all values which we need for the second part of the spell
unit caster
unit target
integer i
real tx
real ty
integer index
player p
endstruct
private function Conditions takes nothing returns boolean //First, we check which ability is being cast
return GetSpellAbilityId() == SPELLID
endfunction
private function Conditions2 takes nothing returns boolean
return GetUnitTypeId(GetTriggerUnit()) == DUMMYID //This is the condition for the second trigger - it checks the type of the dying unit
endfunction
private function grpenu takes nothing returns boolean //Group filter to your left checking for the buff 'rape'
return GetUnitAbilityLevel(GetFilterUnit(), BUFFID)>0
endfunction
private function Tentacles takes nothing returns nothing //Here we deal with everything aftert the first tentacle is created
local real rndx
local real rndy
local real rnda
local unit u2
local tentacle tc = tentacle(GetTimerData(GetExpiredTimer())) //we get the data
set rndx = GetRandomReal(RANDOM_MIN_X, RANDOM_MAX_X) //Now we create the dummy
set rndy = GetRandomReal(RANDOM_MIN_Y, RANDOM_MAX_Y)
set rnda = GetRandomReal(RANDOM_MIN_ANG, RANDOM_MAX_ANG)
set u2 = CreateUnit(tc.p, DUMMYID2, (tc.tx + rndx*Cos((rnda)*bj_DEGTORAD)), tc.ty + rndy*Sin((rnda)*bj_DEGTORAD), rnda)
call IssueTargetOrder(u2, "attack", tc.target) //We order it to attack the target
call UnitApplyTimedLife(u2, 'BTLF', DURATION)
call DestroyEffect(AddSpecialEffect(EFFPATH2, GetUnitX(u2), GetUnitY(u2))) //And add an effect
set tc.index = tc.index+1 //To limit the number of dummies, we set the maximum to lvl*3
if tc.i == tc.index then
call ReleaseTimer(GetExpiredTimer())
set u2 = null
endif
endfunction
private function status takes nothing returns nothing
local tentacle tc = tentacle(GetTimerData(GetExpiredTimer()))
if GetUnitState(tc.target, UNIT_STATE_LIFE) < 4 then
call SetUnitUserData(tc.target, GetUnitUserData(tc.target)-1) //Now as the instance is over, we substract 1 of the custom value
if GetUnitUserData(tc.target) == 0 then //And if there are no instances running (cv == 0),
call SetUnitFlyHeight(tc.target, 0, FALLRATE/2) //we bring it down
call tc.destroy()
endif
call ReleaseTimer(GetExpiredTimer())
endif
endfunction
private function Actions takes nothing returns nothing //Here's the first part which creates the impaling tentacle
local unit caster = GetTriggerUnit()
local unit u
local real x = GetUnitX(caster)
local real y = GetUnitY(caster)
local timer t = NewTimer()
local timer t2 = NewTimer()
local tentacle tc = tentacle.create()
call SetTimerData(t, integer(tc))
call SetTimerData(t2, integer(tc))
set tc.target = GetSpellTargetUnit()
set tc.tx = GetUnitX(tc.target)
set tc.ty = GetUnitY(tc.target)
set tc.i = GetUnitAbilityLevel(caster, SPELLID)*3
set tc.index = 0
set tc.p = GetOwningPlayer(caster)
set u = CreateUnit(tc.p, DUMMYID, tc.tx, tc.ty, 90)
call UnitApplyTimedLife(u, 'BTLF', DURATION+1.2)
call UnitAddAbility(tc.target, 'Amrf') //We add and remove 'crow form' to the target
call UnitRemoveAbility(tc.target, 'Amrf')
call SetUnitFlyHeight(tc.target, FLYHEIGHT, FLYHEIGHT*3) //And make it raise
call DestroyEffect(AddSpecialEffectTarget(EFFPATH, tc.target, "origin"))
call TimerStart(t, 0.2, true, function Tentacles) //We start both timers to create the tentacles
call TimerStart(t2, 0.03, true, function status) //And to check for the target's health
call SetUnitAnimation(u, "birth") //Now we make the tentacle appear out of the ground and set it's animation speed to 0
call SetUnitFlyHeight(u, 0, FLYHEIGHT*3)
call SetUnitTimeScale(u, 0)
call SetUnitUserData(tc.target, GetUnitUserData(tc.target)+1) //Adding a custom value will prevent the target from falling dow too soon
set caster = null
set u = null
endfunction
private function Death takes nothing returns nothing //The third and last part is to bring the target back to the ground when the first tentacle dies
local unit u = GetTriggerUnit()
local unit gru
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local group g = CreateGroup()
call SetUnitTimeScale(u, 1)
call GroupEnumUnitsInRange(g, x, y, 100, Filter(function grpenu)) //We pick the nearby target which still has the buff 'rape'
loop
set gru = FirstOfGroup(g)
exitwhen gru == null
call SetUnitUserData(gru, GetUnitUserData(gru)-1) //Now as the instance is over, we substract 1 of the custom value
if GetUnitUserData(gru) == 0 then //And if there are no instances running (cv == 0),
call SetUnitFlyHeight(gru, 0, FALLRATE) //we bring it down
endif
call GroupRemoveUnit(g, gru)
endloop
call DestroyGroup(g)
set u = null
endfunction
private function AntiLeak takes nothing returns boolean
return true
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
local trigger t2 = CreateTrigger()
local filterfunc f = Filter(function AntiLeak)
local integer i = 0
loop
exitwhen i >= 16
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, f)
call TriggerRegisterPlayerUnitEvent(t2, Player(i), EVENT_PLAYER_UNIT_DEATH, f)
set i = i + 1
endloop
call TriggerAddCondition(t, Condition(function Conditions))
call TriggerAddCondition(t2, Condition(function Conditions2))
call TriggerAddAction(t, function Actions)
call TriggerAddAction(t2, function Death)
call DestroyFilter(f)
set f = null
endfunction
endscope