Alright so I am currently making a system that my map's spells will be based on and am looking for criticism on it. It contains dummy recycling and functions, custom projectiles (can be stopped in place by a heroes shield and then continue on when no longer blocked), a over-time system etc. etc.
Basically whatever any of you have time to look over and can give me feedback on how to optimize would be great.
Map updated to v3.1!
Code attached!
Basically whatever any of you have time to look over and can give me feedback on how to optimize would be great.
Map updated to v3.1!
Code attached!
JASS:
library CWmain initializer init
globals
constant integer FREEZE = 'A005'
unit Unit
group Group = CreateGroup() //Global juggle group
real X //Global juggle X coord (real)
real Y //Global juggle Y coord (real)
real Real //Global juggle real
real array FreezeAoe
endglobals
//
//==============================FILTERS
//
//Filter 1 - Allows enemy ground units and air units.
function Filter1 takes nothing returns boolean
return (IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(Unit)) == true)
endfunction
//Filter 2 - Allows missile freezers.
function Filter2 takes nothing returns boolean
if GetUnitAbilityLevel(GetFilterUnit(),FREEZE) == 1 and IsUnitInRangeXY(GetFilterUnit(), X,Y,Real) == true then
return true
else
return false
endif
endfunction
//
//==============================CALLBACKSS
//
//Callback 1 - Removes nonenemy non freezers or to far away units.
function Callback1 takes nothing returns nothing
if GetUnitAbilityLevel(GetEnumUnit(),FREEZE) == 0 or IsUnitInRangeXY(GetEnumUnit(), X,Y,FreezeAoe[GetUnitAbilityLevel(GetEnumUnit(),'A005')]) == false then
call GroupRemoveUnit(Group,GetEnumUnit())
endif
endfunction
//Callback 2 - Damages unit
function Callback2 takes nothing returns nothing
call UnitDamageTarget(Unit,GetEnumUnit(),Real,false,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNIVERSAL,WEAPON_TYPE_WHOKNOWS)
endfunction
//
//==============================INIT
//
private function init takes nothing returns nothing
set FreezeAoe[1] = 190
endfunction
endlibrary
JASS:
library CWdummy
globals
real GRAVEX = 3000
real GRAVEY = 2750
integer DIT = 0
integer DAT = 0
integer DT = 0
unit array DI
unit array DA
Dummy array DUMS
endglobals
struct Dummy
effect de
unit d
method onDestroy takes nothing returns nothing
call DestroyEffect(.de)
call SetUnitX(.d,GRAVEX)
call SetUnitY(.d,GRAVEY)
endmethod
endstruct
function CDummy takes player p, real x, real y, string e returns unit
local Dummy d
local unit u
local integer i = 0
if DI[0] == null then
set d = Dummy.create()
set DA[DAT] = CreateUnit(p,'h000',x,y,0)
set d.d = DA[DAT]
set u = DA[DAT]
call SetUnitX(u,x)
call SetUnitY(u,y)
set d.de = AddSpecialEffectTarget(e,u,"origin")
set DAT = DAT + 1
else
set d = Dummy.create()
set u = DI[0]
set d.d = u
set d.de = AddSpecialEffectTarget(e,u,"origin")
call SetUnitOwner(u,p, true)
call SetUnitX(u,x)
call SetUnitY(u,y)
loop
exitwhen i >= DIT
set DI[i] = DI[i+1]
set i = i + 1
endloop
set DIT = DIT - 1
endif
set DUMS[DT] = d
set DT = DT + 1
call ShowUnit(u,true)
return u
endfunction
function SetDummyHomingTarget takes unit u, unit target returns nothing
call SetUnitLookAt(u, "Bone_Head", target, 0., 0., 0.)
endfunction
function ClearDummy takes unit u returns nothing
local integer i = 0
local Dummy d
loop
exitwhen i >= DT
if DUMS[i].d == u then
set d = DUMS[i]
set DUMS[i] = DUMS[DT-1]
set DT = DT - 1
call d.destroy()
endif
set i = i + 1
endloop
endfunction
function RecDummy takes unit u returns nothing
local integer i = 0
set DI[DIT] = u
call SetUnitFlyHeight(u,50,0.)
loop
exitwhen i >= DAT
if DA[i] == u then
loop
exitwhen i >= DAT
set DA[i] = DA[i+1]
set i = i + 1
endloop
set DAT = DAT - 1
endif
set i = i + 1
endloop
set DIT = DIT + 1
call ClearDummy(u)
endfunction
function Cast takes unit c, integer ID, unit t, string str, integer l returns nothing
local unit u = CDummy(GetOwningPlayer(c), GetUnitX(t),GetUnitY(t),"")
call UnitAddAbility(u,ID)
call SetUnitAbilityLevel(u,ID,l)
call IssueTargetOrder(u,str,t)
call RecDummy(u)
endfunction
endlibrary
JASS:
library CWovertime initializer Init requires CWstatlib
globals
private Xot array XOTS
private integer total = 0
private real LowestInterval = .01
endglobals
function CreateXot takes unit Caster, unit Target, real Amnt, real Interval, real Dur, string SpecEfec, string AttachPoint, attacktype AttackType, real Angle,string Flag, boolean Stacks,integer X, integer Level returns nothing
local Xot xot
local integer i = 0
local boolean cont = true
loop
exitwhen i >= total or cont == false
set xot = XOTS[i]
if xot.Target == Target then
if Flag == Flag then
if Stacks then
set xot = Xot.create()
set xot.Target = Target
set xot.Caster = Caster
set xot.Amnt = Amnt
set xot.Interval = Interval
set xot.Dur = Dur
set xot.SpecEfec = SpecEfec
set xot.AttachPoint = AttachPoint
set xot.Flag = Flag
set xot.Angle = Angle
set xot.X = X
set xot.Level = Level
set XOTS[total] = xot
if total == 0 then
call TimerStart(Xot.Tim, LowestInterval, true, function Xot.Loop)
endif
set total = total + 1
set cont = false
else
set xot.Target = Target
set xot.Caster = Caster
set xot.Amnt = Amnt
set xot.Interval = Interval
set xot.Dur = Dur
set xot.SpecEfec = SpecEfec
set xot.AttachPoint = AttachPoint
set xot.Flag = Flag
set xot.Angle = Angle
set xot.X = X
set xot.Level = Level
set cont = false
endif
endif
endif
set i = i + 1
endloop
if cont then
set xot = Xot.create()
set xot.Target = Target
set xot.Caster = Caster
set xot.Amnt = Amnt
set xot.Interval = Interval
set xot.Dur = Dur
set xot.SpecEfec = SpecEfec
set xot.AttachPoint = AttachPoint
set xot.Flag = Flag
set xot.Angle = Angle
set xot.X = X
set xot.Level = Level
set XOTS[total] = xot
if total == 0 then
call TimerStart(Xot.Tim, LowestInterval, true, function Xot.Loop)
endif
set total = total + 1
endif
endfunction
struct Xot
unit Target
integer X
unit Caster
real Amnt
real Interval
real Dur
real CurrentWait = 0
real Angle
string SpecEfec
string AttachPoint
string Flag
attacktype AttackType
boolean Stacks
integer Level
static timer Tim = null
static method Loop takes nothing returns nothing
local Xot xot
local integer i = 0
local real angle
loop
exitwhen i >= total
set xot = XOTS[i]
if GetWidgetLife(xot.Target) >= 0 then
set xot.Dur = xot.Dur-LowestInterval
set xot.CurrentWait = xot.CurrentWait+LowestInterval
if xot.Dur >=0 then //Main loop
if xot.CurrentWait >= xot.Interval then
if xot.X == 1 then //Generic Damage (with effect)
call UnitDamageTarget(xot.Caster, xot.Target, xot.Amnt, false, false, xot.AttackType, DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
call DestroyEffect(AddSpecialEffectTarget(xot.SpecEfec, xot.Target, xot.AttachPoint))
endif
if xot.X == 2 then //Generic Heal (with effect)
call SetWidgetLife(xot.Target,GetWidgetLife(xot.Target)+xot.Amnt)
call DestroyEffect(AddSpecialEffectTarget(xot.SpecEfec, xot.Target, xot.AttachPoint))
endif
if xot.X == 3 then //Effectively a wait
endif
set xot.CurrentWait = 0
if xot.X == 4 then //Straddle unit with dummy
call SetUnitX(xot.Caster,GetUnitX(xot.Target))
call SetUnitY(xot.Caster,GetUnitY(xot.Target))
endif
endif
else //Last tick then destruction
if xot.X == 1 then //Generic Damage (with effect)
call UnitDamageTarget(xot.Caster, xot.Target, xot.Amnt, false, false, xot.AttackType, DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
call DestroyEffect(AddSpecialEffectTarget(xot.SpecEfec, xot.Target, xot.AttachPoint))
endif
if xot.X == 2 then //Generic Heal (with effect)
call SetWidgetLife(xot.Target,GetWidgetLife(xot.Target)+xot.Amnt)
call DestroyEffect(AddSpecialEffectTarget(xot.SpecEfec, xot.Target, xot.AttachPoint))
endif
if xot.X == 3 then //Specific spell, cast after wait.
call Cast(xot.Caster, 'A002', xot.Target, "entanglingroots", xot.Level)
call CreateXot(xot.Caster,xot.Target,((100*xot.Level)/((1+.5*xot.Level)/.5))+GetStat(xot.Caster,"SP")/(4-xot.Level),.5,(1+.5*xot.Level),"","chest",ATTACK_TYPE_MAGIC,0,"Germ",true,1,xot.Level)
endif
if xot.X == 4 then //Straddle unit with dummy, recycle
call SetUnitX(xot.Caster,GetUnitX(xot.Target))
call SetUnitY(xot.Caster,GetUnitY(xot.Target))
call RecDummy(xot.Caster)
endif
set XOTS[i] = XOTS[total-1]
set total = total - 1
call xot.destroy()
endif
else
set XOTS[i] = XOTS[total-1]
set total = total - 1
call xot.destroy()
endif
set i = i + 1
endloop
if total == 0 then
call PauseTimer(xot.Tim)
endif
endmethod
method onDestroy takes nothing returns nothing
set this.Target = null
set this.Caster = null
set this.Amnt = 0
set this.Interval = 0
set this.Dur = 0
set this.CurrentWait = 0
set this.SpecEfec = ""
set this.AttachPoint = ""
set this.Flag = ""
set this.AttackType = null
set this.Angle = 0
set this.Level = 0
endmethod
endstruct
function RemoveXot takes unit u returns nothing
local integer i = 0
local Xot xot
loop
exitwhen i >= total
if XOTS[i].Target == u then
set xot = XOTS[i]
set XOTS[i] = XOTS[total-1]
set total = total - 1
call xot.destroy()
endif
set i = i + 1
endloop
endfunction
function IsUnitAffectedBy takes unit u, string flag returns boolean
local integer i = 0
local Xot xot
loop
exitwhen i >= total
if XOTS[i].Target == u then
set xot = XOTS[i]
if xot.Flag == flag then
return true
endif
endif
set i = i + 1
endloop
return false
endfunction
private function Init takes nothing returns nothing
set Xot.Tim = CreateTimer()
endfunction
endlibrary
JASS:
library CWonhit requires CWovertime
function Hit takes unit t, unit c, integer i, integer l, real dmg, real aoerng, integer abil, string orderID returns nothing
local group g = CreateGroup()
//Event ID 1 - Spell > Specific > Germinate: Slows the target and starts the 5(4,3) second countdown for the spell effects.
if i == 1 then
call Cast(c, 'A001', t, "slow", l)
call CreateXot(c,t,0,1,6-1*l,"","",ATTACK_TYPE_MAGIC,0,"GermWait",true,3,l)
endif
//Event ID 2 - Spell > Generic: Causes the projectile to deal damage.
if i == 2 then
if aoerng > 0 then
set Unit = c
set Real = dmg
call GroupEnumUnitsInRange(g,GetUnitX(t),GetUnitY(t),aoerng, Condition(function Filter1))
call ForGroup(g,function Callback2)
else
call UnitDamageTarget(c,t,dmg,false,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNIVERSAL,WEAPON_TYPE_WHOKNOWS)
endif
endif
if i == 3 then
call Cast(c, abil, t, orderID, l)
endif
endfunction
endlibrary
JASS:
library CWprojectile initializer Init requires CWmain CWonhit
//==============================================================================================================================
globals
private projectile array PROS
private integer total = 0
private real Interval = .03
endglobals
//==============================================================================================================================
struct projectile
unit m //Missile
unit c //Caster
string mdl //Model String
unit t //Target
real sp //Speed
integer ID //Event Id
real d //Distance Between m and t
integer Level //Level
real dmg //Damage done
real aoe //Aoe
integer abil //Ability ID
string orderID //Order ID
static timer Tim = null
method onDestroy takes nothing returns nothing
call RecDummy(.m)
set .m = null
set .t = null
set .mdl = null
endmethod
static method Loop takes nothing returns nothing
local projectile p
local integer i = 0
local integer i2 = 0
local real difference
local real ABP
local real z1
local real z2
loop
exitwhen i >= total
set p = PROS[i]
if GetWidgetLife(p.t) <= 0 then
call DestroyEffect(AddSpecialEffectTarget(p.mdl,p.t,"origin"))
call p.destroy()
set total = total - 1
set PROS[i] = PROS[total]
else
set i2 = 0
set X = GetUnitX(p.m)
set Y = GetUnitY(p.m)
call GroupClear(Group)
loop
exitwhen i2 == DAT
call GroupAddUnit(Group,DA[i2])
set i2 = i2 + 1
endloop
call ForGroup(Group,function Callback1)
if CountUnitsInGroup(Group) <= 0 then
set ABP = Atan2(GetUnitY(p.t) - GetUnitY(p.m), GetUnitX(p.t) - GetUnitX(p.m))
set p.d = DistanceBetweenPoints(Location(GetUnitX(p.m),GetUnitY(p.m)),Location(GetUnitX(p.t),GetUnitY(p.t)))
if p.d < p.sp+1 then
call SetUnitX(p.m, GetUnitX(p.t))
call SetUnitY(p.m, GetUnitY(p.t))
set p.d = 0
else
call SetUnitX(p.m, GetUnitX(p.m) + p.sp * Cos(ABP))
call SetUnitY(p.m, GetUnitY(p.m) + p.sp * Sin(ABP))
set p.d = p.d - p.sp
endif
set z1 = GetUnitFlyHeight(p.m) + GetLocationZ(Location(GetUnitX(p.m),GetUnitY(p.m)))
set z2 = GetUnitFlyHeight(p.t) + GetLocationZ(Location(GetUnitX(p.t),GetUnitY(p.t)))
if (z1 > z2) then
if z1 - p.sp < z2 then
call SetUnitFlyHeight(p.m,z2,0.)
else
call SetUnitFlyHeight(p.m,GetUnitFlyHeight(p.m) - p.sp,0.)
endif
elseif (z2 > z1) then
if z1 + p.sp > z2 then
call SetUnitFlyHeight(p.m,z2,0.)
else
call SetUnitFlyHeight(p.m,GetUnitFlyHeight(p.m) + p.sp,0.)
endif
endif
if GetUnitFlyHeight(p.m) < 50 then
call SetUnitFlyHeight(p.m,50,0.)
endif
if (p.d <= 10.00 or p.d <= p.sp+1) then
if (z1 == z2 or z1 == z2 + 50) and z1 == 99199 then
call Hit(p.t, p.c, p.ID, p.Level, p.dmg, p.aoe,p.abil,p.orderID)
call DestroyEffect(AddSpecialEffectTarget(p.mdl,p.t,"origin"))
call p.destroy()
set total = total - 1
set PROS[i] = PROS[total]
endif
endif
endif
set i = i + 1
endif
endloop
if total == 0 then
call PauseTimer(p.Tim)
endif
endmethod
endstruct
//==============================================================================================================================
function CreateP takes unit caster, string mdl, real scale, unit target, real speed, integer EffectID, integer Level, real dmg, real aoe, integer abil, string orderID returns nothing
local projectile p
set p = projectile.create()
set p.m = CDummy(GetOwningPlayer(caster), GetUnitX(caster),GetUnitY(caster),mdl)
set p.t = target
set p.mdl = mdl
set p.c = caster
set p.sp = speed
set p.aoe = aoe
set p.ID = EffectID
set p.Level = Level
set p.dmg = dmg
set p.abil = abil
set p.orderID = orderID
call SetUnitScale(p.m, scale * 0.01, scale * 0.01, scale * 0.01)
call SetDummyHomingTarget(p.m, target)
set PROS[total] = p
if total == 0 then
call TimerStart(projectile.Tim, Interval, true, function projectile.Loop)
endif
set total = total + 1
endfunction
//==============================================================================================================================
function KillP takes unit u returns nothing
local integer i = 0
local projectile p
loop
exitwhen i >= total
if PROS[i].m == u then
set p = PROS[i]
set total = total - 1
set PROS[i] = PROS[total]
call p.destroy()
endif
set i = i + 1
endloop
endfunction
function Init takes nothing returns nothing
set projectile.Tim = CreateTimer()
endfunction
endlibrary
Attachments
Last edited: