• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Power Embrace ver1.1

Hello everyone again. Here's another JASS spell I made. This spell really took me long time to finish, and I hope this is the last JASS spell I upload, since I started learning vJASS :). Hope you like it.

Spell Action:

The caster summons a powerful orb from Universe, to fall down on his enemies. When orb reaches the ground it will start to drill the earth creating a crater that pulls nearby enemy units in it. When the crater expires, the orb will explode, vacuuming the earth and enemy units in the air. When enemy units fall they will take minor damage.

JASS:
//***************************************************************************************************
//* ========================   
//* Power Embrace ver.1.1
//* ========================  
//* Made by Shdow89 
//* 
//*
//* How to implement:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* 1. Copy the ability called "Power Embrace" to your map.
//*    You can change the dummy unit model path if Objecy Editor, if you want it to look different.
//*
//* 2. Copy the dummy unit called "Power Embrace Orb" to your map.
//*
//* 3. Make a global variable of type hashtable, and name it "HashTime" (without " " ofcourse).
//*    After that, copy the trigger called: InitHashtable to your map.
//*       
//* 4. Make a global variable of type unit and name it "GetDamager" (without " " ofcourse),
//*    or you could copy the same from this map to yours.
//*
//* 5. Copy the trigger called "Power Embrace" to your map. Or you can make a new trigger,
//*     name it "Power Embrace" (without " " ofcourse) and copy the entire script from the same
//*     in this map, to trigger you made.
//*   
//* 6. Change the spells and dummy units rawcodes in the constants, change other data
//*     to what you desire, and enjoy.            
//*
//* Choosable/Effects:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯   
//*   Go down through constant function and change to what you like. Units affected are:
//*   Enemy Units, Non-Structures, living and Non-Magic immune.
//*   This could actually be quite tricky to change since filter are found in three functions.
//*   Functions are: Damage_Actions_Orb
//*                  Orb_Pull_Units
//*                  Old_Filter
//*                      
//* 
//* Editor's Word: 
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ 
//*   I've spent quite some time creating this spell, and code is very long.
//*   Since I've lost most of my nerves on this spell, I really decided that I need to learn
//*   vJASS.
//*
//* Spells Action:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ 
//*   The caster summons a powerful orb from Universe, to fall down on his enemies.
//*   When orb reaches the ground it will start to drill the earth creating a crater
//*   that pulls nearby enemy units in it. When the crater expires, the orb will explode,
//*   vaccuiming the earth and enemy units in the air. When enemy units fall they will take
//*   minor damage.
//*
//* Credits:
//* ¯¯¯¯¯¯¯¯
//*   TriggerHappy187, for amazing comments, and help with groups, and BJs.
//*   Deuterium, for help with fixing the BJ
//*   
//*************************************************************************************************
//====================================================================================================
// Start of constants. Constants are created here to provide the user of the spell easier implementing, and changing the spell function, data, rawcodes, etc. All of these can be changed, to what the user like.
//====================================================================================================
constant function Power_Embrace_ID takes nothing returns integer
    return 'A000' // Power Embrace rawcode. Change to yours if used.
endfunction

constant function Power_Embrace_Dummy_ID takes nothing returns integer
    return 'h000' // Power Embrace Orb dummy rawcode. Change to yours if used.
endfunction

constant function Storm_Crow_ID takes nothing returns integer
    return 'Arav' // Strom Crow ability rawcode. This ability is needed for sending units in the air. You don't have to change this, if you haven't changed it in your map.
endfunction

constant function Power_Embrace_Pull_SFX takes nothing returns string
    return "Abilities\\Spells\\Items\\AIil\\AIilTarget.mdl" // This special effect is spawned every 0.3 seconds. It presents a special effect for pulling the units into crater.
endfunction    

constant function Power_Embrace_After_Pull_SFX takes nothing returns string
    return "Objects\\Spawnmodels\\NightElf\\NEDeathMedium\\NEDeath.mdl" // This special effect is spawned after crater finishes with pulling units in it.
endfunction

constant function Power_Embrace_Explode_SFX takes nothing returns string
    return "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl" // This special effect is spawned after dummy orb reaches the ground.
endfunction

constant function Orb_Hit_Units_SFX takes nothing returns string
    return "Abilities\\Spells\\Orc\\FeralSpirit\\feralspiritdone.mdl" // This special effect is spawned when orb dummy reaches the ground, on enemy units.
endfunction

constant function Enemy_Ground_Hit_SFX takes nothing returns string
    return "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl" // This special effect is spawned after enemy units reach the ground, after beign send in the air by the crater.
endfunction

constant function Orb_Explode_Damage takes integer i returns real
    return 100.0 *i // Damage dealt after orb reaches the ground. 100 * level of Power Embrace
endfunction

constant function Ground_Hit_Damage takes integer i returns real
    return 25.0 * i // Damage dealt to enemy units, after reaching the ground, while beign pumped out of crater. 25 * level of Power Embrace.
endfunction

constant function Orb_Blast_AOE takes nothing returns real
    return 350.0 // This presents AOE for explosion of the orb (when it reaches the ground), and AOE of pulling the units in the crater.
endfunction

constant function Orb_Crater_Pull_Time takes integer i returns integer
    return 2 + i // How long (seconds) does the crater pulls the units inside it. 2 seconds + level of Power Embrace,
endfunction

constant function Orb_Crater_Depth_Value takes nothing returns real
    return 700.0 // How much does the crater goes into ground.
endfunction

constant function Dummy_Move_Down_Speed takes nothing returns real
    return 25.0 // How faste does the orb dummy is moving from the air to the ground.
endfunction

constant function Enemy_Pull_Speed takes nothing returns real
    return 6.0 // The speed for pulling the enemy units in crater. I suggest keeping this under 20.0.
endfunction

constant function Dummy_Height_Spawn takes nothing returns real
    return 1500.0 // How far in the air is the dummy orb spawned.
endfunction

constant function Enemy_Height_Reached takes nothing returns real
    return 500.0 // How far in the air are enemy units sent, after beign pumped out of the crater.
endfunction

constant function Enemy_Fly_Speed takes nothing returns real
    return 25.0 // How fast are enemy units are moving in the air.
endfunction
//==================================================================================================================================
//Done with constants, don't touch anything below this if you are unsure.
//========================================================================================================================================================================================================================
function Trig_Power_Embrace_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == Power_Embrace_ID()
endfunction
//========Shadow1500's Parabola======================================================================================================================
function JumpParabola takes real dist, real maxdist,real maxheight returns real
    local real t = (dist*2)/maxdist-1
    return (-t*t+1)*maxheight
endfunction
//=====================================================================================================================================
//Old filter function, since I'm using loop in fly function.
//=======================================================================================================================================
function Old_Filter takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(udg_GetDamager)) == true and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false and (GetWidgetLife(GetFilterUnit())>0.405) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false
endfunction

//==================================================================================================================================
//Filter function for pulling the units in the crater.
//==================================================================================================================================
function Pull_Actions_Orb takes nothing returns boolean
 local unit u      = GetFilterUnit()
 
 local real uX     = GetUnitX     (u)
 local real uY     = GetUnitY     (u)
 local real dummyX = GetUnitX     (udg_GetDamager)
 local real dummyY = GetUnitY     (udg_GetDamager)
 local real angle  = Atan2        (dummyY - uY, dummyX - uX)
 local real moveX  = uX + Enemy_Pull_Speed() * Cos(angle)
 local real moveY  = uY + Enemy_Pull_Speed() * Sin(angle)
  
 
 if IsUnitEnemy(u, GetOwningPlayer(udg_GetDamager)) == true and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false and (GetWidgetLife(u)>0.405) and IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) == false then
    call SetUnitX(u, moveX)
    call SetUnitY(u, moveY)
 endif
 set u = null
 return false
endfunction

//==================================================================================================================================    
//Filter function for damaging enemies after explosion (when Orb reaches the ground).
//==================================================================================================================================
function Damage_Actions_Orb takes nothing returns boolean
 local unit u      = GetFilterUnit()
 local integer lvl = GetUnitAbilityLevel(udg_GetDamager, Power_Embrace_ID()) 
 if IsUnitEnemy(u, GetOwningPlayer(udg_GetDamager)) == true and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false and (GetWidgetLife(u)>0.405) and IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) == false then
    call UnitDamageTarget(udg_GetDamager, u, Orb_Explode_Damage(lvl), true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
    call DestroyEffect(AddSpecialEffect(Orb_Hit_Units_SFX(), GetUnitX(u), GetUnitY(u))) 
 endif
 set u = null
 return false
endfunction
//========================================================================================================================================================================================================================
//========================================================================================================================================================================================================================

//===========================================================================================================================
//This function sends the units in air after creater has expired..
//====================================================================================================================================
function Orb_Blast_Out takes nothing returns nothing
 local timer out   = GetExpiredTimer()
 
 local unit flyer  = LoadUnitHandle(udg_HashTime, GetHandleId(out), 2)
 local unit blah   = LoadUnitHandle(udg_HashTime, GetHandleId(out), 1)
 local unit caster = LoadUnitHandle(udg_HashTime, GetHandleId(out), 10)
 
 //Setting values for executing the jump. Beam me up, Scotty!
 local real mX       = LoadReal(udg_HashTime, GetHandleId(out), 3)
 local real mY       = LoadReal(udg_HashTime, GetHandleId(out), 4)
 local real mHeight  = Enemy_Height_Reached()
 local real mDist    = LoadReal(udg_HashTime, GetHandleId(out), 5)
 local real curDist  = SquareRoot((GetUnitX(flyer) - mX)*(GetUnitX(flyer) - mX)+(GetUnitY(flyer) - mY)*(GetUnitY(flyer)- mY))
 local real away     = JumpParabola(curDist, mDist, mHeight)
 local real angle    = LoadReal(udg_HashTime, GetHandleId(out), 6)
 local real moveX    = GetUnitX(flyer) + Enemy_Fly_Speed() * Cos(angle)
 local real moveY    = GetUnitY(flyer) + Enemy_Fly_Speed() * Sin(angle)

 if curDist <= Enemy_Fly_Speed() then
 
   call PauseTimer(out)
   call DestroyTimer(out)
   call RemoveUnit(blah)
   call SetUnitFlyHeight(flyer, GetUnitDefaultFlyHeight(flyer), 0.0)
   call SetUnitPathing(flyer, true)
   call FlushChildHashtable(udg_HashTime, GetHandleId(out))
   call UnitDamageTarget(caster, flyer, Ground_Hit_Damage(GetUnitAbilityLevel(caster, Power_Embrace_ID())), true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
   set out = null
   call DestroyEffect(AddSpecialEffect(Enemy_Ground_Hit_SFX(), GetUnitX(flyer), GetUnitY(flyer)))
   set caster = null
   set flyer = null
   set blah = null
 
 else
 
  if IsTerrainPathable(moveX, moveY, PATHING_TYPE_FLYABILITY) == false then
 
    call SetUnitPosition(flyer, moveX, moveY)
    call SetUnitFlyHeight(flyer, away, 0.0)

    set caster = null
    set blah = null
    set flyer = null
    set out = null
   
  else 
 
   call PauseTimer(out)
   call DestroyTimer(out)
   call RemoveUnit(blah)
   call SetUnitFlyHeight(flyer, GetUnitDefaultFlyHeight(flyer), 0.0)
   call SetUnitPathing(flyer, true)
   call FlushChildHashtable(udg_HashTime, GetHandleId(out))
   set out = null
   call DestroyEffect(AddSpecialEffect(Enemy_Ground_Hit_SFX(), GetUnitX(flyer), GetUnitY(flyer)))
   call UnitDamageTarget(caster, flyer, Ground_Hit_Damage(GetUnitAbilityLevel(caster, Power_Embrace_ID())), true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
   set caster = null
   set flyer = null
   set blah = null
  endif    
 endif    
endfunction

//===========================================================================================================================
//This function creates the crater, and pulls the units in it.
//====================================================================================================================================
function Orb_Pull_Units takes nothing returns nothing
 local timer pull       = GetExpiredTimer ()
 local timer out        = null
 local unit dummy       = LoadUnitHandle  (udg_HashTime, GetHandleId(pull), 3)
 local unit w           = null
 local unit caster      = LoadUnitHandle  (udg_HashTime, GetHandleId(pull), 4)
 local real pointX      = GetUnitX        (dummy)
 local real pointY      = GetUnitY        (dummy)
 local real dur         = LoadReal        (udg_HashTime, GetHandleId(pull), 1)
 local real curDur      = LoadReal        (udg_HashTime, GetHandleId(pull), 2)
 local real jX          = 0.0
 local real jY          = 0.0
 local real jDist       = 0.0
 local real angle       = 0.0


 local integer sfx_i    = LoadInteger     (udg_HashTime, GetHandleId(pull), 10)
 
 if curDur < dur then
 
  set udg_GetDamager = dummy
  call GroupEnumUnitsInRange  (LoadGroupHandle(udg_HashTime, StringHash("Global Group"), 0), pointX, pointY, Orb_Blast_AOE(), Condition(function Pull_Actions_Orb))

    if sfx_i > 10 then
      call DestroyEffect(AddSpecialEffect(Power_Embrace_Pull_SFX(), GetUnitX(dummy), GetUnitY(dummy)))
      call SaveInteger(udg_HashTime, GetHandleId(pull), 10, 1)
    else
      set sfx_i = sfx_i + 1
      call SaveInteger(udg_HashTime, GetHandleId(pull), 10, sfx_i)
    endif
     
  set curDur = curDur + 0.03
  call SaveReal(udg_HashTime, GetHandleId(pull), 2, curDur)
 
  call GroupClear(LoadGroupHandle(udg_HashTime, StringHash("Global Group"), 0))
  set caster = null
  set dummy = null
  set pull = null
 
 else
 
   call PauseTimer(pull)
   call DestroyTimer(pull)
   call FlushChildHashtable(udg_HashTime, GetHandleId(pull))

   call TerrainDeformCrater(GetUnitX(dummy), GetUnitY(dummy), Orb_Blast_AOE(), Orb_Crater_Depth_Value()*(-1.0), R2I(0.5 * 1000), false)

   call DestroyEffect(AddSpecialEffect(Power_Embrace_After_Pull_SFX(), GetUnitX(dummy), GetUnitY(dummy)))
   
   set udg_GetDamager = dummy
   call GroupEnumUnitsInRange  (LoadGroupHandle(udg_HashTime, StringHash("Global Group"), 0), pointX, pointY, Orb_Blast_AOE(), Condition(function Old_Filter))
   set w = FirstOfGroup(LoadGroupHandle(udg_HashTime, StringHash("Global Group"), 0))
   
 if w == null then
 
   call RemoveUnit(dummy)
   call DestroyEffect(AddSpecialEffect(Power_Embrace_After_Pull_SFX(), GetUnitX(dummy), GetUnitY(dummy)))
   set caster = null
   set w = null
   set out = null
   set dummy = null
   set pull = null
  
 else     
   //Setting values for jump.     
   loop 
     set w = FirstOfGroup(LoadGroupHandle(udg_HashTime, StringHash("Global Group"), 0))
   exitwhen w == null
     call GroupRemoveUnit(LoadGroupHandle(udg_HashTime, StringHash("Global Group"), 0), w)

 
     call UnitAddAbility(w, Storm_Crow_ID())
     call UnitRemoveAbility(w, Storm_Crow_ID())

     call SetUnitPathing(w, false)
     
     set out   = CreateTimer()
     set jDist = GetRandomReal(200.0, 600.0)
     set angle = Atan2(GetUnitY(w) - GetUnitY(dummy), GetUnitX(w) - GetUnitX(dummy)) 
     set jX    = GetUnitX(w) + jDist * Cos(angle)
     set jY    = GetUnitY(w) + jDist * Sin(angle) 
     
     call SaveUnitHandle(udg_HashTime, GetHandleId(out), 1, dummy)
     call SaveUnitHandle(udg_HashTime, GetHandleId(out), 2, w)
     call SaveUnitHandle(udg_HashTime, GetHandleId(out), 10, caster)
     call SaveReal      (udg_HashTime, GetHandleId(out), 3, jX)
     call SaveReal      (udg_HashTime, GetHandleId(out), 4, jY)
     call SaveReal      (udg_HashTime, GetHandleId(out), 5, jDist)
     call SaveReal      (udg_HashTime, GetHandleId(out), 6, angle)
     call TimerStart    (out, 0.03, true, function Orb_Blast_Out)
     
     set out = null
   endloop
   
   call GroupClear(LoadGroupHandle(udg_HashTime, StringHash("Global Group"), 0))
   set caster = null
   set w = null
   set out = null
   set dummy = null
   set pull = null
  endif 
 endif  
endfunction 
     
//===========================================================================================================================
//This function moves the orb to the ground.
//====================================================================================================================================
function Orb_Move_Down takes nothing returns nothing
 local timer down       = GetExpiredTimer()
 local timer pull       = null
 local unit dummy       = LoadUnitHandle(udg_HashTime, GetHandleId(down), 1)
 local unit caster      = LoadUnitHandle(udg_HashTime, GetHandleId(down), 2)
 local integer lvl      = GetUnitAbilityLevel(caster, Power_Embrace_ID())
 local real height      = GetUnitFlyHeight(dummy)
 
 if height > Dummy_Move_Down_Speed() then
   call SetUnitFlyHeight(dummy, height - Dummy_Move_Down_Speed(), 0.0)
   set caster = null
   set down = null
   set dummy = null
 else
   call PauseTimer             (down)
   call DestroyTimer           (down)
   call SetUnitFlyHeight       (dummy, 0.0, 0.0)
   call PauseUnit              (dummy, false)
   call FlushChildHashtable    (udg_HashTime, GetHandleId(down))
   call DestroyEffect          (AddSpecialEffect(Power_Embrace_Explode_SFX(), GetUnitX(dummy), GetUnitY(dummy)))
   
   set udg_GetDamager           = caster
   call GroupEnumUnitsInRange  (LoadGroupHandle(udg_HashTime, StringHash("Global Group"), 0), GetUnitX(dummy), GetUnitY(dummy), Orb_Blast_AOE(), Condition(function Damage_Actions_Orb))

   call TerrainDeformCrater(GetUnitX(dummy), GetUnitY(dummy), Orb_Blast_AOE(), Orb_Crater_Depth_Value(), R2I(Orb_Crater_Pull_Time(lvl) * 1000), false) 
    
   

   
   set pull                     = CreateTimer()
   call SaveReal               (udg_HashTime, GetHandleId(pull), 1, I2R(Orb_Crater_Pull_Time(lvl)))
   call SaveReal               (udg_HashTime, GetHandleId(pull), 2, 0.03)
   call SaveUnitHandle         (udg_HashTime, GetHandleId(pull), 3, dummy)
   call SaveUnitHandle         (udg_HashTime, GetHandleId(pull), 4, caster)
   call SaveInteger            (udg_HashTime, GetHandleId(pull), 10, 1)
   call TimerStart             (pull, 0.03, true, function Orb_Pull_Units)
   
   call GroupClear(LoadGroupHandle(udg_HashTime, StringHash("Global Group"), 0))
   set caster = null
   set dummy = null
   set down = null
  endif 
endfunction

//===========================================================================================================================
//This function sets the values and handles when spell is cast. Action function.
//====================================================================================================================================
function Trig_Power_Embrace_Actions takes nothing returns nothing
 local timer down       = CreateTimer()
 local unit caster      = GetTriggerUnit()
 local unit dummy       = CreateUnit(GetOwningPlayer(caster), Power_Embrace_Dummy_ID(), GetSpellTargetX(), GetSpellTargetY(), 0.0)
 
 call SetUnitFlyHeight(dummy, Dummy_Height_Spawn(), 0.0)

 call SaveUnitHandle  (udg_HashTime, GetHandleId(down), 1, dummy)
 call SaveUnitHandle  (udg_HashTime, GetHandleId(down), 2, caster)
 call TimerStart(down, 0.03, true, function Orb_Move_Down)
 
 set down = null
 set caster = null
 set dummy = null
endfunction
 
  


//=============INIT TRIGG===================================================================
function InitTrig_Power_Embrace takes nothing returns nothing
    local trigger trig = CreateTrigger()

    call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT) 

    call TriggerAddCondition(trig, Condition(function Trig_Power_Embrace_Conditions))
    call TriggerAddAction(trig, function Trig_Power_Embrace_Actions)

    call Preload(Power_Embrace_Pull_SFX())
    call Preload(Power_Embrace_After_Pull_SFX())
    call Preload(Power_Embrace_Explode_SFX())
    call Preload(Orb_Hit_Units_SFX())
    call Preload(Enemy_Ground_Hit_SFX())
    call PreloadStart()
 
endfunction

Spell is MUI, and I hope leak-less. You can edit levels, damage, and a lot of other data from the constants.

Credits: TriggerHappy187 for help with groups, and amazing comments.
Deuterium, for comments, and helping with BJ



- Replaced the Terrain BJ with a native.
- Added Preload action for special effects.
- Made a global group within hashtable, and removed usage of local groups.
- Improved spell documentation a bit.
- Removed action for nulling the trigger
- Replaced loop for event with TriggerRegisterAnyUnitEventBJ.
- Added the new code in description.
- Credits to TriggerHappy187 and Deuterium.


Keywords:
Orb, Pull, Fly, Power, Vacuum, Park, South, Fall
Contents

Power Embrace (Map)

Reviews
19:48, 4th Oct 2009 TriggerHappy187: Right now it's leakless, and visually appealing. But remember to take in the suggestions I made. Approved.

Moderator

M

Moderator

19:48, 4th Oct 2009
TriggerHappy187:

Right now it's leakless, and visually appealing. But remember to take in the suggestions I made.

Approved.
 
Level 8
Joined
Jun 18, 2007
Messages
214
why you don't learn vJass?
(the jump is to fast i think)

No, that's not it. I'm still learning it, and I have huge problems with installing it.
And I am kinda lazy to learn it, since I'm just enjoying making spells with JASS... Have to find time to learn vJASS :p.
Thank you all for your comments, and I hope you like the spell.
 
Spell is visually pretty cool, though I'm not sure about the large spike of terrain at the end.

  • I will list some things that are not improvements, but rather things that are not needed.
    • You don't need to null triggers.
    • The TriggerRegisterAnyUnitEventBJ is perfectly fine, no need to use the native equivalent.
  • You should make your timer interval configurable.
  • Right now your dynamically creating groups, and since your using a hashtable it would be pretty simple (and more efficient) to create a group, store it in the hashtable, and re-use it in your triggers.
  • Your InitHashtable trigger would be better of in GUI, this way people don't have to manually create the hashtable. If it is in GUI the variable will auto-copy over.
  • This should work in replacement for that BJ;
    JASS:
    call TerrainDeformCrater(GetUnitX(dummy), GetUnitY(dummy), Orb_Blast_AOE(), Orb_Crater_Depth_Value()* (-1.0), 500, false)
 
Level 8
Joined
Jun 18, 2007
Messages
214
Spell is visually pretty cool, though I'm not sure about the large spike of terrain at the end.

  • I will list some things that are not improvements, but rather things that are not needed.
    • You don't need to null triggers.
    • The TriggerRegisterAnyUnitEventBJ is perfectly fine, no need to use the native equivalent.
  • You should make your timer interval configurable.
  • Right now your dynamically creating groups, and since your using a hashtable it would be pretty simple (and more efficient) to create a group, store it in the hashtable, and re-use it in your triggers.
  • Your InitHashtable trigger would be better of in GUI, this way people don't have to manually create the hashtable. If it is in GUI the variable will auto-copy over.
  • This should work in replacement for that BJ;
    JASS:
    call TerrainDeformCrater(GetUnitX(dummy), GetUnitY(dummy), Orb_Blast_AOE(), Orb_Crater_Depth_Value()* (-1.0), 500, false)

First of all thank you all for your comments, I really appreciate them :).
Now, well I'm always using, TriggerRegisterUnitEvent native, since I always believed it was faster. I guess I'll change it. Now, don't triggers extend as handles? I mean, if they do, then I have to null them, won't they leak otherwise?
I would really like to know how to not dynamically create groups. But, I will need some help with this. Do you mean I create a group at the action function of my spell, and then I just LoadGroupHandle in other functions, that are needed. Or do I make a group in the InitHashtable trigger, then it would have to be a global group?
And thank you for TerrainDeformation native :).
 
triggers extend as handles? I mean, if they do, then I have to null them, won't they leak otherwise?

You only need to null handles that you destroy, and you don't destroy triggers.

I would really like to know how to not dynamically create groups. But, I will need some help with this.

You basically just use a global group and keep enumerating it over and over. No need to destroy it either. Make sure to clear it after (if there are any units left inside of it).

As for using it with the hastable, in your init trigger do something like;

call SaveGroupHandle(hashtable, StringHash("Global Group"), 0, CreateGroup())

And use some constant function like;

JASS:
function GLOBAL_GROUP takes nothing returns group
    return LoadGroupHandle(hashtable, StringHash("Global Group"), 0)
endfunction

True in this case, but it'll be better if he uses the true boolexpr instead of the "null" ;)

Null boolexprs don't leak inside events. I have confirmed it myself as well as seen tests from numerous others.
 
Last edited:
Top