- Joined
- Oct 18, 2007
- Messages
- 930
Ok im working on my new spell now and i implemented some H2I codes for checking if the unit has the "orbs" around it or not.
If cast twice it works flawless by replacing the old ones.
But if i let the time run out and let them be destroyed in the MotionLoop the game fucks up and i get the "Dubble Free!" message spammed on my face... Any ideas`??
And YES i know what Dubble Free! is
Code:
Map:
If cast twice it works flawless by replacing the old ones.
But if i let the time run out and let them be destroyed in the MotionLoop the game fucks up and i get the "Dubble Free!" message spammed on my face... Any ideas`??
And YES i know what Dubble Free! is
Code:
JASS:
scope ElementalShield initializer Init
globals
// General Globals
private constant integer AID = 'A000'
private constant integer DID = 'n000'
private constant integer FID = 'Amrf'
private constant string CastCasterEffect = "Abilities\\Spells\\Items\\AIda\\AIdaCaster.mdl"
private constant string CastCasterEffectAttach = "origin"
private constant real Interval = 0.030
private constant integer OrbAmount = 5 // Verry important for the spells core!
// Sphere/Ball/Missile/Orb(Or whatever you would call it) Globals, keyword is Orb
private constant real Orb_AreaOfEffect = 50.
private constant real Orb_AreaOfEffectInc = 10.
private constant real Orb_Speed = 10.
private constant real Orb_Height = 55.
private constant real Orb_Offset = 100.
private constant real Orb_OffsetInc = 22.
private constant integer Orb_AmountOfOrbs = 3
private constant integer Orb_AOOInc = 1
private constant real Orb_Damage = 55.
private constant real Orb_DamageInc = 15.
private constant real Orb_Duration = 20.
private constant real Orb_DurationInc = 10.
private constant real Orb_EnemyGroupReset = 1.5
private constant integer Orb_Charges = 8
private constant integer Orb_ChargesInc = 2
private constant string Orb_DamageEffectAttach = "chest"
private constant integer Orb_AngleOfAttack = 90
// Knockback globals, keyword is Knock. ( Read the Knockback manual in the Knockback trigger for more info )
private constant real Knock_Distance = 250.
private constant real Knock_DistanceInc = 50.
private constant real Knock_Time = 0.7
private constant real Knock_TimeInc = 0.2
private constant real Knock_TreeRadius = 100.
private constant boolean Knock_Pause = false
private constant integer Knock_EffectSpawn = 4
private constant integer Knock_EffectType = 1
private constant string Knock_EffectAttach = "origin"
// Array for setup of different elements, you dont need to change this
private attacktype array Element_Attacktype
private damagetype array Element_Damagetype
private weapontype array Element_Weapontype
private real array Element_Scale
private real array Element_ScaleInc
private string array Element_Look
private string array Element_DamageEx
private string array Element_KnockEx
// Misc globals, you should not change theese
private player tmpP = null
private unit tmpU = null
private group tmpG = CreateGroup()
private group tmpG2 = null
private integer tmpI = 0
private boolexpr EnemyFilter = null
endglobals
private function SetupElements takes nothing returns nothing
// Electric
set Element_Attacktype[1] = ATTACK_TYPE_MAGIC
set Element_Damagetype[1] = DAMAGE_TYPE_LIGHTNING
set Element_Weapontype[1] = null
set Element_Scale[1] = 1.2
set Element_ScaleInc[1] = 0.1
set Element_Look[1] = "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
set Element_DamageEx[1] = "Abilities\\Weapons\\Bolt\\BoltImpact.mdl"
set Element_KnockEx[1] = "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
// Ice
set Element_Attacktype[2] = ATTACK_TYPE_MAGIC
set Element_Damagetype[2] = DAMAGE_TYPE_COLD
set Element_Weapontype[2] = null
set Element_Scale[2] = 0.08
set Element_ScaleInc[2] = 0.04
set Element_Look[2] = "Abilities\\Weapons\\FrostWyrmMissile\\FrostWyrmMissile.mdl"
set Element_DamageEx[2] = "Abilities\\Weapons\\FrostWyrmMissile\\FrostWyrmMissile.mdl"
set Element_KnockEx[2] = "Abilities\\Weapons\\ZigguratFrostMissile\\ZigguratFrostMissile.mdl"
// Fire
set Element_Attacktype[3] = ATTACK_TYPE_MAGIC
set Element_Damagetype[3] = DAMAGE_TYPE_FIRE
set Element_Weapontype[3] = null
set Element_Scale[3] = 0.8
set Element_ScaleInc[3] = 0.03
set Element_Look[3] = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
set Element_DamageEx[3] = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
set Element_KnockEx[3] = "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnBirthMissile.mdl"
// Earth
set Element_Attacktype[4] = ATTACK_TYPE_SIEGE
set Element_Damagetype[4] = DAMAGE_TYPE_FORCE
set Element_Weapontype[4] = null
set Element_Scale[4] = 0.8
set Element_ScaleInc[4] = 0.04
set Element_Look[4] = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
set Element_DamageEx[4] = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
set Element_KnockEx[4] = "Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl"
// Chaos
set Element_Attacktype[5] = ATTACK_TYPE_CHAOS
set Element_Damagetype[5] = DAMAGE_TYPE_DEATH
set Element_Weapontype[5] = null
set Element_Scale[5] = 0.8
set Element_ScaleInc[5] = 0.04
set Element_Look[5] = "Abilities\\Weapons\\DemonHunterMissile\\DemonHunterMissile.mdl"
set Element_DamageEx[5] = "Abilities\\Weapons\\GreenDragonMissile\\GreenDragonMissile.mdl"
set Element_KnockEx[5] = "Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl"
// If you want any more elements then just add them below as did in over here. Remmember to always have a higher int on the array!
endfunction
private constant function GetKnock_Distance takes integer lvl returns real
return Knock_Distance + ( Knock_DistanceInc * ( lvl - 1 ) )
endfunction
private constant function GetKnock_Time takes integer lvl returns real
return Knock_Time + ( Knock_TimeInc * ( lvl - 1 ) )
endfunction
private constant function GetOrb_Scale takes integer orb, integer lvl returns real
return Element_Scale[orb] + ( Element_ScaleInc[orb] * ( lvl - 1 ) )
endfunction
private constant function GetOrb_AreaOfEffect takes integer lvl returns real
return Orb_AreaOfEffect + ( Orb_AreaOfEffectInc * ( lvl - 1 ) )
endfunction
private constant function GetOrb_Offset takes integer lvl returns real
return Orb_Offset + ( Orb_OffsetInc * ( lvl - 1 ) )
endfunction
private constant function GetOrb_AmountOfOrbs takes integer lvl returns integer
return Orb_AmountOfOrbs + ( Orb_AOOInc * ( lvl - 1 ) )
endfunction
private constant function GetOrb_Damage takes integer lvl returns real
return Orb_Damage + ( Orb_DamageInc * ( lvl - 1 ) )
endfunction
private constant function GetOrb_Duration takes integer lvl returns real
return Orb_Duration + ( Orb_DurationInc * ( lvl - 1 ) )
endfunction
private constant function GetOrb_Charges takes integer lvl returns integer
return Orb_Charges + ( Orb_ChargesInc * ( lvl - 1 ) )
endfunction
// End of setup
//==================================================================================
private function H2I takes handle h returns integer
return h
return 0
endfunction
private keyword Orb
globals
private integer array Orbs [10000] [OrbAmount]
endglobals
private function Check takes integer x returns nothing
local Orb dat
local integer i = 1
loop
exitwhen i > OrbAmount
set dat = Orbs[x][i]
if dat.Orb != null then
call dat.destroy()
endif
set i = i + 1
endloop
endfunction
private function GroupFilter takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(), tmpP) and GetWidgetLife(GetFilterUnit()) > .405 and IsUnitType(GetFilterUnit(), UNIT_TYPE_GROUND) and not IsUnitInGroup(GetFilterUnit(), tmpG2)
endfunction
private struct Orb
unit u
player p
integer l
unit Orb
effect OrbLook
integer OrbType
group Check = CreateGroup()
real Turn = 0
real Offset
real Duration = 0
real EndDuration
real Refresh = 0
real Damage
real KnockDistance
real KnockTime
real Aoe
integer Charges
static real nX = 0
static real nY = 0
static integer array Index
static integer Total = 0
static timer Tim = CreateTimer()
static method Loop takes nothing returns nothing
local Orb dat
local integer i = 0
loop
exitwhen i >= dat.Total
set dat = dat.Index[i]
if dat.Duration < dat.EndDuration and GetWidgetLife(dat.u) > .405 then
set dat.Turn = dat.Turn + ( Orb_Speed * bj_DEGTORAD )
set dat.nX = GetUnitX(dat.u) + dat.Offset * Cos(dat.Turn)
set dat.nY = GetUnitY(dat.u) + dat.Offset * Sin(dat.Turn)
call SetUnitFacing(dat.Orb, Atan2(dat.nY - GetUnitY(dat.Orb), dat.nX - GetUnitX(dat.Orb)) * bj_RADTODEG)
call SetUnitX(dat.Orb, dat.nX)
call SetUnitY(dat.Orb, dat.nY)
set tmpP = dat.p
set tmpG2 = dat.Check
call GroupEnumUnitsInRange(tmpG, dat.nX, dat.nY, dat.Aoe, EnemyFilter)
loop
set tmpU = FirstOfGroup(tmpG)
exitwhen tmpU == null
if Element_DamageEx[dat.OrbType] != "" then
call DestroyEffect(AddSpecialEffectTarget(Element_DamageEx[dat.OrbType], tmpU, Orb_DamageEffectAttach))
endif
call UnitDamageTarget(dat.u, tmpU, dat.Damage, false, false, Element_Attacktype[dat.OrbType], Element_Damagetype[dat.OrbType], Element_Weapontype[dat.OrbType])
call KnockbackEx(tmpU, dat.KnockDistance, Atan2(GetUnitY(tmpU) - dat.nY, GetUnitX(tmpU) - dat.nX), dat.KnockTime, Knock_TreeRadius, Knock_Pause, Knock_EffectSpawn, Knock_EffectType, Element_KnockEx[dat.OrbType], Knock_EffectAttach)
call GroupAddUnit(dat.Check, tmpU)
call GroupRemoveUnit(tmpG, tmpU)
set tmpI = 1
endloop
if dat.Refresh > Orb_EnemyGroupReset then
call GroupClear(dat.Check)
set dat.Refresh = 0
else
set dat.Refresh = dat.Refresh + Interval
endif
set dat.Duration = dat.Duration + Interval
if tmpI > 0 then
if dat.Charges > 0 then
set dat.Charges = dat.Charges - 1
else
call dat.destroy()
set i = i - 1
endif
set tmpI = 0
endif
else
call dat.destroy()
set i = i - 1
endif
set i = i + 1
endloop
if dat.Total == 0 then
call PauseTimer(dat.Tim)
endif
endmethod
static method Start takes unit u, player p, integer l, integer t, real a returns Orb
local Orb dat = Orb.allocate()
local real s = GetOrb_Scale(t, l)
set dat.u = u
set dat.p = p
set dat.l = l
set dat.OrbType = t
set dat.Turn = a
set dat.Offset = GetOrb_Offset(l)
set dat.EndDuration = GetOrb_Duration(l)
set dat.Damage = GetOrb_Damage(l)
set dat.KnockDistance = GetKnock_Distance(l)
set dat.KnockTime = GetKnock_Time(l)
set dat.Aoe = GetOrb_AreaOfEffect(l)
set dat.Charges = GetOrb_Charges(l)
set dat.Orb = CreateUnit(p, DID, GetUnitX(u) + dat.Offset * Cos(a), GetUnitY(u) + dat.Offset * Sin(a), a * bj_RADTODEG)
call UnitAddAbility(dat.Orb, FID)
call UnitRemoveAbility(dat.Orb, FID)
call SetUnitFlyHeight(dat.Orb, Orb_Height, 0)
call SetUnitAnimationByIndex(dat.Orb, Orb_AngleOfAttack)
call SetUnitScale(dat.Orb, s, s, s)
if Element_Look[t] != "" then
set dat.OrbLook = AddSpecialEffectTarget(Element_Look[t], dat.Orb, "origin")
endif
if dat.Total == 0 then
call TimerStart(dat.Tim, Interval, true, function Orb.Loop)
endif
set dat.Index[dat.Total] = dat
set dat.Total = dat.Total + 1
return dat
endmethod
method onDestroy takes nothing returns nothing
call DestroyGroup(this.Check)
call DestroyEffect(this.OrbLook)
call KillUnit(this.Orb)
set this.Check = null
set this.OrbLook = null
set this.Orb = null
set this.u = null
set this.p = null
set this.Total = this.Total - 1
set this.Index[this] = this.Index[this.Total]
endmethod
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AID
endfunction
private function Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local player p = GetOwningPlayer(u)
local integer l = GetUnitAbilityLevel(u, AID)
local integer i = 1
local integer e = GetOrb_AmountOfOrbs(l)
local real a = 360/e
local integer x = H2I(u) - 0x100000
call Check(x)
loop
exitwhen i > e
set Orbs[x][i] = Orb.Start(u, p, l, i, (a*i+GetUnitFacing(u)) * bj_DEGTORAD)
set i = i + 1
endloop
if CastCasterEffect != "" then
call DestroyEffect(AddSpecialEffectTarget(CastCasterEffect, u, CastCasterEffectAttach))
endif
set u = null
set p = null
endfunction
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
local integer i = 1
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddAction(trg, function Actions)
call TriggerAddCondition(trg, Condition(function Conditions))
set trg = null
call SetupElements()
// Preloading the effects
loop // Array Preloading ;)
exitwhen Element_Look[i] == "" or Element_Look[i] == null
call Preload(Element_Look[i])
set i = i + 1
endloop
loop // Array Preloading ;)
exitwhen Element_DamageEx[i] == "" or Element_DamageEx[i] == null
call Preload(Element_DamageEx[i])
set i = i + 1
endloop
loop // Array Preloading ;)
exitwhen Element_KnockEx[i] == "" or Element_KnockEx[i] == null
call Preload(Element_KnockEx[i])
set i = i + 1
endloop
call Preload(CastCasterEffect)
call PreloadStart()
// End of Preloading
set EnemyFilter = Condition(function GroupFilter)
endfunction
endscope
Map: