- Joined
- Jan 22, 2010
- Messages
- 2,583
Good luck with all of your spells!
Mine's leaky. :S
Mine's leaky. :S
You need to know how to make a struct stack to make it properly
http://www.wc3c.net/showthread.php?t=91491
Here's my WIP.
Greatings to all,
Finally I can summite my first decent work here in the Hive
and the actions run when you cast any spell. Maybe the condition function should be action function and add a proper condition function.
scope HoneyShower initializer InitTrig_Initialize
globals
private constant integer SpellID = 'A000'
private constant integer DummyID = 'n000'
private constant string DummyAttach = "chest"
private constant string BuffAttach = "origin"
private constant real Duration = 5.
private constant real DurationIncr = 2.5
private constant integer BeeSum = 3
private constant integer BeeSumIncr = 1
private constant real BeeAtkInterval = 1.
private constant real BeeAtkIntervalIncr = 0.
private constant real BeeAtkSpeed = 2.
private constant real BeeAtkSpeedIncr = -0.5
private constant real BeeDist = 200.
private constant real BeeDistIncr = 0.
private constant real BeeDmg = 2.
private constant real BeeDmgIncr = 1.
private constant real BearChance = 20.
private constant real BearChanceIncr = 10.
private constant real BearDmg = 100.
private constant real BearDmgIncr = 50.
private constant real BearDist = 150.
private constant real BeeMoveSpeed = 300.
private constant real BeeCollision = 150.
private constant real AoE = 500.
private constant real AoEIncr = 0.
private constant real SlowAmount = 0.10
private constant real SlowIncr = 0.05
private constant string BeeModel = "units\\undead\\Locust\\Locust.mdl"
private constant integer BearUnit = 'ngz4'
private constant string BearAnim = "attack"
private constant real BearAnimTime = 1.
private constant string BearAttach = "chest"
private constant string HoneyStartEffect = "Abilities\\Spells\\Other\\HealingSpray\\HealBottleMissile.mdl"
private constant string HoneyAreaEffect = ""
private constant real HoneyAreaEffectScale = 1.
private constant real HoneyAreaEffectScaleIncr = 0.
private constant string HoneyAreaSecondaryEffect = "Abilities\\Spells\\Undead\\ReplenishHealth\\ReplenishHealthCasterOverhead.mdl"
private constant integer HoneyAreaSecondaryEffectSum = 10
private constant real HoneyAreaSecondaryEffectInterval = 0.25
private constant string HoneyBuffEffect = "Abilities\\Spells\\Human\\slow\\slowtarget.mdl"
private constant string HoneyEndEffect = "Abilities\\Spells\\Other\\Andt\\Andt.mdl"
private constant string BeeAppearEffect = "Abilities\\Weapons\\snapMissile\\snapMissile.mdl"
private constant string BeeAttachEffect = ""
private constant string BeeDmgEffect = "Abilities\\Weapons\\PoisonArrow\\PoisonArrowMissile.mdl"
private constant string BeeDisappearEffect = "units\\undead\\Locust\\Locust.mdl"
private constant string BearAppearEffect = "Abilities\\Spells\\Human\\Polymorph\\PolyMorphTarget.mdl"
private constant string BearDmgEffect = "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"
private constant string BearAttachEffect = ""
private constant string BearDisappearEffect = "Abilities\\Spells\\Orc\\FeralSpirit\\feralspiritdone.mdl"
private constant real TimeOut = 0.03
private constant attacktype BeeATT = ATTACK_TYPE_NORMAL
private constant damagetype BeeDGT = DAMAGE_TYPE_NORMAL
private constant weapontype BeeWPT = WEAPON_TYPE_WHOKNOWS
private constant attacktype BearATT = ATTACK_TYPE_NORMAL
private constant damagetype BearDGT = DAMAGE_TYPE_NORMAL
private constant weapontype BearWPT = WEAPON_TYPE_WHOKNOWS
private real array R
endglobals
private struct Bear
private unit Caster
private unit Target
private unit Bear
private real Dmg
private real Time
private effect sfx
private static Bear array Index
private static integer Total = 0
private static timer Timer = CreateTimer()
static method Loop takes nothing returns nothing
local Bear dat
local integer i = 0
loop
exitwhen i >= Bear.Total
set dat = Bear.Index[i]
set dat.Time = dat.Time - TimeOut
set R[0] = GetUnitFacing(dat.Bear)-180.
if R[0] < 0 then
set R[0] = R[0] + 360.
endif
set R[1] = GetUnitX(dat.Target)+(BearDist*Cos(R[0]*bj_DEGTORAD))
set R[2] = GetUnitY(dat.Target)+(BearDist*Sin(R[0]*bj_DEGTORAD))
call SetUnitX(dat.Bear,R[1])
call SetUnitY(dat.Bear,R[2])
if dat.Time <= 0 then
call UnitDamageTarget(dat.Caster,dat.Target,dat.Dmg,true,false,BearATT,BearDGT,BearWPT)
call DestroyEffect(AddSpecialEffect(BearDmgEffect,GetUnitX(dat.Target),GetUnitY(dat.Target)))
call DestroyEffect(dat.sfx)
call DestroyEffect(AddSpecialEffect(BearDisappearEffect,GetUnitX(dat.Bear),GetUnitY(dat.Bear)))
call RemoveUnit(dat.Bear)
call dat.destroy()
set Bear.Total = Bear.Total - 1
set Bear.Index[i] = Bear.Index[Bear.Total]
set i = i - 1
endif
set i = i+1
endloop
if Bear.Total == 0 then
call PauseTimer(Bear.Timer)
endif
endmethod
static method Create takes unit u, unit t, real dmg returns nothing
local Bear dat = Bear.allocate()
set dat.Caster = u
set dat.Target = t
set dat.Dmg = dmg
set R[0] = GetRandomReal(0.,360.)
set R[1] = GetUnitX(dat.Target)+(BearDist*Cos(R[0]*bj_DEGTORAD))
set R[2] = GetUnitY(dat.Target)+(BearDist*Sin(R[0]*bj_DEGTORAD))
set dat.Bear = CreateUnit(GetOwningPlayer(u),BearUnit,R[1],R[2],R[0])
call UnitAddAbility(dat.Bear,'Avul')
call UnitAddAbility(dat.Bear,'Aloc')
set dat.Time = BearAnimTime
call SetUnitAnimation(dat.Bear,BearAnim)
call DestroyEffect(AddSpecialEffect(BearAppearEffect,R[1],R[2]))
set dat.sfx = AddSpecialEffectTarget(BearAttachEffect,dat.Bear,BearAttach)
if Bear.Total == 0 then
call TimerStart(Bear.Timer,TimeOut,true,function Bear.Loop)
endif
set Bear.Index[Bear.Total] = dat
set Bear.Total = Bear.Total + 1
endmethod
endstruct
private struct Bee
private unit Bee
private unit Caster
private unit Target
private real Dist
private real angle
private real Time
private real time2
private real Dmg
private real Chance
private integer level
private integer Code
private integer ActID
private effect sfx
private effect sfx2
static real array Interval
private static Bee array Index
private static integer Total = 0
private static timer Timer = CreateTimer()
static method Finish takes unit t, integer c returns nothing
local integer i = 0
local Bee dat
loop
exitwhen i >= Bee.Total
set dat = Bee.Index[i]
if (dat.Target == t) and (dat.Code == c) then
call DestroyEffect(dat.sfx)
call DestroyEffect(dat.sfx2)
call DestroyEffect(AddSpecialEffect(BeeDisappearEffect,GetUnitX(dat.Bee),GetUnitY(dat.Bee)))
call UnitApplyTimedLife(dat.Bee,'BTLF',TimeOut)
call dat.destroy()
set Bee.Total = Bee.Total - 1
set Bee.Index[i] = Bee.Index[Bee.Total]
if Bee.Total == 0 then
call PauseTimer(Bee.Timer)
endif
set i = i - 1
endif
set i = i+1
endloop
endmethod
static method Change takes unit t, integer from, integer to returns nothing
local integer i = 0
local Bee dat
loop
exitwhen i >= Bee.Total
set dat = Bee.Index[i]
if (dat.Target == t) and (dat.Code == from) then
set dat.Code = to
set Bee.Interval[to] = Bee.Interval[from]
endif
set i = i+1
endloop
endmethod
static method Loop takes nothing returns nothing
local integer i = 0
local Bee dat
loop
exitwhen i >= Bee.Total
set dat = Bee.Index[i]
set dat.angle = dat.angle+((BeeMoveSpeed*TimeOut/dat.Dist)*bj_RADTODEG)
if dat.angle <= 0 then
set dat.angle = dat.angle+360.
endif
if dat.ActID == 0 then
if dat.time2 > 0 then
set dat.time2 = dat.time2-TimeOut
endif
call SetUnitX(dat.Bee,GetUnitX(dat.Target)+(dat.Dist*Cos(dat.angle*bj_DEGTORAD)))
call SetUnitY(dat.Bee,GetUnitY(dat.Target)+(dat.Dist*Sin(dat.angle*bj_DEGTORAD)))
call SetUnitFacing(dat.Bee,dat.angle+90.)
if (dat.time2 <= 0) and (Bee.Interval[dat.Code] <= 0) then
set dat.ActID = 1
set dat.time2 = dat.Time
set Bee.Interval[dat.Code] = BeeAtkInterval+(BeeAtkIntervalIncr*I2R(dat.level))
endif
elseif dat.ActID == 1 then
set R[0] = Atan2(GetUnitY(dat.Target)-GetUnitY(dat.Bee),GetUnitX(dat.Target)-GetUnitX(dat.Bee))
set R[1] = GetUnitX(dat.Bee)+(BeeMoveSpeed*TimeOut*Cos(R[0]))
set R[2] = GetUnitY(dat.Bee)+(BeeMoveSpeed*TimeOut*Sin(R[0]))
call SetUnitX(dat.Bee,R[1])
call SetUnitY(dat.Bee,R[2])
set R[3] = R[1] - GetUnitX(dat.Target)
set R[4] = R[2] - GetUnitY(dat.Target)
set R[5] = SquareRoot((R[3]*R[3])+(R[4]*R[4]))
if R[5] <= BeeCollision then
set dat.ActID = 2
call UnitDamageTarget(dat.Caster,dat.Target,dat.Dmg,true,false,BeeATT,BeeDGT,BeeWPT)
call DestroyEffect(AddSpecialEffect(BeeDmgEffect,GetUnitX(dat.Target),GetUnitY(dat.Target)))
if GetRandomReal(0.,100.) <= dat.Chance then
call Bear.Create(dat.Caster,dat.Target,BearDmg+(BearDmgIncr*I2R(dat.level)))
endif
endif
elseif dat.ActID == 2 then
set R[6] = GetUnitX(dat.Target)+(dat.Dist*Cos(dat.angle*bj_DEGTORAD))
set R[7] = GetUnitY(dat.Target)+(dat.Dist*Sin(dat.angle*bj_DEGTORAD))
set R[0] = Atan2(R[7]-GetUnitY(dat.Bee),R[6]-GetUnitX(dat.Bee))
set R[1] = GetUnitX(dat.Bee)+(BeeMoveSpeed*TimeOut*Cos(R[0]))
set R[2] = GetUnitY(dat.Bee)+(BeeMoveSpeed*TimeOut*Sin(R[0]))
call SetUnitX(dat.Bee,R[1])
call SetUnitY(dat.Bee,R[2])
set R[3] = R[1] - R[6]
set R[4] = R[2] - R[7]
set R[5] = SquareRoot((R[3]*R[3])+(R[4]*R[4]))
if R[5] <= BeeCollision then
set dat.ActID = 0
call SetUnitX(dat.Bee,R[6])
call SetUnitY(dat.Bee,R[7])
call SetUnitFacing(dat.Bee,dat.angle+90.)
endif
endif
set i = i+1
endloop
endmethod
static method Create takes unit c, unit u, integer i, integer lvl returns nothing
local Bee dat = Bee.allocate()
set dat.Caster = c
set dat.Target = u
set dat.Code = i
set dat.ActID = 0
set dat.level = lvl
set dat.Dist = BeeDist+(BeeDistIncr*I2R(dat.level))
set dat.angle = GetRandomReal(0.,360.)
set dat.Time = BeeAtkSpeed+(BeeAtkSpeedIncr*I2R(dat.level))
set dat.time2 = dat.Time
set dat.Dmg = BeeDmg+(BeeDmgIncr*I2R(dat.level))
set dat.Chance = BearChance+(BearChanceIncr*I2R(dat.level))
set dat.Bee = CreateUnit(GetOwningPlayer(dat.Caster),DummyID,GetUnitX(dat.Target)+(dat.Dist*Cos(dat.angle*bj_DEGTORAD)),GetUnitY(dat.Target)+(dat.Dist*Sin(dat.angle*bj_DEGTORAD)),dat.angle+90)
set dat.sfx = AddSpecialEffectTarget(BeeModel,dat.Bee,DummyAttach)
set dat.sfx2 = AddSpecialEffectTarget(BeeAttachEffect,dat.Bee,DummyAttach)
call DestroyEffect(AddSpecialEffect(BeeAppearEffect,GetUnitX(dat.Bee),GetUnitY(dat.Bee)))
if Bee.Total == 0 then
call TimerStart(Bee.Timer,TimeOut,true,function Bee.Loop)
endif
set Bee.Index[Bee.Total] = dat
set Bee.Total = Bee.Total + 1
endmethod
endstruct
private struct Slow
private unit Caster
private unit Affected
private real Amount
private real time
private effect sfx
private integer Code
private static Slow array Index
private static integer Total = 0
private static timer Timer = CreateTimer()
static method Finish takes unit u, integer a returns nothing
local integer i = 0
local Slow dat
loop
exitwhen i >= Slow.Total
set dat = Slow.Index[i]
if (dat.Affected == u) and (dat.Code == a) then
call DestroyEffect(dat.sfx)
call SetUnitMoveSpeed(dat.Affected,GetUnitMoveSpeed(dat.Affected)+dat.Amount)
call Bee.Finish(dat.Affected,i)
call dat.destroy()
set Slow.Total = Slow.Total-1
set Slow.Index[i] = Slow.Index[Slow.Total]
call Bee.Change(Slow.Index[Slow.Total].Affected,Slow.Total,i)
if Slow.Total == 0 then
call PauseTimer(Slow.Timer)
endif
set i = i-1
endif
set i = i+1
endloop
endmethod
static method Change takes unit u, integer from, integer to returns nothing
local integer i = 0
local Slow dat
loop
exitwhen i >= Slow.Total
set dat = Slow.Index[i]
if (dat.Affected == u) and (dat.Code == from) then
set dat.Code = to
endif
set i = i+1
endloop
endmethod
static method Loop takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= Slow.Total
set Bee.Interval[i] = Bee.Interval[i]-TimeOut
set i = i+1
endloop
endmethod
static method Create takes unit c, unit u, real r, effect fx, integer i, integer lvl returns nothing
local Slow dat = Slow.allocate()
local integer s
set dat.Caster = c
set dat.Affected = u
set dat.Amount = r
call SetUnitMoveSpeed(u,GetUnitMoveSpeed(u)-dat.Amount)
set dat.sfx = fx
set dat.Code = i
set Bee.Interval[Slow.Total]=BeeAtkInterval+(BeeAtkIntervalIncr*I2R(lvl))
set s = BeeSum+(BeeSumIncr*lvl)
loop
exitwhen s <= 0
call Bee.Create(dat.Caster,dat.Affected,Slow.Total,lvl)
set s = s-1
endloop
if Slow.Total == 0 then
call TimerStart(Slow.Timer,TimeOut,true,function Slow.Loop)
endif
set Slow.Index[Slow.Total] = dat
set Slow.Total = Slow.Total+1
endmethod
endstruct
private struct Honey
private unit Caster
private real CentralX
private real CentralY
private real Area
private real Time
private real Time2
private integer level
private unit sfxu
private effect sfx
private group Affected
private static unit Temp
private static Honey array Index
private static integer Total = 0
private static timer Timer = CreateTimer()
static method CanTargeted takes nothing returns boolean
if not IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(Honey.Temp))then
return false
elseif IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) then
return false
elseif IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD) then
return false
elseif not IsUnitVisible(GetFilterUnit(), GetOwningPlayer(Honey.Temp)) then
return false
else
return true
endif
endmethod
static method Loop takes nothing returns nothing
local Honey dat
local group g = CreateGroup()
local unit u
local boolexpr filter
local integer i = 0
local integer j = 0
loop
exitwhen i >= Honey.Total
set dat = Honey.Index[i]
set dat.Time = dat.Time-TimeOut
set dat.Time2 = dat.Time2-TimeOut
call GroupAddGroup(dat.Affected,g)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g,u)
set R[0] = dat.CentralX - GetUnitX(u)
set R[1] = dat.CentralY - GetUnitY(u)
set R[2] = SquareRoot((R[0]*R[0])+(R[1]*R[1]))
if (R[2] > dat.Area) or (not(IsUnitEnemy(u, GetOwningPlayer(dat.Caster)))) or (IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)) or (IsUnitType(u, UNIT_TYPE_DEAD)) or (not(IsUnitVisible(u, GetOwningPlayer(dat.Caster)))) then
call GroupRemoveUnit(dat.Affected,u)
call Slow.Finish(u,i)
endif
endloop
set filter = Filter(function Honey.CanTargeted)
set Honey.Temp = dat.Caster
call GroupEnumUnitsInRange(g,dat.CentralX,dat.CentralY,dat.Area,filter)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g,u)
if not IsUnitInGroup(u,dat.Affected) then
call GroupAddUnit(dat.Affected,u)
call Slow.Create(dat.Caster,u,GetUnitMoveSpeed(u)*(SlowAmount+(SlowIncr*I2R(dat.level))),AddSpecialEffectTarget(HoneyBuffEffect,u,BuffAttach),i,dat.level)
endif
endloop
set Honey.Temp = null
call DestroyBoolExpr(filter)
if dat.Time2 <= 0 then
set dat.Time2 = HoneyAreaSecondaryEffectInterval
set j = HoneyAreaSecondaryEffectSum
loop
exitwhen j == 0
set R[0] = GetRandomReal(0.,dat.Area)
set R[1] = GetRandomReal(0.,360.)
set R[2] = dat.CentralX+(R[0]*Cos(R[1]*bj_DEGTORAD))
set R[3] = dat.CentralY+(R[0]*Sin(R[1]*bj_DEGTORAD))
call DestroyEffect(AddSpecialEffect(HoneyAreaSecondaryEffect,R[2],R[3]))
set j = j-1
endloop
endif
if dat.Time <= 0 then
loop
set u = FirstOfGroup(dat.Affected)
exitwhen u == null
call GroupRemoveUnit(dat.Affected,u)
call Slow.Finish(u,i)
endloop
call DestroyEffect(dat.sfx)
call UnitApplyTimedLife(dat.sfxu,'BTLF',0.5)
call DestroyEffect(AddSpecialEffect(HoneyEndEffect,dat.CentralX,dat.CentralY))
call DestroyGroup(dat.Affected)
call dat.destroy()
set Honey.Total = Honey.Total - 1
set Honey.Index[i] = Honey.Index[Honey.Total]
call GroupAddGroup(Honey.Index[Honey.Total].Affected,g)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g,u)
call Slow.Change(u,Honey.Total,i)
endloop
set i = i-1
endif
set i = i+1
endloop
if Honey.Total == 0 then
call PauseTimer(Honey.Timer)
endif
call DestroyGroup(g)
set g = null
set u = null
endmethod
static method Create takes nothing returns nothing
local Honey dat = Honey.allocate()
local unit u = GetTriggerUnit()
local unit u2
local location loc = GetSpellTargetLoc()
local group g = CreateGroup()
local integer i = HoneyAreaSecondaryEffectSum
local boolexpr filter
set dat.Caster = u
set dat.level = GetUnitAbilityLevel(u,SpellID) - 1
set dat.CentralX = GetLocationX(loc)
set dat.CentralY = GetLocationY(loc)
set dat.Time = Duration+(DurationIncr*I2R(dat.level))
set dat.Time2 = HoneyAreaSecondaryEffectInterval
set dat.Area = AoE+(AoEIncr*I2R(dat.level))
set dat.sfxu = CreateUnit(GetOwningPlayer(u),DummyID,dat.CentralX,dat.CentralY,0.)
set dat.sfx = AddSpecialEffectTarget(HoneyAreaEffect,dat.sfxu,DummyAttach)
call SetUnitScale(dat.sfxu,HoneyAreaEffectScale+(HoneyAreaEffectScaleIncr*I2R(dat.level)),0.,0.)
set dat.Affected = CreateGroup()
call DestroyEffect(AddSpecialEffect(HoneyStartEffect,dat.CentralX,dat.CentralY))
loop
exitwhen i == 0
set R[0] = GetRandomReal(0.,dat.Area)
set R[1] = GetRandomReal(0.,360.)
set R[2] = dat.CentralX+(R[0]*Cos(R[1]*bj_DEGTORAD))
set R[3] = dat.CentralY+(R[0]*Sin(R[1]*bj_DEGTORAD))
call DestroyEffect(AddSpecialEffect(HoneyAreaSecondaryEffect,R[2],R[3]))
set i = i-1
endloop
set filter = Filter(function Honey.CanTargeted)
set Honey.Temp = u
call GroupEnumUnitsInRange(g,dat.CentralX,dat.CentralY,dat.Area,filter)
loop
set u2 = FirstOfGroup(g)
exitwhen u2 == null
call GroupRemoveUnit(g,u2)
call GroupAddUnit(dat.Affected,u2)
call Slow.Create(u,u2,GetUnitMoveSpeed(u2)*(SlowAmount+(SlowIncr*I2R(dat.level))),AddSpecialEffectTarget(HoneyBuffEffect,u2,BuffAttach),Honey.Total,dat.level)
endloop
set Honey.Temp = null
call DestroyBoolExpr(filter)
if Honey.Total == 0 then
call TimerStart(Honey.Timer,TimeOut,true,function Honey.Loop)
endif
set Honey.Index[Honey.Total] = dat
set Honey.Total = Honey.Total+1
call RemoveLocation(loc)
call DestroyGroup(g)
set loc = null
set u = null
set u2 = null
set g = null
endmethod
endstruct
private function Conditions takes nothing returns boolean
if GetSpellAbilityId() == SpellID then
call Honey.Create()
endif
return false
endfunction
private function InitTrig_Initialize takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function Conditions))
call RemoveUnit(CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),BearUnit,0,0,0))
call Preload(BeeModel)
call Preload(HoneyStartEffect)
call Preload(HoneyAreaEffect)
call Preload(HoneyAreaSecondaryEffect)
call Preload(HoneyBuffEffect)
call Preload(HoneyEndEffect)
call Preload(BeeAppearEffect)
call Preload(BeeAttachEffect)
call Preload(BeeDmgEffect)
call Preload(BeeDisappearEffect)
call Preload(BearAppearEffect)
call Preload(BearDmgEffect)
call Preload(BearDisappearEffect)
call PreloadStart()
endfunction
endscope
scope Bedlam initializer InitTrig_Bedlam
globals
private constant integer ABILID = 'A000'
private constant integer DUMMYABILID = 'A001'
private constant integer DUMMYORDERABILID = 'A007'
private constant integer BUFFID = 'B000'
private constant integer DUMMYID = 'h000'
private constant integer DESELECTCHANCE = 50
private constant integer MOVECHANCE = 50
private constant integer ATTACKCHANCE = 50
private constant real TIMEOUTMIN = 1.
private constant real TIMEOUTMAX = 3.
private constant real DURNORMAL = 30.
private constant real DURHERO = 10.
private constant real DISTMIN = 128.
private constant real DISTMAX = 500.
private constant string DUMMYORDER = "slow"
private unit dummy
private player plr
private integer bedlams = 0
private hashtable hash = InitHashtable()
private group grp = CreateGroup()
private group CastedOn = CreateGroup()
private group BedlamActive = CreateGroup()
trigger BedlamSelected = CreateTrigger()
endglobals
private function GroupFilter takes nothing returns boolean
local unit u = GetFilterUnit()
if GetWidgetLife(u) > 0.405 and /*
*/ IsUnitAlly(u , plr) /*
*/ then
set u = null
return true
else
set u = null
return false
endif
endfunction
private function Remove takes unit who returns nothing
local integer ID = GetHandleId(who)
call GroupRemoveUnit(BedlamActive , who)
call UnitRemoveAbility(who , DUMMYABILID)
call UnitAddAbility(who , DUMMYORDERABILID)
set bedlams = bedlams - 1
if bedlams == 0 then
call DisableTrigger(BedlamSelected)
endif
set bj_lastStartedTimer = LoadTimerHandle(hash , ID , StringHash("timer"))
call FlushChildHashtable(hash , GetHandleId(bj_lastStartedTimer))
call DestroyTimer(bj_lastStartedTimer)
call FlushChildHashtable(hash , ID)
endfunction
private function TimerExpire takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer ID = GetHandleId(t)
local unit u = LoadUnitHandle(hash , ID , StringHash("unit"))
local integer ID2 = GetHandleId(u)
local real time = LoadReal(hash , ID2 , StringHash("time"))
local real timeout = GetRandomReal(TIMEOUTMIN , TIMEOUTMAX)
local real angle
local real dist
if time-timeout <= 0. or GetWidgetLife(u) < 0.405 or GetUnitAbilityLevel(u , BUFFID) == 0 then
call Remove(u)
else
if GetRandomInt(1, 2) == 1 then
if GetRandomInt(1, 100) <= MOVECHANCE then
set angle = GetRandomReal(-bj_PI , bj_PI)
set dist = GetRandomReal(DISTMIN , DISTMAX)
call DisableTrigger(BedlamSelected)
call IssuePointOrder(u , "move" , GetUnitX(u) + dist * Cos(angle) , GetUnitY(u) + dist * Sin(angle))
call EnableTrigger(BedlamSelected)
endif
else
if GetRandomInt(1, 100) <= MOVECHANCE then
call GroupEnumUnitsInRange(grp , GetUnitX(u) , GetUnitY(u) , DISTMAX , function GroupFilter)
if FirstOfGroup(grp) != null and FirstOfGroup(grp) != u then
call DisableTrigger(BedlamSelected)
call IssueTargetOrder(u , "attack" , FirstOfGroup(grp))
call EnableTrigger(BedlamSelected)
endif
call GroupClear(grp)
endif
endif
if GetLocalPlayer() == GetOwningPlayer(u) then
if GetRandomInt(1, 100) <= DESELECTCHANCE then
call SelectUnit(u , false)
endif
endif
call SaveReal(hash , ID2 , StringHash("time") , time - timeout)
call TimerStart(t , timeout , false , function TimerExpire)
endif
set u = null
set t = null
endfunction
private function SelectActions takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer oID = GetIssuedOrderId() - 851000
local integer chance
local real angle
local real dist
set plr = GetOwningPlayer(u)
if GetIssuedOrderId() > 0 then
if GetRandomInt(1, 100) <= MOVECHANCE then
if oID == 971 or oID == 986 or oID == 983 or oID == 972 or oID == 993 then
if GetRandomInt(1,2) == 1 then
call IssueImmediateOrder(u , "cripple")
else
set angle = GetRandomReal(-bj_PI , bj_PI)
set dist = GetRandomReal(DISTMIN , DISTMAX)
call DisableTrigger(BedlamSelected)
call IssuePointOrder(u , "move" , GetUnitX(u) + dist * Cos(angle) , GetUnitY(u) + dist * Sin(angle))
call EnableTrigger(BedlamSelected)
endif
endif
endif
elseif GetLocalPlayer() == plr then
if GetRandomInt(1, 100) <= DESELECTCHANCE then
call SelectUnit(u , false)
endif
endif
set u = null
endfunction
private function SelectConditions takes nothing returns boolean
return IsUnitInGroup(GetTriggerUnit() , BedlamActive)
endfunction
private function CastConditions takes nothing returns boolean
return GetSpellAbilityId() == ABILID
endfunction
private function CastActions takes nothing returns nothing
local unit target = GetSpellTargetUnit()
local player p = GetOwningPlayer(target)
local integer ID = GetHandleId(target)
local real timeout = GetRandomReal(TIMEOUTMIN , TIMEOUTMAX)
call SetUnitX(dummy , GetUnitX(target))
call SetUnitY(dummy , GetUnitY(target))
call SetUnitAbilityLevel(dummy , DUMMYABILID , GetUnitAbilityLevel(GetTriggerUnit() , ABILID))
call IssueTargetOrder(dummy , DUMMYORDER , target)
if IsUnitSelected(target , p) and GetLocalPlayer() == p then
if GetRandomInt(1, 100) <= DESELECTCHANCE then
call SelectUnit(target , false)
endif
endif
if IsUnitInGroup(target , CastedOn) == false then
call GroupAddUnit(CastedOn , target)
call TriggerRegisterUnitEvent(BedlamSelected , target , EVENT_UNIT_SELECTED)
call TriggerRegisterUnitEvent(BedlamSelected , target , EVENT_UNIT_ISSUED_ORDER)
call TriggerRegisterUnitEvent(BedlamSelected , target , EVENT_UNIT_ISSUED_POINT_ORDER)
call TriggerRegisterUnitEvent(BedlamSelected , target , EVENT_UNIT_ISSUED_TARGET_ORDER)
endif
if IsUnitType(target , UNIT_TYPE_HERO) then
call SaveReal(hash , ID , StringHash("time") , DURHERO - timeout)
else
call SaveReal(hash , ID , StringHash("time") , DURNORMAL - timeout)
endif
if not(HaveSavedHandle(hash , ID , StringHash("timer"))) then
call UnitAddAbility(target , DUMMYORDERABILID)
set bj_lastStartedTimer = CreateTimer()
call TimerStart(bj_lastStartedTimer , timeout , false , function TimerExpire )
call SaveTimerHandle( hash , ID , StringHash("timer") , bj_lastStartedTimer )
call SaveUnitHandle( hash , GetHandleId(bj_lastStartedTimer) , StringHash("unit") , target )
if bedlams == 0 then
call EnableTrigger(BedlamSelected)
endif
set bedlams = bedlams + 1
call GroupAddUnit(BedlamActive , target)
endif
set p = null
set target = null
endfunction
private function InitTrig_Bedlam takes nothing returns nothing
local trigger t = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( t , EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( t , Condition( function CastConditions ) )
call TriggerAddAction( t , function CastActions )
call TriggerAddCondition( BedlamSelected , Condition( function SelectConditions ) )
call TriggerAddAction( BedlamSelected , function SelectActions )
call DisableTrigger(BedlamSelected)
set dummy = CreateUnit( Player(15) , DUMMYID , 0 , 0 , 0 )
call ShowUnit(dummy , false)
endfunction
endscope
scope Moonwalk initializer InitTrig_Moonwalk
globals
private constant integer ABILID = 'A003'
private constant integer BOOKID = 'A004'
private constant integer ABILDUMMYID = 'A005'
private constant integer DUMMYID = 'h000'
private constant integer INDEX = 12
private constant real DURATION = 8.
private constant real OFFSET = 200.
private constant real SPEEDLOOP = bj_PI/16.
private constant real AOE = 250.
private constant real DMGBASE = 50.
private constant real DMGBONUS = 25.
private constant real TIMEOUTMIN = 1.
private constant real TIMERLOOP = 0.03125
private constant string array FLOATS
private constant integer floatAmount = 2
private constant attacktype ATK_TYPE = ATTACK_TYPE_NORMAL
private constant damagetype DMG_TYPE = DAMAGE_TYPE_NORMAL
private constant string DUMMYORDER = "innerfire"
private constant string EFFECTTARGET = "Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl"
private constant string EFFECTCASTER = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"
private real dmg
private unit caster
private player plr
private integer moonwalks = 0
private integer actives = 0
private unit dummy
private hashtable hash = InitHashtable()
private group grp = CreateGroup()
private group ActiveWalkers = CreateGroup()
private group Moonwalkers = CreateGroup()
private timer MoonwalkTimer = CreateTimer()
trigger MoonwalkAttacked = CreateTrigger()
endglobals
private function DamageFilter takes nothing returns boolean
local unit u = GetFilterUnit()
if GetWidgetLife(u) > 0.405 and /*
*/ IsUnitEnemy(u , plr) /*
*/ then
call DestroyEffect(AddSpecialEffectTarget(EFFECTTARGET , u , "chest"))
call UnitDamageTarget(caster , u , dmg , true , false , ATK_TYPE , DMG_TYPE , WEAPON_TYPE_WHOKNOWS)
endif
set u = null
return false
endfunction
private function LoopWalkers takes nothing returns nothing
local unit u = GetEnumUnit()
local integer id = GetHandleId(u)
local real r = LoadReal(hash , id , StringHash("loop"))
local real angle = LoadReal(hash , id , StringHash("angle"))
local real x = LoadReal(hash , id , StringHash("x"))
local real y = LoadReal(hash , id , StringHash("y"))
call SetUnitX(u , x + OFFSET * Cos(angle) * Sin(r))
call SetUnitY(u , y + OFFSET * Sin(angle) * Sin(r))
set r = r + SPEEDLOOP
if r < bj_PI and GetWidgetLife(u) > 0.405 then
call SaveReal(hash , id , StringHash("loop") , r)
call SetUnitVertexColor(u , 255 , 255 , 255 , R2I(255*r/bj_PI) )
else
call SetUnitX(u,x)
call SetUnitY(u,y)
call UnitRemoveAbility(u , BOOKID)
call UnitRemoveAbility(u , ABILDUMMYID)
call SetUnitTimeScale(u , 1)
call SetUnitAnimation(u , "stand")
call SetUnitVertexColor(u , 255 , 255 , 255 , 255 )
call DestroyEffect(LoadEffectHandle(hash , id , StringHash("effect")))
set caster = u
set plr = GetOwningPlayer(u)
set dmg = LoadReal(hash , id , StringHash("damage"))
call GroupEnumUnitsInRange(grp , x , y , AOE , function DamageFilter)
call GroupClear(grp)
call GroupRemoveUnit(ActiveWalkers , u)
set actives = actives - 1
if actives == 0 then
call PauseTimer(MoonwalkTimer)
endif
endif
set u = null
endfunction
private function TimerExpire takes nothing returns nothing
call ForGroup(ActiveWalkers , function LoopWalkers)
endfunction
private function EvadeActions takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit attacker = GetAttacker()
local integer id = GetHandleId(u)
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real angle = Atan2(y - GetUnitY(attacker) , x - GetUnitX(attacker)) + GetRandomReal(-bj_PI/2 , bj_PI/2)
if not(IsUnitInGroup(u , ActiveWalkers)) then
set bj_lastCreatedTextTag = CreateTextTag()
call SetTextTagText(bj_lastCreatedTextTag , FLOATS[GetRandomInt(1,2)] , 0.021)
call SetTextTagPosUnit(bj_lastCreatedTextTag , u , 0. )
call SetTextTagColor(bj_lastCreatedTextTag , 255 , 255 , 255 , 255)
call SetTextTagVelocity( bj_lastCreatedTextTag , 0, 0.05 )
call SetTextTagPermanent( bj_lastCreatedTextTag , false )
call SetTextTagLifespan( bj_lastCreatedTextTag , 2.00 )
call SetTextTagFadepoint( bj_lastCreatedTextTag , 1.70 )
call SaveReal(hash , id , StringHash("angle") , angle)
call SaveReal(hash , id , StringHash("loop") , 0)
call SaveReal(hash , id , StringHash("x") , x)
call SaveReal(hash , id , StringHash("y") , y)
call SaveEffectHandle(hash , id , StringHash("effect") , AddSpecialEffectTarget(EFFECTCASTER , u , "origin"))
call UnitAddAbility(u , BOOKID)
call UnitAddAbility(u , ABILDUMMYID)
call SetUnitTimeScale(u , 2)
call IssueImmediateOrder(u , "controlmagic")
call SetUnitAnimationByIndex(u , INDEX)
if actives == 0 then
call TimerStart(MoonwalkTimer , TIMERLOOP , true , function TimerExpire)
endif
set actives = actives + 1
call GroupAddUnit(ActiveWalkers , u)
endif
set u = null
endfunction
private function CastActions takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer ID = GetHandleId(u)
call SaveReal(hash , ID , StringHash("damage") , DMGBASE + (GetUnitAbilityLevel(u , ABILID) - 1) * DMGBONUS)
if moonwalks == 0 then
call EnableTrigger(MoonwalkAttacked)
endif
set moonwalks = moonwalks + 1
call GroupAddUnit(Moonwalkers , u)
call SetUnitX(dummy , GetUnitX(u))
call SetUnitY(dummy , GetUnitY(u))
call IssueTargetOrder(dummy , DUMMYORDER , u)
call TriggerSleepAction(DURATION)
set moonwalks = moonwalks + 1
call UnitRemoveAbility(u , BOOKID)
if moonwalks == 0 then
call DisableTrigger(MoonwalkAttacked)
endif
call GroupRemoveUnit(Moonwalkers , u)
set u = null
endfunction
private function EvadeConditions takes nothing returns boolean
return IsUnitInGroup(GetTriggerUnit() , Moonwalkers)
endfunction
private function CastConditions takes nothing returns boolean
return GetSpellAbilityId() == ABILID
endfunction
private function InitTrig_Moonwalk takes nothing returns nothing
local trigger t = CreateTrigger( )
local integer i = 0
call TriggerRegisterAnyUnitEventBJ( t , EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( t , Condition( function CastConditions ) )
call TriggerAddAction( t , function CastActions )
call TriggerRegisterAnyUnitEventBJ( MoonwalkAttacked , EVENT_PLAYER_UNIT_ATTACKED )
call TriggerAddCondition( MoonwalkAttacked , Condition( function EvadeConditions ) )
call TriggerAddAction( MoonwalkAttacked , function EvadeActions )
loop
call SetPlayerAbilityAvailable(Player(i) , BOOKID , false)
exitwhen i == 15
set i = i + 1
endloop
call DisableTrigger(MoonwalkAttacked)
set dummy = CreateUnit( Player(15) , DUMMYID , 0 , 0 , 0 )
call ShowUnit(dummy , false)
set FLOATS[1] = "Can't touch this!"
set FLOATS[2] = "You can't see me!"
endfunction
endscope
Custom values are a surefire way to get less points from a reviewer. Also remember to clean leaks.
:O
I've forgot to check which spell was casted, thanks for pointing that out lol
Anyway i've updated spell, remade it in vJASS. Hopefully,there aren't any flaws except that i've used hashtables over structs since it's my first vJASS spell :X
huh? Dunno what caused this, but it works fine for me.Mage Goo,
Your spell gives me a compile error while trying to save before testing
And yes,i opened with JNGP.
scope HoneyShower initializer InitTrig_Initialize
///////////////////////////////////////////////////////////////////////////////////////
//Welcome to the Header //
//u can customize most part of the spell from here //
///////////////////////////////////////////////////////////////////////////////////////
globals
//Insert the raw-code of your Honey Shower ability. U can see the raw-code of the spell by pressing Ctrl+D.
private constant integer SpellID = 'A000'
//Insert your dummy unit raw-code. Dummy unit must be able to be attached by an effect.
private constant integer DummyID = 'n000'
//this one for the attachment point of the dummy. most of it use either "chest" or "origin".
private constant string DummyAttach = "chest"
//insert where u want the effect attached to enemy unit that get affected by this spell.
//in this spell, the only effect attached to enemy is slow effect when enemy is in the area of spell.
private constant string BuffAttach = "origin"
//to produce a value in this spell that get increased/decreased on different level,
//i use the default and modifier value. for lvl 1 spell, the default value will be applied.
//on each increased lvl, the modifier value will be added to default value, thus effectively
//increase/decrease that value.
//ex: Bear's damage default value is 100 dmg and it's modifier value is 50 dmg.
// so, on lvl 1, bear's damage will be 100. on lvl 2 it's (100+50)=150 dmg,
//on lvl 3 it's (150+50)=200 dmg, and so on
//insert the honey duration default value here.
private constant real Duration = 5.
//insert modifier of honey duration here.
private constant real DurationIncr = 2.5
//insert the number of bee summoned for each affected unit here. this will be the default value.
private constant integer BeeSum = 3
//insert modifier of number of bee summoned here.
private constant integer BeeSumIncr = 1
//insert the attack interval for a group of bee here. this will be the default value.
private constant real BeeAtkInterval = 1.
//insert modifier of a bee's roup attack interval here.
private constant real BeeAtkIntervalIncr = 0.
//insert the attack speed of a single bee here. this will be the default value.
private constant real BeeAtkSpeed = 2.
//insert modifier of bee's attack speed here.
private constant real BeeAtkSpeedIncr = -0.5
//insert the distance between bee and it's target here. this will be the default value.
private constant real BeeDist = 200.
//insert modifier of distance between bee and it's target here.
private constant real BeeDistIncr = 0.
//insert the damage dealt by a single bee's attack here. this will be the default value.
private constant real BeeDmg = 2.
//insert modifier of bee's damage here.
private constant real BeeDmgIncr = 1.
//insert the chance for each bee's attack to summon a bear here.
//this processed as percentage. this will be the default value.
private constant real BearChance = 20.
//insert modifier of chance to summon bear here.
private constant real BearChanceIncr = 10.
//insert the damage dealt by a single bear's attack here. this will be the default value.
private constant real BearDmg = 100.
//insert modifier of bear's damage here.
private constant real BearDmgIncr = 50.
//insert the distance between bear and it's target here.
private constant real BearDist = 150.
//insert the bee's movement speed here.
private constant real BeeMoveSpeed = 300.
//insert the bee's collision here. it's the distance the bee's needed to successfully attack a unit.
private constant real BeeCollision = 150.
//insert the spell's area of effect here. this will be the default value.
private constant real AoE = 300.
//insert modifier of spell's area of effect here.
private constant real AoEIncr = 0.
//insert the amount of movement the honey will reduce from the affected unit here.
//this value should be between 0 and 1, while 0 means no slow and 1 means fully slow.
//multiply this by 100 and u get the percentage of slow.
private constant real SlowAmount = 0.10
//insert modifier of honey's slow amount here.
private constant real SlowIncr = 0.05
//insert the model's path of the model u want to use for the bee.
private constant string BeeModel = "units\\undead\\Locust\\Locust.mdl"
//insert the unit u want to be the bear here. any unit that use the model that u want to be bear works here.
//remember to use un-needed unit here for safety or just create a custom unit here.
private constant integer BearUnit = 'ngz4'
//insert the animation u want the bear to play when dealing damage to it's target.
private constant string BearAnim = "attack"
//insert the time it's needed to finish that animation.
private constant real BearAnimTime = 1.
//insert the attachment point u want the effect attached to.
private constant string BearAttach = "chest"
//insert the effect u want to be created once when the spell is started.
//the effect is created on center of the honey's area.
private constant string HoneyStartEffect = "Abilities\\Spells\\Other\\HealingSpray\\HealBottleMissile.mdl"
//insert the area effect that shown in the central of honey's area.
//this one last until the duration end.
private constant string HoneyAreaEffect = ""
//set the scale of the area effect. 1 is the normal size of the effect. this will be default value.
private constant real HoneyAreaEffectScale = 1.
//insert the area effect's scale modifier.
private constant real HoneyAreaEffectScaleIncr = 0.
//set the effect that will be created on random location in honey's area on each interval.
private constant string HoneyAreaSecondaryEffect = "Abilities\\Spells\\Undead\\ReplenishHealth\\ReplenishHealthCasterOverhead.mdl"
//set the number of secondary effect u want to be created on each interval.
private constant integer HoneyAreaSecondaryEffectSum = 10
//set the interval for the secondary efect to shown.
private constant real HoneyAreaSecondaryEffectInterval = 1.
//set the effect attached to unit's affected by honey's slow.
private constant string HoneyBuffEffect = "Abilities\\Spells\\Human\\slow\\slowtarget.mdl"
//set the effect that appear once when the spell's duration end.
private constant string HoneyEndEffect = "Abilities\\Spells\\Other\\Andt\\Andt.mdl"
//set the effect created when the bee is summoned.
private constant string BeeAppearEffect = "Abilities\\Weapons\\snapMissile\\snapMissile.mdl"
//set the effect attached to bee. this one is optional.
private constant string BeeAttachEffect = ""
//set the effect that created on enemy unit when they area damaged by the bee.
private constant string BeeDmgEffect = "Abilities\\Weapons\\PoisonArrow\\PoisonArrowMissile.mdl"
//set the effect that created when the bee disappear.
private constant string BeeDisappearEffect = "units\\undead\\Locust\\Locust.mdl"
//set the effect when the bear is successfully summoned.
private constant string BearAppearEffect = "Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl"
//set the effect when the bear successfully damage the enemy.
private constant string BearDmgEffect = "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"
//set the effect that will be attached to the bear. this one is optional.
private constant string BearAttachEffect = ""
//set the effect that created when the bear dsappear
private constant string BearDisappearEffect = "Abilities\\Spells\\Orc\\FeralSpirit\\feralspiritdone.mdl"
//set the timer's time out. the lower it is, the more precise the spell will get.
//but, warcraft has it's limit for time out though. don't use value lower than 0.03
//because it will lower the warcraft performance.
//this one usually between 0.05 to 0.03. 0.03 is more common(and efficient too!)
private constant real TimeOut = 0.03
//this one will decide the bee's attack type
private constant attacktype BeeATT = ATTACK_TYPE_NORMAL
//this one will decide the bee's damage type
private constant damagetype BeeDGT = DAMAGE_TYPE_NORMAL
//this one will decide the bee's weapon type
private constant weapontype BeeWPT = WEAPON_TYPE_WHOKNOWS
//this one will decide the bear's attack type
private constant attacktype BearATT = ATTACK_TYPE_NORMAL
//this one will decide the bear's damage type
private constant damagetype BearDGT = DAMAGE_TYPE_NORMAL
//this one will decide the bear's weapon type
private constant weapontype BearWPT = WEAPON_TYPE_WHOKNOWS
//////////////////////////////////////////////////////////////////////
private boolexpr filter
private unit temp
private group g = CreateGroup()
//this line is variable for the spell's mechanism. don't change it.
//it's for the sake of efficiency of the spell..
private real array R
//////////////////////////////////////////////////////////////////////
endglobals
//u can edit the condition the unit neded to be affected by the spell here
private function CanTarget takes unit caster, unit target returns boolean
return IsUnitEnemy(target, GetOwningPlayer(caster))/*
*/and not (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE))/*
*/and not (IsUnitType(target, UNIT_TYPE_DEAD))/*
*/and IsUnitVisible(target, GetOwningPlayer(caster))
endfunction
///////////////////////////////////////////////////////////////////////////////////////
//This is the end of the header //
//don't edit anything below if u don't know it. //
//I'll try to explain it as best as i can though //
///////////////////////////////////////////////////////////////////////////////////////
//the bear's struct
private struct Bear
//well, initialize the struct
private unit Caster
private unit Target
private unit bear
private real Dmg
private real Time
private effect sfx
private static Bear array Index
private static integer Total = 0
private static timer Timer = CreateTimer()
static method Loop takes nothing returns nothing
local Bear dat
local integer i = 0
//the usual looping every TimeOut set above.
loop
exitwhen i >= Bear.Total
set dat = Bear.Index[i]
set dat.Time = dat.Time - TimeOut
//move the bear so it maintains the distance set above. note that this will move it's instantly
set R[0] = GetUnitFacing(dat.bear)-180.
if R[0] < 0 then
set R[0] = R[0] + 360.
endif
set R[1] = GetUnitX(dat.Target)+(BearDist*Cos(R[0]*bj_DEGTORAD))
set R[2] = GetUnitY(dat.Target)+(BearDist*Sin(R[0]*bj_DEGTORAD))
call SetUnitX(dat.bear,R[1])
call SetUnitY(dat.bear,R[2])
//check wether the bear animation has ended
if dat.Time <= 0 then
//if it's anim is end, do the stuff
//damage the target
call UnitDamageTarget(dat.Caster,dat.Target,dat.Dmg,true,false,BearATT,BearDGT,BearWPT)
//create bear's damage effect on target's location
call DestroyEffect(AddSpecialEffect(BearDmgEffect,GetUnitX(dat.Target),GetUnitY(dat.Target)))
//destroy bear's attached effect
call DestroyEffect(dat.sfx)
//create bear's disappear effect
call DestroyEffect(AddSpecialEffect(BearDisappearEffect,GetUnitX(dat.bear),GetUnitY(dat.bear)))
//remove the bear from game. why not just kill it? for safety.
//this because the bear can also be a normal unit, which leave corpse, or have ability that triggered when dies, or other annoying thing
call RemoveUnit(dat.bear)
//nulling the handle variable
set dat.Caster = null
set dat.Target = null
set dat.bear = null
set dat.sfx = null
//destroy the struct instance and rellocate it so it's ready for the next instance
call dat.destroy()
set Bear.Total = Bear.Total - 1
set Bear.Index[i] = Bear.Index[Bear.Total]
//decrease the loop counter, so the instance that fill this place will get in loop too
set i = i - 1
endif
//increase the loop counter
set i = i+1
endloop
if Bear.Total == 0 then
//if there's no struct instance active anymore, it stop the timer
call PauseTimer(Bear.Timer)
endif
endmethod
static method Create takes unit u, unit t, real dmg returns nothing
//allocate the instance
local Bear dat = Bear.allocate()
//set the necessary variables
set dat.Caster = u
set dat.Target = t
set dat.Dmg = dmg
set dat.Time = BearAnimTime
//create bear on random angle and have distance to target unit as set on the header
set R[0] = GetRandomReal(0.,360.)
set R[1] = GetUnitX(dat.Target)+(BearDist*Cos(R[0]*bj_DEGTORAD))
set R[2] = GetUnitY(dat.Target)+(BearDist*Sin(R[0]*bj_DEGTORAD))
set R[3] = R[0] - 180.
if R[3] < 0. then
set R[3] = R[3]+360.
endif
set dat.bear = CreateUnit(GetOwningPlayer(u),BearUnit,R[1],R[2],R[3])
//add the invulnerable and locust ability to prevent killing and selecting the bear.
//that's t make the bear really an effect
call UnitAddAbility(dat.bear,'Avul')
call UnitAddAbility(dat.bear,'Aloc')
//this one remove the bear ability to attack normally
call UnitAddAbility(dat.bear,'Abun')
//play the bear's desired animation
call SetUnitAnimation(dat.bear,BearAnim)
//create the bear's appear effect
call DestroyEffect(AddSpecialEffect(BearAppearEffect,R[1],R[2]))
//create the attach effect to bear
set dat.sfx = AddSpecialEffectTarget(BearAttachEffect,dat.bear,BearAttach)
if Bear.Total == 0 then
//if there's no instance active before, active the timer
call TimerStart(Bear.Timer,TimeOut,true,function Bear.Loop)
endif
//allocate the instance to the right place
set Bear.Index[Bear.Total] = dat
set Bear.Total = Bear.Total + 1
endmethod
endstruct
//Bee's Struct
private struct Bee
//struct's list of variable
private unit bee
private unit Caster
private unit Target
private real Dist
private real angle
private real Time
private real time2
private real Dmg
private real Chance
private integer level
private integer Code
private integer ActID
private effect sfx
private effect sfx2
//array that save and share the interval of a group of bee attack
static real array Interval
private static Bee array Index
private static integer Total = 0
private static timer Timer = CreateTimer()
static method Finish takes unit t, integer c returns nothing
//method to destroy a group of bee by giving the code of which the bee attacking at.
local integer i = 0
local Bee dat
//search the right bee
loop
exitwhen i >= Bee.Total
set dat = Bee.Index[i]
//check if it's the right bee to end by check it's target and target's code
if (dat.Target == t) and (dat.Code == c) then
//destroy bee's model and bee's attached effect
call DestroyEffect(dat.sfx)
call DestroyEffect(dat.sfx2)
//create bee's disappear effect
call DestroyEffect(AddSpecialEffect(BeeDisappearEffect,GetUnitX(dat.bee),GetUnitY(dat.bee)))
//add timed life. it's more safer than instant kill
call UnitApplyTimedLife(dat.bee,'BTLF',TimeOut)
//nulling the handle
set dat.bee = null
set dat.Caster = null
set dat.Target = null
set dat.sfx = null
set dat.sfx2 = null
//destroy and relocate the instance
call dat.destroy()
set Bee.Total = Bee.Total - 1
set Bee.Index[i] = Bee.Index[Bee.Total]
set i = i - 1
endif
set i = i+1
endloop
if Bee.Total == 0 then
call PauseTimer(Bee.Timer)
endif
endmethod
static method Change takes unit t, integer from, integer to returns nothing
//method to change the unit code of a group of bee is attacking at.
local integer i = 0
local Bee dat
//search the right group of bee
loop
exitwhen i >= Bee.Total
set dat = Bee.Index[i]
//check if it's te right bee by check it's target and target's code
if (dat.Target == t) and (dat.Code == from) then
//change the target's code
set dat.Code = to
//move the shared interval of a group of bee
set Bee.Interval[to] = Bee.Interval[from]
endif
set i = i+1
endloop
endmethod
static method Loop takes nothing returns nothing
local integer i = 0
local Bee dat
//the usual looping
loop
exitwhen i >= Bee.Total
set dat = Bee.Index[i]
//always move the angle bee is currently circling
set dat.angle = dat.angle+((BeeMoveSpeed*TimeOut/dat.Dist)*bj_RADTODEG)
if dat.angle <= 0 then
set dat.angle = dat.angle+360.
endif
if dat.ActID == 0 then
//bee's 'circling' part
if dat.time2 > 0 then
//reducing the tk speed counter if bee is not yet ready to attack
set dat.time2 = dat.time2-TimeOut
endif
//move te bee in the right position of circle
call SetUnitX(dat.bee,GetUnitX(dat.Target)+(dat.Dist*Cos(dat.angle*bj_DEGTORAD)))
call SetUnitY(dat.bee,GetUnitY(dat.Target)+(dat.Dist*Sin(dat.angle*bj_DEGTORAD)))
call SetUnitFacing(dat.bee,dat.angle+90.)
if (dat.time2 <= 0) and (Bee.Interval[dat.Code] <= 0) then
//if bee is ready to attack the interval of group is free, the bee will switch to attack
//switch the action ID to 'moving to attack'
set dat.ActID = 1
//reset the bee cooldown time
set dat.time2 = dat.Time
//reset the shared interval time
set Bee.Interval[dat.Code] = BeeAtkInterval+(BeeAtkIntervalIncr*I2R(dat.level))
endif
elseif dat.ActID == 1 then
//bee's 'moving to attack part'
//move bee to target according to it's speed.
set R[0] = Atan2(GetUnitY(dat.Target)-GetUnitY(dat.bee),GetUnitX(dat.Target)-GetUnitX(dat.bee))
set R[1] = GetUnitX(dat.bee)+(BeeMoveSpeed*TimeOut*Cos(R[0]))
set R[2] = GetUnitY(dat.bee)+(BeeMoveSpeed*TimeOut*Sin(R[0]))
call SetUnitX(dat.bee,R[1])
call SetUnitY(dat.bee,R[2])
//check the distance between bee and the target
set R[3] = R[1] - GetUnitX(dat.Target)
set R[4] = R[2] - GetUnitY(dat.Target)
set R[5] = SquareRoot((R[3]*R[3])+(R[4]*R[4]))
if R[5] <= BeeCollision then
//if the distance is lower or equal to bee's collision,
//switch bee action ID to 'moving back to circling' part
set dat.ActID = 2
//damage the unit
call UnitDamageTarget(dat.Caster,dat.Target,dat.Dmg,true,false,BeeATT,BeeDGT,BeeWPT)
//create the bee damage effect
call DestroyEffect(AddSpecialEffect(BeeDmgEffect,GetUnitX(dat.Target),GetUnitY(dat.Target)))
if GetRandomReal(0.,100.) <= dat.Chance then
//check the chance to summon bear.
//if right, summon it with Bear.Create method
call Bear.Create(dat.Caster,dat.Target,BearDmg+(BearDmgIncr*I2R(dat.level)))
endif
endif
elseif dat.ActID == 2 then
//bee's 'moving back to circling'
//move bee to it's position in the circling according to it's speed
set R[6] = GetUnitX(dat.Target)+(dat.Dist*Cos(dat.angle*bj_DEGTORAD))
set R[7] = GetUnitY(dat.Target)+(dat.Dist*Sin(dat.angle*bj_DEGTORAD))
set R[0] = Atan2(R[7]-GetUnitY(dat.bee),R[6]-GetUnitX(dat.bee))
set R[1] = GetUnitX(dat.bee)+(BeeMoveSpeed*TimeOut*Cos(R[0]))
set R[2] = GetUnitY(dat.bee)+(BeeMoveSpeed*TimeOut*Sin(R[0]))
call SetUnitX(dat.bee,R[1])
call SetUnitY(dat.bee,R[2])
//check the distance between bee and it's circling position
set R[3] = R[1] - R[6]
set R[4] = R[2] - R[7]
set R[5] = SquareRoot((R[3]*R[3])+(R[4]*R[4]))
if R[5] <= BeeCollision then
//if it's lower or equal to it's collision, make it circling again
//change action ID to 'circling' part
set dat.ActID = 0
//instantly move the bee to it's exact position in circling's circle
call SetUnitX(dat.bee,R[6])
call SetUnitY(dat.bee,R[7])
call SetUnitFacing(dat.bee,dat.angle+90.)
endif
endif
set i = i+1
endloop
endmethod
static method Create takes unit c, unit u, integer i, integer lvl returns nothing
//method to allocate the instance and set the necessary variable
local Bee dat = Bee.allocate()
//set the necessary variable
set dat.Caster = c
set dat.Target = u
set dat.Code = i
set dat.ActID = 0
set dat.level = lvl
set dat.Dist = BeeDist+(BeeDistIncr*I2R(dat.level))
set dat.angle = GetRandomReal(0.,360.)
set dat.Time = BeeAtkSpeed+(BeeAtkSpeedIncr*I2R(dat.level))
set dat.time2 = dat.Time
set dat.Dmg = BeeDmg+(BeeDmgIncr*I2R(dat.level))
set dat.Chance = BearChance+(BearChanceIncr*I2R(dat.level))
//create the bee
set dat.bee = CreateUnit(GetOwningPlayer(dat.Caster),DummyID,GetUnitX(dat.Target)+(dat.Dist*Cos(dat.angle*bj_DEGTORAD)),GetUnitY(dat.Target)+(dat.Dist*Sin(dat.angle*bj_DEGTORAD)),dat.angle+90)
//attach the bee model to it
set dat.sfx = AddSpecialEffectTarget(BeeModel,dat.bee,DummyAttach)
//attach the attach effect to it
set dat.sfx2 = AddSpecialEffectTarget(BeeAttachEffect,dat.bee,DummyAttach)
//create the appear effect
call DestroyEffect(AddSpecialEffect(BeeAppearEffect,GetUnitX(dat.bee),GetUnitY(dat.bee)))
if Bee.Total == 0 then
//start the timer if there's no instance active before
call TimerStart(Bee.Timer,TimeOut,true,function Bee.Loop)
endif
//allocate the struct instance
set Bee.Index[Bee.Total] = dat
set Bee.Total = Bee.Total + 1
endmethod
endstruct
//slow struct. struct for the affected unit
private struct Slow
//the variable needed
private unit Caster
private unit Affected
private real Amount
private real time
private effect sfx
private integer Code
private static Slow array Index
private static integer Total = 0
private static timer Timer = CreateTimer()
static method Finish takes unit u, integer a returns nothing
//method to remove the effect on affected unit.
local integer i = 0
local Slow dat
loop
exitwhen i >= Slow.Total
set dat = Slow.Index[i]
//check if it's the right unit by checking the unit and the code
if (dat.Affected == u) and (dat.Code == a) then
//destroy the buff effect
call DestroyEffect(dat.sfx)
//reset the unit move speed
call SetUnitMoveSpeed(dat.Affected,GetUnitMoveSpeed(dat.Affected)+dat.Amount)
//remove the group of bee attacking the unit by calling Bee.Finish and giving the unit's code
call Bee.Finish(dat.Affected,i)
//nulling the handle
set dat.Caster = null
set dat.Affected = null
set dat.sfx = null
//destroy and rellocate the instance
call dat.destroy()
set Slow.Total = Slow.Total-1
set Slow.Index[i] = Slow.Index[Slow.Total]
call Bee.Change(Slow.Index[Slow.Total].Affected,Slow.Total,i)
set i = i-1
endif
set i = i+1
endloop
if Slow.Total == 0 then
//if there's no instance left, pause the timer
call PauseTimer(Slow.Timer)
endif
endmethod
static method Change takes unit u, integer from, integer to returns nothing
//method to change the code of affecte unit
local integer i = 0
local Slow dat
//search the right affected unit
loop
exitwhen i >= Slow.Total
set dat = Slow.Index[i]
//check if it's the right unit by check the unit and the code
if (dat.Affected == u) and (dat.Code == from) then
//change the code
set dat.Code = to
endif
set i = i+1
endloop
endmethod
static method Loop takes nothing returns nothing
local integer i = 0
//the usual looping
loop
exitwhen i >= Slow.Total
//reduce the group of bee shared interval
set Bee.Interval[i] = Bee.Interval[i]-TimeOut
set i = i+1
endloop
endmethod
static method Create takes unit c, unit u, real r, effect fx, integer i, integer lvl returns nothing
//allocate and create the effect for the unit
local Slow dat = Slow.allocate()
local integer s
//set the necessary variable
set dat.Caster = c
set dat.Affected = u
set dat.Amount = r
//reduce the unit move speed
call SetUnitMoveSpeed(u,GetUnitMoveSpeed(u)-dat.Amount)
//set the necessary variable again
set dat.sfx = fx
set dat.Code = i
//set the shared group of bee interval
set Bee.Interval[Slow.Total]=BeeAtkInterval+(BeeAtkIntervalIncr*I2R(lvl))
//create the desired bee amount
set s = BeeSum+(BeeSumIncr*lvl)
loop
exitwhen s <= 0
//create a bee via Bee.Create and pass the unit's code too
call Bee.Create(dat.Caster,dat.Affected,Slow.Total,lvl)
set s = s-1
endloop
if Slow.Total == 0 then
//if there's no instance active before, active the timer
call TimerStart(Slow.Timer,TimeOut,true,function Slow.Loop)
endif
//allocate the instance
set Slow.Index[Slow.Total] = dat
set Slow.Total = Slow.Total+1
endmethod
endstruct
//Honey struct.
private struct Honey
//list of needed variable
private unit Caster
private real CentralX
private real CentralY
private real Area
private real Time
private real Time2
private integer level
private unit sfxu
private effect sfx
private group Affected
private static Honey array Index
private static integer Total = 0
private static timer Timer = CreateTimer()
//function for the group filter
static method CanTargeted takes nothing returns boolean
return CanTarget(temp,GetFilterUnit())
endmethod
static method Loop takes nothing returns nothing
local Honey dat
local unit u
local integer i = 0
local integer j = 0
//the usual looping
loop
exitwhen i >= Honey.Total
set dat = Honey.Index[i]
//reduce the time counter for duration and secondary effect interval
set dat.Time = dat.Time-TimeOut
set dat.Time2 = dat.Time2-TimeOut
//pick all group in affected group
call GroupAddGroup(dat.Affected,g)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g,u)
//check the distance to central location
set R[0] = dat.CentralX - GetUnitX(u)
set R[1] = dat.CentralY - GetUnitY(u)
set R[2] = SquareRoot((R[0]*R[0])+(R[1]*R[1]))
if (R[2] > dat.Area) or not(CanTarget(dat.Caster,u)) then
//if the unit either out of the area or doesn't fulfill the 'can be targeted' condition,
//it'll removed from affected group and finish the effect on that unit
call GroupRemoveUnit(dat.Affected,u)
call Slow.Finish(u,i)
endif
endloop
//pick every unit in the area that fulfill the 'can be targeted' condition
set filter = Filter(function Honey.CanTargeted)
set temp = dat.Caster
call GroupEnumUnitsInRange(g,dat.CentralX,dat.CentralY,dat.Area,filter)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g,u)
//check if it's already affected by the spell
if not IsUnitInGroup(u,dat.Affected) then
//if yes, add it to affected group and create the effect on it
call GroupAddUnit(dat.Affected,u)
call Slow.Create(dat.Caster,u,GetUnitMoveSpeed(u)*(SlowAmount+(SlowIncr*I2R(dat.level))),AddSpecialEffectTarget(HoneyBuffEffect,u,BuffAttach),i,dat.level)
endif
endloop
set temp = null
call DestroyBoolExpr(filter)
//check wether the secondary effect interval has reached
if dat.Time2 <= 0 then
//reset the interval
set dat.Time2 = HoneyAreaSecondaryEffectInterval
//create the effect
set j = HoneyAreaSecondaryEffectSum
loop
exitwhen j == 0
//pick random location
set R[0] = GetRandomReal(0.,dat.Area)
set R[1] = GetRandomReal(0.,360.)
set R[2] = dat.CentralX+(R[0]*Cos(R[1]*bj_DEGTORAD))
set R[3] = dat.CentralY+(R[0]*Sin(R[1]*bj_DEGTORAD))
//create the effect
call DestroyEffect(AddSpecialEffect(HoneyAreaSecondaryEffect,R[2],R[3]))
set j = j-1
endloop
endif
//check wether the duration has ended
if dat.Time <= 0 then
//remove all unit from affected group and end the spell's effect via Slow.Finish
loop
set u = FirstOfGroup(dat.Affected)
exitwhen u == null
call GroupRemoveUnit(dat.Affected,u)
call Slow.Finish(u,i)
endloop
//create the spell's finished effect
call DestroyEffect(AddSpecialEffect(HoneyEndEffect,dat.CentralX,dat.CentralY))
//destroy the affected group
call DestroyGroup(dat.Affected)
//destroy the area effect
call DestroyEffect(dat.sfx)
//kill the dummy unit
call UnitApplyTimedLife(dat.sfxu,'BTLF',0.5)
//nulling handle variable
set dat.Affected = null
set dat.sfxu = null
set dat.Caster = null
set dat.sfx = null
//destroy and relocate struct instance
call dat.destroy()
set Honey.Total = Honey.Total - 1
set Honey.Index[i] = Honey.Index[Honey.Total]
//pick all moved struct's affected unt and change it's code
call GroupAddGroup(Honey.Index[Honey.Total].Affected,g)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g,u)
call Slow.Change(u,Honey.Total,i)
endloop
set i = i-1
endif
set i = i+1
endloop
if Honey.Total == 0 then
//if there's no instance active, pause the timer
call PauseTimer(Honey.Timer)
endif
set u = null
endmethod
static method Create takes nothing returns nothing
//the create method...
local Honey dat = Honey.allocate()
local unit u = GetTriggerUnit()
local unit u2
local integer i = HoneyAreaSecondaryEffectSum
//set the necessary variable
set dat.Caster = u
set dat.level = GetUnitAbilityLevel(u,SpellID) - 1
set dat.CentralX = GetSpellTargetX()
set dat.CentralY = GetSpellTargetY()
set dat.Time = Duration+(DurationIncr*I2R(dat.level))
set dat.Time2 = HoneyAreaSecondaryEffectInterval
set dat.Area = AoE+(AoEIncr*I2R(dat.level))
//create the area effect
//create dummy unit
set dat.sfxu = CreateUnit(GetOwningPlayer(u),DummyID,dat.CentralX,dat.CentralY,0.)
//create effect and attach to that dummy
set dat.sfx = AddSpecialEffectTarget(HoneyAreaEffect,dat.sfxu,DummyAttach)
//change the created area effect scale
call SetUnitScale(dat.sfxu,HoneyAreaEffectScale+(HoneyAreaEffectScaleIncr*I2R(dat.level)),0.,0.)
//create the secondary area effect
call DestroyEffect(AddSpecialEffect(HoneyStartEffect,dat.CentralX,dat.CentralY))
loop
exitwhen i == 0
set R[0] = GetRandomReal(0.,dat.Area)
set R[1] = GetRandomReal(0.,360.)
set R[2] = dat.CentralX+(R[0]*Cos(R[1]*bj_DEGTORAD))
set R[3] = dat.CentralY+(R[0]*Sin(R[1]*bj_DEGTORAD))
call DestroyEffect(AddSpecialEffect(HoneyAreaSecondaryEffect,R[2],R[3]))
set i = i-1
endloop
//pick all unit in spell's area that fulfill the 'can be targeted' condition
set dat.Affected = CreateGroup()
set filter = Filter(function Honey.CanTargeted)
set temp = u
call GroupEnumUnitsInRange(g,dat.CentralX,dat.CentralY,dat.Area,filter)
loop
set u2 = FirstOfGroup(g)
exitwhen u2 == null
call GroupRemoveUnit(g,u2)
//add it to affected group
call GroupAddUnit(dat.Affected,u2)
//create spell's effect on that unit
call Slow.Create(u,u2,GetUnitMoveSpeed(u2)*(SlowAmount+(SlowIncr*I2R(dat.level))),AddSpecialEffectTarget(HoneyBuffEffect,u2,BuffAttach),Honey.Total,dat.level)
endloop
set temp = null
call DestroyBoolExpr(filter)
if Honey.Total == 0 then
//if there's no instance before, start the timer
call TimerStart(Honey.Timer,TimeOut,true,function Honey.Loop)
endif
//allocate the struct instance
set Honey.Index[Honey.Total] = dat
set Honey.Total = Honey.Total+1
set u = null
set u2 = null
endmethod
endstruct
private function Conditions takes nothing returns boolean
if GetSpellAbilityId() == SpellID then
call Honey.Create()
endif
return false
endfunction
private function InitTrig_Initialize takes nothing returns nothing
//create the spell trigger
local trigger t = CreateTrigger()
//add the event to it
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
//add the 'condition' to that trigger
call TriggerAddCondition(t, Condition(function Conditions))
//preload the unit
call RemoveUnit(CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),BearUnit,0,0,0))
call RemoveUnit(CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),DummyID,0,0,0))
//preload all effect
call Preload(BeeModel)
call Preload(HoneyStartEffect)
call Preload(HoneyAreaEffect)
call Preload(HoneyAreaSecondaryEffect)
call Preload(HoneyBuffEffect)
call Preload(HoneyEndEffect)
call Preload(BeeAppearEffect)
call Preload(BeeAttachEffect)
call Preload(BeeDmgEffect)
call Preload(BeeDisappearEffect)
call Preload(BearAppearEffect)
call Preload(BearDmgEffect)
call Preload(BearAttachEffect)
call Preload(BearDisappearEffect)
endfunction
endscope
well, after 3 hours of trying almost all of the blood effect, I found out that it won't change the color even when the unit vertex coloring is changed...Have you tried attaching effects to a dummy model and giving the dummy-unit yellow vertex colouring? Some coloured blood effects would fit none too badly.
ok, I'll fix it in a minute. After I update my outdated jasshelper, I found out that this occur because recent update that allow u to use struct member without '.<member name>' or 'this.<member name>' anymore. it thinks that Bear i use there is a Bear member of that Bear struct, thus thinks that as an error. I'm gonna fix it by change the name of that member.Mage Goo,here's a screenshot of error
![]()
u can set the 'Corpse' ability Maximum Total damage to 0 rather than 99,999 to make it really don't have maximum total damage.Here you go, finished one!
There is chance that I forget something so I won't upload pictures and such things, if I find time and improve it even more I will upload last version once again, if not I will edit this post![]()
I believe it's has something to do with the unit'sCan you help me with a problem I found:
when I am casting the ability I create a dummy which casts web on a flying unit (not explainig exactly) and the timing is aaaaaaaawwwwwwwfuuuuuulll
the least time for the unit to cast the ability is: 45 sec
what should I do?
plz answer fast!!!!!!!!!!!!!!!!
Edit I hate the fact that I have only 14h left and I won't be able to spend them all!!!!!!!!!!!!!!!!!
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Moonwalk v1.0 by Maker
The caster is gain 100% Evade for short duration
and deals AOE at the end.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
scope Moonwalk initializer InitTrig_Moonwalk
globals
// Main ability ~ Moonwalk
private constant integer ABILID = 'A003'
// Spell book ~ Spell Book - Moonwalk
private constant integer BOOKID = 'A004'
// Dummy's raw code ~ Moonwalk Dummy
private constant integer DUMMYID = 'h000'
// The animation ondex of walk animation
// This is different for many units
private constant integer INDEX = 12
// How far the unit moonwalks
private constant real OFFSET = 250.
// How much the unit moves per loop
// Speedloop begins from 0 and goes to bj_PI
// When it is >= bj_PI, the unit has returned to the original pos
private constant real SPEEDLOOP = bj_PI/20.
// AoE of damage
private constant real AOE = 200.
// Base damage
private constant real DMGBASE = 40.
// Bonus damage per level, doesn't apply at lvl 1
private constant real DMGBONUS = 20.
// How often the loop than changes unit's position runs
private constant real TIMERLOOP = 0.03125
// How fast the animation speed plays
private constant real ANIMSPEED = 2.
// Is floating text shown
private constant boolean SHOWFLOAT = TRUE
private constant string array FLOATS
// How many different floating texts are defined
private constant integer FLOATAMOUNT = 2
// The size of the floating text
private constant real FLOATSIZE = 0.021
// Self explanatory
private constant attacktype ATK_TYPE = ATTACK_TYPE_NORMAL
private constant damagetype DMG_TYPE = DAMAGE_TYPE_NORMAL
// Order string of the buff applying ability
private constant string DUMMYBUFFORDER = "innerfire"
// Effect upon hit by AoE
private constant string EFFECTTARGET = "Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl"
// Effect to apply on caster for the duration of the dodging move
private constant string EFFECTCASTER = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"
// Effect to apply at caster's position when spell is cast
private constant string PREEFFECTCASTER = "Abilities\\Spells\\Items\\AIil\\AIilTarget.mdl"
// Attachment point for EFFECTTARGET
private constant string ETARGATT = "chest"
// Attachment point for EFFECTCASTER
private constant string ECASTATT = "origin"
/*~~~~~~~~~~~~~~~~~~~~~ Don't change these ~~~~~~~~~~~~~~~~~~~~~~*/
private real dmg
private unit caster
private player plr
private integer moonwalks = 0
private integer prewalks = 0
private integer actives = 0
private unit dummy
private hashtable hash = InitHashtable()
private group grp = CreateGroup()
private group Moonwalkers = CreateGroup()
private timer MoonwalkTimer = CreateTimer()
private group Prewalkers = CreateGroup()
private timer PreTimer = CreateTimer()
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
endglobals
// Here you can define the floating texts
private function SetFloats takes nothing returns nothing
set FLOATS[1] = "Can't touch this!"
set FLOATS[2] = "You can't see me!"
endfunction
/*~~~~~~~~~ DThese return child keys for hashtable actions ~~~~~~~*/
private function HashX takes nothing returns integer
return 1
endfunction
private function HashY takes nothing returns integer
return 2
endfunction
private function HashLoop takes nothing returns integer
return 3
endfunction
private function HashAngle takes nothing returns integer
return 4
endfunction
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// Damages units, filters out unwanted units
private function DamageFilter takes nothing returns boolean
local unit u = GetFilterUnit()
if GetWidgetLife(u) > 0.405 and /*
*/ IsUnitEnemy(u , plr) /*
*/ then
call DestroyEffect(AddSpecialEffectTarget(EFFECTTARGET , u , ETARGATT))
call UnitDamageTarget(caster , u , dmg , true , false , ATK_TYPE , DMG_TYPE , WEAPON_TYPE_WHOKNOWS)
endif
set u = null
return false
endfunction
private function LoopWalkers takes nothing returns nothing
local unit u = GetEnumUnit()
local integer id = GetHandleId(u)
local real r = LoadReal(hash , id , HashLoop())
local real angle = LoadReal(hash , id , HashAngle())
local real x = LoadReal(hash , id , HashX())
local real y = LoadReal(hash , id , HashY())
set r = r + SPEEDLOOP
if r < bj_PI and GetWidgetLife(u) > 0.405 then
call SetUnitX(u , x + OFFSET * Cos(angle) * Sin(r))
call SetUnitY(u , y + OFFSET * Sin(angle) * Sin(r))
call SaveReal(hash , id , HashLoop() , r)
call SetUnitVertexColor(u , 255 , 255 , 255 , R2I(255*r/bj_PI) )
else
call SetUnitX(u,x)
call SetUnitY(u,y)
call UnitRemoveAbility(u , BOOKID)
call SetUnitTimeScale(u , 1)
call SetUnitAnimation(u , "stand")
call SetUnitVertexColor(u , 255 , 255 , 255 , 255 )
call DestroyEffect(LoadEffectHandle(hash , id , StringHash("effect")))
set caster = u
set plr = GetOwningPlayer(u)
set dmg = LoadReal(hash , id , StringHash("damage"))
call GroupEnumUnitsInRange(grp , x , y , AOE , function DamageFilter)
call GroupClear(grp)
set moonwalks = moonwalks - 1
if moonwalks == 0 then
call PauseTimer(MoonwalkTimer)
endif
call GroupRemoveUnit(Moonwalkers , u)
endif
set u = null
endfunction
private function TimerExpire takes nothing returns nothing
call ForGroup(Moonwalkers , function LoopWalkers)
endfunction
private function CastActions takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer id = GetHandleId(u)
if SHOWFLOAT == TRUE then
set bj_lastCreatedTextTag = CreateTextTag()
call SetTextTagText(bj_lastCreatedTextTag , FLOATS[GetRandomInt(1,FLOATAMOUNT)] , FLOATSIZE)
call SetTextTagPosUnit(bj_lastCreatedTextTag , u , 0. )
// With this line one can modifu the floating text colour
//call SetTextTagColor(bj_lastCreatedTextTag , 255 , 255 , 255 , 255)
call SetTextTagVelocity( bj_lastCreatedTextTag , 0, 0.05 )
call SetTextTagPermanent( bj_lastCreatedTextTag , false )
call SetTextTagLifespan( bj_lastCreatedTextTag , 2.00 )
call SetTextTagFadepoint( bj_lastCreatedTextTag , 1.70 )
endif
call SaveReal(hash , id , HashAngle() , GetRandomReal(0,360))
call SaveReal(hash , id , HashLoop() , 0)
call SaveReal(hash , id , HashX() , GetUnitX(u))
call SaveReal(hash , id , HashY() , GetUnitY(u))
call SaveEffectHandle(hash , id , StringHash("effect") , AddSpecialEffectTarget(EFFECTCASTER , u , ECASTATT))
// Adds the evasion ability
call UnitAddAbility(u , BOOKID)
// Increases the animation speed
call SetUnitTimeScale(u , ANIMSPEED)
call SaveReal(hash , id , StringHash("damage") , DMGBASE + (GetUnitAbilityLevel(u , ABILID) - 1) * DMGBONUS)
call SetUnitX(dummy , GetUnitX(u))
call SetUnitY(dummy , GetUnitY(u))
call IssueTargetOrder(dummy , DUMMYBUFFORDER , u)
if moonwalks == 0 then
call TimerStart(MoonwalkTimer , TIMERLOOP , true , function TimerExpire)
endif
set moonwalks = moonwalks + 1
call GroupAddUnit(Moonwalkers , u)
set u = null
endfunction
/*~ The pre actions override the animation of the ability ~~*/
/*~ This allows me to play the walk animation already when ~*/
/*~ the spell is begun to cast. The actual actions take ~~~~*/
/*~ place when staring the effect of the ability ~~~~~~~~~~~*/
private function PreWalkerLoop takes nothing returns nothing
local unit u = GetEnumUnit()
set prewalks = prewalks - 1
call GroupRemoveUnit(Prewalkers , u)
call DestroyEffect(AddSpecialEffect(PREEFFECTCASTER, GetUnitX(u), GetUnitY(u)))
call SetUnitAnimationByIndex(u , INDEX)
set u = null
endfunction
private function PreTimerExpire takes nothing returns nothing
call ForGroup(Prewalkers , function PreWalkerLoop)
endfunction
private function BeginActions takes nothing returns nothing
if prewalks == 0 then
call TimerStart(PreTimer , 0. , false , function PreTimerExpire)
endif
set prewalks = prewalks + 1
call GroupAddUnit(Prewalkers , GetTriggerUnit())
endfunction
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
private function CastConditions takes nothing returns boolean
return GetSpellAbilityId() == ABILID and not(IsUnitInGroup(GetTriggerUnit() , Moonwalkers))
endfunction
private function InitTrig_Moonwalk takes nothing returns nothing
local trigger t1 = CreateTrigger()
local trigger t2 = CreateTrigger()
local integer i = 0
call TriggerAddCondition( t1 , Condition( function CastConditions ) )
call TriggerAddAction( t1 , function CastActions )
call TriggerAddCondition( t2 , Condition( function CastConditions ) )
call TriggerAddAction( t2 , function BeginActions )
loop
call TriggerRegisterPlayerUnitEvent(t1, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerRegisterPlayerUnitEvent(t2, Player(i), EVENT_PLAYER_UNIT_SPELL_CAST, null)
call SetPlayerAbilityAvailable(Player(i) , BOOKID , false)
exitwhen i == 15
set i = i + 1
endloop
set dummy = CreateUnit( Player(15) , DUMMYID , 0 , 0 , 0 )
call ShowUnit(dummy , false)
call SetFloats()
endfunction
endscope
//===========================================================================
// Chicken Burst spell
// by Garfield1337
//===========================================================================
scope ChickenBurst initializer Init
globals
private constant integer CHICKEN_ID = 'h001' //Raw code of chicken
private constant integer DUMMY_ID = 'h002' //Raw code of dummy
private constant integer EGG_ID = 'h000' //Raw code of egg
private constant integer ABILITY_ID = 'A000' //Raw code of ability
private constant real EGG_SPEED = 24.00 //Egg's flying speed
private constant real CHICKEN_SPEED = 4.00 //Chickens' flying speed
private constant real CHICKEN_HEIGHT = 600.0 //Chickens' max height when flying
private constant real CHICKEN_EXPLOSION_AOE = 160.0 //Radius of area which chickens damage
private constant real CHICKEN_RANGE_MIN = 150.0 //Minimum range chickens fly from egg
private constant real CHICKEN_RANGE_MAX = 350.0 //Maximum range chickens fly from egg
private constant string CHICKEN_EXPLOSION_SFX = "Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl" //Effect created upon chicken explosion
private constant boolean DAMAGE_ALLIED = false //Should the spell damage allied units?
private constant boolean DAMAGE_ENEMY = true //Should the spell damage enemy units?
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL //Explosion attack type
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL //Explosion damage type
private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS //Explosion weapon type
private constant boolean DESTROY_DESTRUCTABLES = false //Should the explosion destroy destructables?
private constant boolean TREES_ONLY = false //Should the explosion only affect trees as destructables?
//If DESTROY_DESTRUCTABLES is false,DESTRUCTABLE_DAMAGE can be set to a number greater than 0.00
//to damage destructables instead of instantly killing them
//If DESTROY_DESTRUCTABLES is false and DESTRUCTABLE_DAMAGE is 0.00 the spell will not affect any destructables
private constant real DESTRUCTABLE_DAMAGE = 40.0
endglobals
private keyword INVALID_TARGETS //Don't change this line
private function InvalidTargets takes nothing returns nothing
//Which unit types shouldn't be affected by spell
set INVALID_TARGETS[0] = UNIT_TYPE_FLYING
set INVALID_TARGETS[1] = UNIT_TYPE_STRUCTURE
set INVALID_TARGETS[2] = UNIT_TYPE_MAGIC_IMMUNE
endfunction
private function Damage takes integer lvl returns real
//Damage per explosion per level
return 50.0 + 20.0 * lvl
endfunction
private function ChickenAmount takes integer lvl returns integer
//Number of chickens per level
return 5 + 5 * lvl
endfunction
private function ChickenDuration takes nothing returns real
//Time before each chicken explodes
return GetRandomReal(1.00,2.00)
endfunction
//End of configuration part
//===========================================================================
globals
private hashtable Hash = InitHashtable()
private group g = CreateGroup()
private location l = Location(0.00,0.00)
private unittype array INVALID_TARGETS
private group EGGS = CreateGroup()
private group CHICKENS = CreateGroup()
private rect r
private unit t
private real r1
private real r2
private real r3
private real r4
private integer i1
private integer i2
private integer i3
private unit u1
private unit u2
private real x1
private real y1
private real x2
private real y2
endglobals
private function Parabola takes real y0, real y1, real h, real d, real x returns real
local real A = (2*(y0+y1)-4*h)/(d*d)
local real B = (y1-y0-A*d*d)/d //Credits to moyack for the parabola function
return A*x*x + B*x + y0
endfunction
private function Cast takes nothing returns boolean
if GetSpellAbilityId() == ABILITY_ID then
set x1 = GetUnitX(GetTriggerUnit())
set y1 = GetUnitY(GetTriggerUnit())
//Creating egg
set u1 = CreateUnit(GetOwningPlayer(GetTriggerUnit()),EGG_ID,x1,y1,GetRandomReal(0.00,360.0))
set x2 = GetSpellTargetX()
set y2 = GetSpellTargetY()
set i1 = GetHandleId(u1)
//Moving the egg on caster's position since it is created beside
call SetUnitX(u1,x1)
call SetUnitY(u1,y1)
//Enabling the egg to fly by adding and removing crow form
call UnitAddAbility(u1,'Amrf')
call UnitRemoveAbility(u1,'Amrf')
//Adding a slight height to egg so it doesn't fly off the ground
call SetUnitFlyHeight(u1,30.0,0.00)
//Saving angle between caster and target
set r1 = Atan2(y2 - y1,x2 - x1)
call SaveReal(Hash,i1,0,r1)
//To prevent the egg from hitting cliff while in air before reaching it's target
//i check height of terrain on egg's way and find the peak (if any)
//then later i add the peak's height to max height of parabola in loop
set r2 = 0
set r3 = SquareRoot(Pow(x2 - x1,2) + Pow(y2 - y1,2))
set r4 = 0
loop
call MoveLocation(l,x1 + r2 * Cos(r1),y1 + r2 * Sin(r1))
if r2 == 0 then
//Saving caster's height for parabola
call SaveReal(Hash,i1,1,GetLocationZ(l) + 30.0)
elseif r2 >= r3 then
//Saving target's height for parabola
call SaveReal(Hash,i1,2,GetLocationZ(l))
exitwhen true
endif
if GetLocationZ(l) > r4 then
set r4 = GetLocationZ(l)
endif
set r2 = r2 + 32.0
endloop
//Saving peak's height
call SaveReal(Hash,i1,3,r4)
//Saving total distance
call SaveReal(Hash,i1,4,r3)
//Saving passed distance which is 0
call SaveReal(Hash,i1,5,0.00)
//Saving spell level
call SaveInteger(Hash,i1,6,GetUnitAbilityLevel(GetTriggerUnit(),ABILITY_ID))
//Saving a custom integer which will be used in loop
call SaveInteger(Hash,i1,7,0)
call GroupAddUnit(EGGS,u1)
endif
return false
endfunction
private function Loop1 takes nothing returns nothing
//Egg loop
set u1 = GetEnumUnit()
set i1 = GetHandleId(u1)
set i2 = LoadInteger(Hash,i1,7)
set i3 = 0
if i2 == 0 then //At first, the egg is just flying
//Egg movement
set x1 = GetUnitX(u1) + EGG_SPEED * Cos(LoadReal(Hash,i1,0))
set y1 = GetUnitY(u1) + EGG_SPEED * Sin(LoadReal(Hash,i1,0))
call SetUnitX(u1,x1)
call SetUnitY(u1,y1)
call SaveReal(Hash,i1,5,LoadReal(Hash,i1,5) + EGG_SPEED)
call MoveLocation(l,x1,y1)
//Setting egg's flying height with parabola
call SetUnitFlyHeight(u1,Parabola(LoadReal(Hash,i1,1),LoadReal(Hash,i1,2),LoadReal(Hash,i1,4) / 3 + LoadReal(Hash,i1,3),LoadReal(Hash,i1,4),LoadReal(Hash,i1,5)) - GetLocationZ(l),0.00)
if LoadReal(Hash,i1,5) >= LoadReal(Hash,i1,4) then
//Playing egg's birth animation to make it look as if it jumped off the ground
call SetUnitAnimation(u1,"birth")
//If the egg hits ground,the custom integer is set to 1 to prevent egg from moving anymore
call SaveInteger(Hash,i1,7,1)
endif
else
set x1 = GetUnitX(u1)
set y1 = GetUnitY(u1)
//The custom integer is now used as a counter to simulate wait function
call SaveInteger(Hash,i1,7,i2 + 1)
if i2 == 20 then //Upon reaching 20 the egg explodes...
set u2 = CreateUnit(GetOwningPlayer(u1),DUMMY_ID,x1,y1,GetRandomReal(0.00,360.0))
call SetUnitX(u2,x1)
call SetUnitY(u2,y1)
//Mine's death spell animation is used as a small explosion for egg
call SetUnitAnimation(u2,"death spell")
call UnitApplyTimedLife(u2,'BTLF',2.00)
elseif i2 == 25 then //...and after a short delay,chickens burst
loop
set i3 = i3 + 1
//Creating chickens until it hits wanted amount
exitwhen i3 > ChickenAmount(LoadInteger(Hash,i1,6))
//Defining the facing angle of each chicken to make them form a circle
set r1 = 6.28318 / ChickenAmount(LoadInteger(Hash,i1,6)) * (i3 - 1) + GetRandomReal(0.00,6.28318 / ChickenAmount(LoadInteger(Hash,i1,6)))
set u2 = CreateUnit(GetOwningPlayer(u1),CHICKEN_ID,x1,y1,r1 * bj_RADTODEG)
call SetUnitX(u2,x1)
call SetUnitY(u2,y1)
set i2 = GetHandleId(u2)
//Enabling the chickens to fly
call UnitAddAbility(u2,'Amrf')
call UnitRemoveAbility(u2,'Amrf')
//Defining the coordinates for each chicken to fall on
set x2 = x1 + GetRandomReal(CHICKEN_RANGE_MIN,CHICKEN_RANGE_MAX) * Cos(r1)
set y2 = y1 + GetRandomReal(CHICKEN_RANGE_MIN,CHICKEN_RANGE_MAX) * Sin(r1)
//Saving the egg's height for parabola
call MoveLocation(l,x1,y1)
call SaveReal(Hash,i2,0,GetLocationZ(l))
//Saving target coordinates' height
call MoveLocation(l,x2,y2)
call SaveReal(Hash,i2,1,GetLocationZ(l))
//Saving total distance
call SaveReal(Hash,i2,2,SquareRoot(Pow(x2 - x1,2) + Pow(y2 - y1,2)))
//Saving passed distance
call SaveReal(Hash,i2,3,0.00)
//Saving spell level, inherited from the egg
call SaveInteger(Hash,i2,4,LoadInteger(Hash,i1,6))
call GroupAddUnit(CHICKENS,u2)
endloop
//After chickens are created, the egg is destroyed
call KillUnit(u1)
call GroupRemoveUnit(EGGS,u1)
call FlushChildHashtable(Hash,i1)
endif
endif
endfunction
private function Loop2 takes nothing returns nothing
//Chicken loop
set u1 = GetEnumUnit()
set i1 = GetHandleId(u1)
//Chicken movement
set x1 = GetUnitX(u1) + CHICKEN_SPEED * Cos(GetUnitFacing(u1) * bj_DEGTORAD)
set y1 = GetUnitY(u1) + CHICKEN_SPEED * Sin(GetUnitFacing(u1) * bj_DEGTORAD)
call SetUnitX(u1,x1)
call SetUnitY(u1,y1)
call MoveLocation(l,x1,y1)
call SaveReal(Hash,i1,3,LoadReal(Hash,i1,3) + CHICKEN_SPEED)
//Setting chickens' flying height with parabola
call SetUnitFlyHeight(u1,Parabola(LoadReal(Hash,i1,0),LoadReal(Hash,i1,1),CHICKEN_HEIGHT + RMaxBJ(LoadReal(Hash,i1,0),LoadReal(Hash,i1,1)),LoadReal(Hash,i1,2),LoadReal(Hash,i1,3)) - GetLocationZ(l),0.00)
if LoadReal(Hash,i1,3) >= LoadReal(Hash,i1,2) then
//Upon hitting ground,each chicken is ordered to move to a random point
//The distance is defined by chickens' movement speed and time before they explode
set r1 = ChickenDuration()
set r2 = GetUnitMoveSpeed(u1) * r1 * 3
set x1 = GetUnitX(u1) + r2 * Cos(GetRandomReal(0.00,6.28318))
set y1 = GetUnitY(u1) + r2 * Sin(GetRandomReal(0.00,6.28318))
call IssuePointOrder(u1,"smart",x1,y1)
//Applying timed life to chickens to make them explode after the set time
call UnitApplyTimedLife(u1,'BTLF',r1)
call GroupRemoveUnit(CHICKENS,u1)
endif
endfunction
private function LoopInit takes nothing returns nothing
call ForGroup(EGGS,function Loop1)
call ForGroup(CHICKENS,function Loop2)
endfunction
private function ExplosionFilter takes nothing returns boolean
//Explosion's filter
local boolean b = true
set i1 = 0
set u1 = GetTriggerUnit()
set u2 = GetFilterUnit()
//Checking whether filter unit is enemy or ally
//whether the corresponding booleans are true or false
//and whether the filter unit is alive
if ((DAMAGE_ENEMY == true and IsUnitEnemy(u2,GetOwningPlayer(u1))) or (DAMAGE_ALLIED == true and IsUnitAlly(u2,GetOwningPlayer(u1)))) and IsUnitType(u2, UNIT_TYPE_DEAD) == false then
loop
//Looping through all invalid target types
//If the filter unit belongs to any,it's invalid
exitwhen INVALID_TARGETS[i1] == null
if IsUnitType(u2,INVALID_TARGETS[i1]) then
set b = false
endif
set i1 = i1 + 1
endloop
if b then
//If the filter unit passes all checks, it's damaged
call UnitDamageTarget(u1,u2,Damage(LoadInteger(Hash,GetHandleId(u1),4)),true,false,ATTACK_TYPE,DAMAGE_TYPE,WEAPON_TYPE)
endif
endif
return false
endfunction
private function DestructableEnum takes nothing returns nothing
local destructable d = GetFilterDestructable()
//Checking destructable life and filtering out dead ones
if GetDestructableLife(d) > 0 then
set x1 = GetDestructableX(d)
set y1 = GetDestructableY(d)
//If only trees should be damaged or destroyed, a tree-check is applied
if TREES_ONLY then
call IssueTargetOrder(t,"harvest",d)
if not(GetUnitCurrentOrder(t) == OrderId("harvest")) then
//In case destructable is not a tree, the function ends
call IssueImmediateOrder(t,"stop")
return
endif
call IssueImmediateOrder(t,"stop")
endif
if DESTROY_DESTRUCTABLES then
//Destroying destructable if the configurable boolean is true...
call KillDestructable(d)
else
//...if not, it's damaged instead
if DESTRUCTABLE_DAMAGE < GetDestructableLife(d) then
call SetDestructableAnimation(d,"stand hit")
endif
call SetDestructableLife(d,GetDestructableLife(d) - DESTRUCTABLE_DAMAGE)
endif
endif
set d = null
endfunction
private function Death takes nothing returns boolean
set u1 = GetTriggerUnit()
set x1 = GetUnitX(u1)
set y1 = GetUnitY(u1)
if GetUnitTypeId(u1) == CHICKEN_ID then
//When a chicken dies, it creates the SFX and enumerates
//the surrounding units and destructables for damage
call DestroyEffect(AddSpecialEffect(CHICKEN_EXPLOSION_SFX,GetUnitX(u1),GetUnitY(u1)))
call GroupEnumUnitsInRange(g,x1,y1,CHICKEN_EXPLOSION_AOE,Filter(function ExplosionFilter))
//Checking if destructable annihilation or damage is ON
if DESTROY_DESTRUCTABLES or DESTRUCTABLE_DAMAGE != 0.00 then
call MoveRectTo(r,x1,y1)
call EnumDestructablesInRect(r,null,function DestructableEnum)
endif
call FlushChildHashtable(Hash,GetHandleId(u1))
elseif GetUnitTypeId(u1) == DUMMY_ID then
//When a dummy dies,it's instantly removed to hide the dying animation
call RemoveUnit(u1)
endif
return false
endfunction
private function Init takes nothing returns nothing
local trigger t1 = CreateTrigger()
local trigger t2 = CreateTrigger()
call InvalidTargets()
set t = CreateUnit(Player(15),DUMMY_ID,0.00,0.00,0.00)
call ShowUnit(t,false)
set r = Rect(-CHICKEN_EXPLOSION_AOE,-CHICKEN_EXPLOSION_AOE,CHICKEN_EXPLOSION_AOE,CHICKEN_EXPLOSION_AOE)
set i1 = 0
loop
call TriggerRegisterPlayerUnitEvent(t1,Player(i1),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
call TriggerRegisterPlayerUnitEvent(t2,Player(i1),EVENT_PLAYER_UNIT_DEATH,null)
set i1 = i1 + 1
exitwhen i1 == 16
endloop
call TriggerAddCondition(t1,Condition(function Cast))
call TriggerAddCondition(t2,Condition(function Death))
call TimerStart(CreateTimer(),0.03,true,function LoopInit)
set t1 = null
set t2 = null
endfunction
endscope
^I think you should get rid of all that RADTODEG and DEGTORAD nonsense and use radians all the way. Also store the handleid in a variable so you don't have to call GetHandleId repeatedly![]()
use trigger tagscan tell me how to post triggers here???
this one still wip?This is the latest wip!
this one still wip?
we still can edit it before u review it?I am doing judging today. Late entries cannot be accepted, edited entries, well, if you edit it after I've reviewed it it's too late.
lol at the don't abuse part.Can you edit it before I review it? I don't deeply value strict policy or punctuality, but let's just say on the record, "no", but off the record, ignorance is bliss. Just don't abuse it.
is it just me or the reputation gem really are turned into cookies?