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 = "Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.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 real DURATION = 7 //Here goes the duration of the spell
private constant real FLYHEIGHT = 400 //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 = 500
private constant real RANDOM_MIN_Y = 0
private constant real RANDOM_MAX_Y = 500
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 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(), 'B000')>0
endfunction
private function Tentacles takes nothing returns nothing //Here we deal with everything aftert the first tentacle is created
local real x
local real y
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
// call SetUnitFlyHeight(u2, 0, 400)
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())
call tc.destroy()
endif
set u2 = null
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 tentacle tc = tentacle.create()
call SetTimerData(t, 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, 700) //And make it raise
call DestroyEffect(AddSpecialEffectTarget(EFFPATH, tc.target, "origin"))
call TimerStart(t, 0.2, true, function Tentacles)
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, 800)
call SetUnitTimeScale(u, 0)
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 SetUnitFlyHeight(gru, 0, FALLRATE) //And bring it down
call GroupRemoveUnit(g, gru)
endloop
call DestroyGroup(g)
set u = null
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
local trigger t2 = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(t, Condition(function Conditions))
call TriggerAddCondition(t2, Condition(function Conditions2))
call TriggerAddAction(t, function Actions)
call TriggerAddAction(t2, function Death)
endfunction
endscope