• 🏆 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!

Swing Slash and Nether Glaive vBETA

Here comes my, I forgot which number :p JASS spells. This time I'm presenting two spells. For now they are the most advanced spells I've ever made with JASS. This could also mean that I did something wrong, so any comments on how to improve would good.

1. Swing Slash:

Actions:
The caster swings it's sword dealing damage to all units in front of him, in the type of 180 % novas. Units caught by the swing will be cut and take damage each second for 5 seconds.


Code:
JASS:
//***************************************************************************************************
//* ========================   
//* Swing Slash ver.1.0a
//* ========================  
//* Made by Shdow89 
//* 
//*
//* How to implement:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* 1. Copy the spell "Swing Slash" to your map.
//*
//* 2. Copy the spell "Swing Slash(Bleed DoT)" to your map.
//*
//* 3. Copy the unit "Dummy Unit" to youe map.
//*      
//* 4. Make a global variable of type hashtable, name it Hash, and copy "InitHashtable" trigger.
//*
//* 5, Make a global variable of type unit group and name it temp_group.
//*
//* 6. Copy the "Swing Slash" trigger to your map, go down through constants,
//*    change the rawcodes, other data, and enjoy.              
//*
//* Choosable/Effects:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯   
//*    Go down through constant function and change to what you like. Units affected are:
//*    Enemy Units, Non-Structures and living. This can be change in function Swing_Slash_Filter.
//*    You can also change data in "Swing Slash(Bleed DoT)" spell to what you like.
//* 
//*
//* Editor's Word: 
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ 
//*    This spell is made before Nether Glaive, and it's still using FirstOfGroup, as API for groups.
//*    I won't change this now, since now it's working the way I want it to, but any other improvements
//*    ideas are wellcome. This is still BETA version.
//*
//* Spells Action:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ 
//*    The caster swings it's sword in front of him, dealing damage in 180 %. Units caught
//*    by the swing will be cut and they will bleed each second, taking damage each second,
//*    for 5 seconds.
//*
//* Credits:
//* ¯¯¯¯¯¯¯¯
//*    TriggerHappy187 for help with groups, and amazing reviews.   
//*
//*************************************************************************************************
constant function Swing_Slash_Rawcode takes nothing returns integer
    return 'A000' // Swing Slash spell rawcode. Change to yours if used.
endfunction

constant function Swing_Slash_DOT_Code takes nothing returns integer
    return 'A001'// Swing Slash(Bleed DoT) rawcode. Change to yours if used.
endfunction

constant function Dummy_Unit_Code takes nothing returns integer
    return 'h003' // Dummy Unit rawcode. Change to yours if used.
endfunction

constant function Cast_Animation takes nothing returns string
   return "spin" // Caster animation on cast. You can set this to null, if you don't want an animation.
endfunction

constant function Nova_SFX takes nothing returns string
    return "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl" // Special Effect for novas that are created in front of caster.
endfunction

constant function Hit_SFX takes nothing returns string
    return "Objects\\Spawnmodels\\Critters\\Albatross\\CritterBloodAlbatross.mdl" // Special Effects for units beign hit by the nova,
endfunction

constant function Slash_Distance takes nothing returns real
    return 250.0 // How far in front of the caster are novas summoned.
endfunction

constant function Damage_Radius takes nothing returns real
    return 125.0 // Area of Effect of the novas, for damage and adding bleed DoT.
endfunction

constant function Slash_Damage takes integer i returns real
    return 50.0*i // Damage dealt by the nova. Currently: 50 * level of Swing Slash
endfunction    

constant function Slash_Number takes nothing returns integer
    return 10 // Number of novas spawned in front of caster
endfunction

constant function Nova_Spawn_Speed takes nothing returns real
    return 0.04 // How fast are novas spawned
endfunction
//==========================================================================================================================================================================================================
//Condition trigger.
function Trig_Swing_Slash_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == Swing_Slash_Rawcode()
endfunction

//Filter for picking enemies in group.
function Swing_Slash_Filter takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), bj_groupEnumOwningPlayer) and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false and (GetWidgetLife(GetFilterUnit())>0.405) and IsUnitInGroup(GetFilterUnit(), udg_temp_group) == false
endfunction
//==========================================================================================================================================================================================================


//===========EXECUTE NOVA===============================================================================
function Slash_Nova takes nothing returns nothing
 local timer novatimer = GetExpiredTimer()
 local unit damager    = LoadUnitHandle(udg_Hash, GetHandleId(novatimer), 1)
 local unit ug         = null
 local unit dummy      = null
 local integer count   = LoadInteger(udg_Hash, GetHandleId(novatimer), 6)
 local integer angle   = 180/Slash_Number()
 local integer level   = LoadInteger(udg_Hash, GetHandleId(novatimer), 7)
 local real x          = LoadReal(udg_Hash, GetHandleId(novatimer), 3)
 local real y          = LoadReal(udg_Hash, GetHandleId(novatimer), 4)
 local real start      = LoadReal(udg_Hash, GetHandleId(novatimer), 5)
 local boolexpr b      = null
 local real newX
 local real newY 
 
 if count < Slash_Number() then
 
  set newX = x + Slash_Distance() * Cos((start + angle * count) * bj_DEGTORAD)
  set newY = y + Slash_Distance() * Sin((start + angle * count) * bj_DEGTORAD)
  call DestroyEffect(AddSpecialEffect(Nova_SFX(), newX, newY)) 
  call SaveInteger  (udg_Hash, GetHandleId(novatimer), 6, count + 1)

  set udg_temp_group           = LoadGroupHandle(udg_Hash, GetHandleId(novatimer), 8)
  set b                        = Condition(function Swing_Slash_Filter)
  set bj_groupEnumOwningPlayer = GetOwningPlayer(damager)
  call GroupEnumUnitsInRange(LoadGroupHandle(udg_Hash, StringHash("Global G"), 0), newX, newY, Damage_Radius(), b)
  call DestroyBoolExpr(b)
  set dummy                    = CreateUnit(GetOwningPlayer(damager), Dummy_Unit_Code(), newX, newY, 0.0)
  call UnitAddAbility         (dummy, Swing_Slash_DOT_Code())
  call SetUnitAbilityLevel    (dummy, Swing_Slash_DOT_Code(), level)

        
        loop   
            set ug = FirstOfGroup(LoadGroupHandle(udg_Hash, StringHash("Global G"), 0))
            exitwhen ug == null
            call GroupRemoveUnit        (LoadGroupHandle(udg_Hash, StringHash("Global G"), 0), ug)
            call DestroyEffect          (AddSpecialEffect(Hit_SFX(), GetUnitX(ug), GetUnitY(ug)))
            call UnitDamageTarget       (damager, ug, Slash_Damage(level), true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
            call IssueTargetOrder       (dummy, "shadowstrike", ug)   
            call GroupAddUnit           (udg_temp_group, ug)  
        endloop
   call UnitApplyTimedLife     (dummy, 'BTLF', 2.0)
   call SaveGroupHandle (udg_Hash, GetHandleId(novatimer), 8, udg_temp_group)
   call GroupClear(LoadGroupHandle(udg_Hash, StringHash("Global G"), 0))
   set b = null
   set novatimer = null
   set dummy = null
   set damager = null
   set ug = null
   
 else
    
    call FlushChildHashtable(udg_Hash, GetHandleId(novatimer))
    call PauseTimer(novatimer)
    call DestroyTimer(novatimer)
    call DestroyGroup(udg_temp_group)
    call SetUnitAnimation(damager,"stand")
    set novatimer = null
    set damager = null
  endif
endfunction       


//===============SETTINGS FOR 180 % NOVA==============================================================================
function Trig_Swing_Slash_Actions takes nothing returns nothing
 local timer novatimer = CreateTimer()
 local unit cast       = GetTriggerUnit()
 local integer level   = GetUnitAbilityLevel(cast, Swing_Slash_Rawcode()) 
 local real start      = GetUnitFacing(cast) - 90.0
 local real cX         = GetUnitX(cast)
 local real cY         = GetUnitY(cast)
 call SetUnitAnimation(cast,Cast_Animation())

        call SaveUnitHandle  (udg_Hash, GetHandleId(novatimer), 1, cast)
        call SaveReal        (udg_Hash, GetHandleId(novatimer), 3, cX)
        call SaveReal        (udg_Hash, GetHandleId(novatimer), 4, cY)
        call SaveReal        (udg_Hash, GetHandleId(novatimer), 5, start)
        call SaveInteger     (udg_Hash, GetHandleId(novatimer), 6, 1)
        call SaveInteger     (udg_Hash, GetHandleId(novatimer), 7, level)
        call SaveGroupHandle (udg_Hash, GetHandleId(novatimer), 8, CreateGroup())
        call TimerStart(novatimer, Nova_Spawn_Speed(), true, function Slash_Nova)  
    set novatimer = null
    set cast      = null
endfunction
     


//=============INIT TRIGG===================================================================
function InitTrig_Swing_Slash takes nothing returns nothing
    local trigger trig = CreateTrigger()
    local integer guza = 0


    loop
        call TriggerRegisterPlayerUnitEvent(trig, Player(guza), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        set guza = guza + 1
        exitwhen guza == 16
    endloop

    call TriggerAddCondition(trig, Condition(function Trig_Swing_Slash_Conditions))
    call TriggerAddAction(trig, function Trig_Swing_Slash_Actions)
    
    call Preload(Nova_SFX())
    call Preload(Hit_SFX())
    call PreloadStart()
    
 
endfunction

2. Nether Glaive

Actions:
The caster throws a nether glaive at a targeted enemy unit. Glaive will deal damage to unit it passes by until it reaches it's target. When it reaches the target, it will blast him with a few nether lightnings, after which will return to the caster again dealing damage to units it passes by.


Code:
JASS:
//***************************************************************************************************
//* ========================   
//* Nether Glaive ver.1.0a
//* ========================  
//* Made by Shdow89 
//* 
//*
//* How to implement:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* 1. Copy the spell "Nether Glaive" to your map.
//*
//* 2. Copy the unit  "Glaive Dummy" to your map. Change it's model path to what you like.
//*      
//* 3. Make a global variable of type hashtable, name it Hash, and copy "InitHashtable" trigger.
//*
//* 4, Make a global variable of type unit group and name it temp_group1.
//*
//* 5. Make a global variable of type unit and name it damager.
//*
//* 6. Copy the "Nether Glaive" trigger to your map, go down through constants,
//*    hange the rawcodes, other data, and enjoy.              
//*
//* Choosable/Effects:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯   
//*    Go down through constant function and change to what you like. Units affected are:
//*    Enemy Units, Non-Structures and living. This can be change in function Filter_Action.
//* 
//* Editor's Word: 
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ 
//*    This is most advanced JASS spell I ever made. The code is really large, and I'm not
//*    sure if I did everything right. It will remain BETA version, until I get some feedback
//*    about code. Until then, you can check it out, use it, and tell me what you think.
//*
//* Spells Action:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ 
//*    The casters throws a nether glaive at a targeted enemy unit. Glaive will deal damage
//*    to unit it passes by unitl it reaches it's target. When it reaches the target it will
//*    blast it with a few lightnings and return to the caster, again dealing damage to enemy
//*    units it passes by.
//*
//* Credits:
//* ¯¯¯¯¯¯¯¯
//*    TriggerHappy187 for help with groups, and amazing reviews.   
//*
//*************************************************************************************************
constant function Glaive_Hit_SFX takes nothing returns string
    return "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl" // Special Effect for units hit by the glaive while moving
endfunction

constant function Glaive_Spin_SFX takes nothing returns string
    return "Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl" // Special Effect from which lightning is created.
endfunction

constant function Glaive_Lightning takes nothing returns string
    return "AFOD" // The Finger of Death lightning code. This can be change to Chain Lig, Forl Lig, etc.
endfunction

constant function Nether_Glaive_ID takes nothing returns integer
    return 'A002' // Nether Glaive rawcode. Change to yours if used.
endfunction

constant function Glaive_Dummy_ID takes nothing returns integer
    return 'h000' // Glaive Dummy rawcode. Change to yours if used.
endfunction

constant function Dummy_Moving_Speed takes nothing returns real
    return 30.0 // Glaive moving speed.
endfunction

constant function Moving_Damage takes integer i returns real
    return 50.0*i // Damage dealt while moving. Currently: 50 * level of Nether Glaive
endfunction

constant function Spin_Damage takes integer pica returns real
    return 25.0*pica // Damage dealt by the lightnings. Currently: 25 * level of nether glaive.
endfunction

constant function Spin_Times takes integer cvarak returns integer
    return 2*cvarak // How many lightnings, special effects are spawned, and damaged the tarageted unit. Currently: 2 * level of nether glaive
endfunction

constant function Glaive_Coolison takes nothing returns real
    return 100.0 // Area of effect for Glaive damage while moving.
endfunction
//====================================================================================================================
function Trig_Nether_Glaive_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == Nether_Glaive_ID()
endfunction

function Filter_Actions takes nothing returns boolean
 local unit u = GetFilterUnit() 
 if IsUnitEnemy(u, GetOwningPlayer(udg_damager)) == true and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false and (GetWidgetLife(u)>0.405) and IsUnitInGroup(u, udg_temp_group1) == false then
    call UnitDamageTarget(udg_damager, u, Moving_Damage(GetUnitAbilityLevel(udg_damager, Nether_Glaive_ID())), true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
    call DestroyEffect(AddSpecialEffect(Glaive_Hit_SFX(), GetUnitX(u), GetUnitY(u)))
    call GroupAddUnit(udg_temp_group1, u)    
 endif
 set u = null
 return false
endfunction      
//====================================================================================================================================  


//===========================Moving Glaive=====================================================================
function Glaive_Return takes nothing returns nothing
 local timer rt            = GetExpiredTimer()
 local unit gl             = LoadUnitHandle(udg_Hash, GetHandleId(rt), 2)
 local unit ct             = LoadUnitHandle(udg_Hash, GetHandleId(rt), 1)
 local real x              = GetUnitX(ct)
 local real y              = GetUnitY(ct)
 local real x1             = GetUnitX(gl)
 local real y1             = GetUnitY(gl)
 local real dist           = SquareRoot((x1 - x) * (x1 - x) + (y1 - y) * (y1 - y))
 local real angle          = Atan2(y - y1, x - x1)
 local real newX           = x1 + Dummy_Moving_Speed() * Cos(angle)
 local real newY           = y1 + Dummy_Moving_Speed() * Sin(angle)
 set udg_damager           = LoadUnitHandle(udg_Hash, GetHandleId(rt), 1)
 
 if dist <= Dummy_Moving_Speed() then
 
 call PauseTimer(rt)
 call DestroyTimer(rt)
 call RemoveUnit(gl)
 call FlushChildHashtable(udg_Hash, GetHandleId(rt))
 call GroupClear(udg_temp_group1)
 set rt = null
 set gl = null
 set ct = null
 
 else
 
  call SetUnitPosition(gl, newX, newY)
  set udg_temp_group1 = LoadGroupHandle(udg_Hash, GetHandleId(rt), 30)
  call GroupEnumUnitsInRange(LoadGroupHandle(udg_Hash, StringHash("Global G"), 0), GetUnitX(gl), GetUnitY(gl), Glaive_Coolison(), Condition(function Filter_Actions))
  call GroupClear(LoadGroupHandle(udg_Hash, StringHash("Global G"), 0))
  call SaveGroupHandle(udg_Hash, GetHandleId(rt), 30, udg_temp_group1)   
     
  set ct       = null
  set gl       = null
  set rt  = null
 endif
endfunction

//=========================LIGHTNING AND NOVAS SPAWN===================================================================
function Spin_Attack takes nothing returns nothing
 local timer spin          = GetExpiredTimer()
 local timer returner      = null
 local unit dmg            = LoadUnitHandle(udg_Hash, GetHandleId(spin), 3)
 local unit trg            = LoadUnitHandle(udg_Hash, GetHandleId(spin), 1)
 local unit glv            = null
 local integer count       = LoadInteger   (udg_Hash, GetHandleId(spin), 4)
 local real angle1         = 360.0/Spin_Times(GetUnitAbilityLevel(dmg,Nether_Glaive_ID()))
 local real effectX        = GetUnitX(trg) + 300.0 * Cos((angle1*count) * bj_DEGTORAD)
 local real effectY        = GetUnitY(trg) + 300.0 * Sin((angle1*count) * bj_DEGTORAD)
 local real angle          = 0.0
 local lightning l         = LoadLightningHandle(udg_Hash, GetHandleId(spin), 6)
 call DestroyLightning(l)
 set l = null

 if GetWidgetLife(trg)>0.405 and count != Spin_Times(GetUnitAbilityLevel(dmg,Nether_Glaive_ID())) then
    call DestroyEffect(AddSpecialEffect(Glaive_Spin_SFX(), effectX, effectY))
    set l = AddLightning(Glaive_Lightning(),  true, effectX, effectY, GetUnitX(trg), GetUnitY(trg))
    call UnitDamageTarget(dmg, trg, Spin_Damage(GetUnitAbilityLevel(dmg, Nether_Glaive_ID())), true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
    call SaveLightningHandle(udg_Hash, GetHandleId(spin), 6, l)
    call SaveInteger(udg_Hash, GetHandleId(spin), 4, count + 1)
    set l       = null
    set dmg     = null
    set trg     = null
    set spin    = null
 else
    if GetWidgetLife(dmg)>0.408 then
        call PauseTimer(spin)
        call DestroyTimer(spin)
        set angle     = Atan2(GetUnitY(dmg) - GetUnitY(trg), GetUnitX(dmg) - GetUnitX(trg))
        set glv       = CreateUnit(GetOwningPlayer(dmg), Glaive_Dummy_ID(), GetUnitX(trg) + 20.0 * Cos(angle), GetUnitY(trg) + 20.0 * Sin(angle), angle) 
        set returner  = CreateTimer()
        
        call SaveUnitHandle (udg_Hash, GetHandleId(returner), 1, dmg)
        call SaveUnitHandle (udg_Hash, GetHandleId(returner), 2, glv)
        call SaveGroupHandle(udg_Hash, GetHandleId(returner), 30, CreateGroup())
        call TimerStart(returner, 0.03, true, function Glaive_Return)
        
        set spin = null
        set dmg  = null
        set trg  = null
        set glv  = null
     else
        call FlushChildHashtable(udg_Hash, GetHandleId(spin))
        call PauseTimer(spin)
        call DestroyTimer(spin)
        set spin = null
        set dmg  = null
        set trg  = null
     endif       
 endif         
endfunction

//========================GLAIVE FIRST MOVE======================================================================================
function Glaive_Move takes nothing returns nothing
 local timer mover         = GetExpiredTimer()
 local timer spin          = null
 local timer returner      = null
 local unit target         = LoadUnitHandle(udg_Hash, GetHandleId(mover), 1)
 local unit glaive         = LoadUnitHandle(udg_Hash, GetHandleId(mover), 2)
 local real x              = GetUnitX(target)
 local real y              = GetUnitY(target)
 local real x1             = GetUnitX(glaive)
 local real y1             = GetUnitY(glaive)
 local real dist           = SquareRoot((x1 - x) * (x1 - x) + (y1 - y) * (y1 - y))
 local real angle          = Atan2(y - y1, x - x1)
 local real newX           = x1 + Dummy_Moving_Speed() * Cos(angle)
 local real newY           = y1 + Dummy_Moving_Speed() * Sin(angle)
 set udg_damager           = LoadUnitHandle(udg_Hash, GetHandleId(mover), 3)
//!!!!!!!Conditions for stopping the glaive, if target is dead, move it back to caster. If caster is dead, destroy it. 
  if dist <= Dummy_Moving_Speed() then
  
     call PauseTimer(mover)
     call DestroyTimer(mover)
     set mover   = null
     call FlushChildHashtable(udg_Hash, GetHandleId(mover))
     call RemoveUnit(glaive)
     call GroupClear(udg_temp_group1)
     
    if GetWidgetLife(target)>0.405 then       
        set  spin                        = CreateTimer()
        call SaveUnitHandle             (udg_Hash, GetHandleId(spin), 1, target)
        call SaveUnitHandle             (udg_Hash, GetHandleId(spin), 2, glaive)
        call SaveUnitHandle             (udg_Hash, GetHandleId(spin), 3, udg_damager)
        call SaveInteger                (udg_Hash, GetHandleId(spin), 4, 0)
        call TimerStart                 (spin, 0.3, true, function Spin_Attack)     
        set glaive                       = null
        set target                       = null
        set spin                         = null        
     else
         if GetWidgetLife(udg_damager)>0.405 then         
           set returner                  = CreateTimer()
           set glaive                    = null
           set glaive                    = CreateUnit(GetOwningPlayer(udg_damager), Glaive_Dummy_ID(), GetUnitX(target) + 20.0 * Cos(angle), GetUnitY(target) + 20.0 * Sin(angle), angle)
           call SaveUnitHandle           (udg_Hash, GetHandleId(returner), 1, udg_damager)
           call SaveUnitHandle           (udg_Hash, GetHandleId(returner), 2, glaive)
           call SaveGroupHandle          (udg_Hash, GetHandleId(returner), 30, CreateGroup())
           call TimerStart               (returner, 0.03, true, function Glaive_Return)         
           set glaive                    = null
           set target                    = null
           set returner                  = null          
          else          
           set glaive                    = null
           set target                    = null
          endif  
      endif       
     
     
  else  
     call SetUnitPosition(glaive, newX, newY)
     set udg_temp_group1 = LoadGroupHandle(udg_Hash, GetHandleId(mover), 30)
     call GroupEnumUnitsInRange(LoadGroupHandle(udg_Hash, StringHash("Global G"), 0), GetUnitX(glaive), GetUnitY(glaive), Glaive_Coolison(), Condition(function Filter_Actions))
     call SaveGroupHandle(udg_Hash, GetHandleId(mover), 30, udg_temp_group1)
     call GroupClear(LoadGroupHandle(udg_Hash, StringHash("Global G"), 0))
     
     set target = null
     set mover  = null
  endif   
endfunction     

//=====================Preset action trigger==================================================================     
function Trig_Nether_Glaive_Actions takes nothing returns nothing
 local timer moving        = CreateTimer()
 local unit cast           = GetTriggerUnit()
 local unit target         = GetSpellTargetUnit()
 local real angle          = Atan2(GetUnitY(cast) - GetUnitY(target), GetUnitX(cast) - GetUnitX(target))   
 local unit glaive         = CreateUnit(GetOwningPlayer(cast), Glaive_Dummy_ID(), GetUnitX(cast) + 20.0 * Cos(angle), GetUnitY(cast) + 20.0 * Sin(angle), angle)
 
    call SaveUnitHandle(udg_Hash, GetHandleId(moving), 1, target)
    call SaveUnitHandle(udg_Hash, GetHandleId(moving), 2, glaive)
    call SaveUnitHandle(udg_Hash, GetHandleId(moving), 3, cast)
    call SaveGroupHandle(udg_Hash, GetHandleId(moving), 30, CreateGroup())
    call TimerStart(moving, 0.03, true, function Glaive_Move)
  
 set cast   = null
 set target = null
 set glaive = null
 set moving = null
endfunction      



//=============INIT TRIGG===================================================================
function InitTrig_Nether_Glaive takes nothing returns nothing
    local trigger trig = CreateTrigger()
    local integer taki = 0


    loop
        call TriggerRegisterPlayerUnitEvent(trig, Player(taki), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        set taki = taki + 1
        exitwhen taki == 16
    endloop

    call TriggerAddCondition(trig, Condition(function Trig_Nether_Glaive_Conditions))
    call TriggerAddAction(trig, function Trig_Nether_Glaive_Actions)

    call Preload(Glaive_Hit_SFX())
    call Preload(Glaive_Spin_SFX())
    call PreloadStart()

  
endfunction

This is currently BETA version, and it will be improved, if possible, in the future.

Spells are MUI, and if they are leakless, well that I'll have to wait and see.

Credits:
HTML:
Void, for amazing help, and useful comments. 
xBlackRose for pointing me to API for boolespr as callback for group.
Deuterium, for constant comments, and huge help.
TriggerHappy187 for helping me with almost everything


- Fixed a major bug with MUI in Nether Glaive (hope it's MUI now)
- Added global group handle in InitHahstable trigger, and used it both spells
- Fixed damaging issues
- Reworked groups (there is still dynamic creation, since that was only way I could achieve MUI)
- Removed trigger nulling.
- Added new codes.
- Credit to TriggerHappy187.






Keywords:
Pack, Two, Move, Glaive, Throw, Slash, Nova, Attack, Spin, Lightning, Toss, Return
Contents

Just another Warcraft III map (Map)

Reviews
20:50, 10th Oct 2009 Dr Super Good: The leak which TriggerHappy187 mentioned was preventing approval has been fixed thus this spell is now approved. For a more detailed review or potentially better rating (I gave the bare minimum for a moderatly...

Moderator

M

Moderator

20:50, 10th Oct 2009
Dr Super Good:

The leak which TriggerHappy187 mentioned was preventing approval has been fixed thus this spell is now approved.
For a more detailed review or potentially better rating (I gave the bare minimum for a moderatly functional spell) I advise recontacting him.
 
Level 8
Joined
Jun 18, 2007
Messages
214
Then explain constant function to me.

Constant is unavailable to vanilla JASS users.

EDIT: Just checked, and it works with functions.

Nice, didn't know that. You should, ofcourse, avoid using all these functions anyway, as they don't get inlined without JNPG.

What are you talking about? I should avoid constant function? How do you expect me to follow JESP standards if I don't use constant function? Constant function, were long before vJASS ever came...
 
Level 8
Joined
Jun 18, 2007
Messages
214
Really? I find it hard to believe you intended it so that the Blademaster could be left spinning forever, even after the spell is done...

There, I changed it. And you can't spin forever, because, I doubt someone will just stand in one place after casting a spell, if they die - it's reseted, if they move it's reseted, if they cast another spell, it's reseted. But now, I reseted to finish after nova's.... Hope you like it now :(
 
Swing Slash

  • All of your constant functions should be level-able.
  • Your dynamically creating groups, just save a global group inside a hashtable in your init function and use a constant function to reference it.
    JASS:
    constant function slash_group takes nothing returns group
        return LoadGroupHandle(....)
    endfunction
  • By using the above suggestion, you could also remove the udg_temp_group dependancy. Just use the same method.
  • These are no needed at the end of your actions function;
    JASS:
        set b = null
        set g = null
        set ug = null
    They are already initialized as null. I'm talking about under the else block.

Nether Glaive

  • Take the suggestions from swing slash, and use them here (dynamic groups, levelable constants ect..)
  • In your filter_actions function you need to set local unit u = GetFilterUnit() to null.
  • You need to add some bound safety when you set a units position to make sure they're inside the map (call SetUnitPosition(gl, newX, newY))
 
Level 8
Joined
Jun 18, 2007
Messages
214
Swing Slash

  • All of your constant functions should be level-able.
  • Your dynamically creating groups, just save a global group inside a hashtable in your init function and use a constant function to reference it.
    JASS:
    constant function slash_group takes nothing returns group
        return LoadGroupHandle(....)
    endfunction
  • By using the above suggestion, you could also remove the udg_temp_group dependancy. Just use the same method.
  • These are no needed at the end of your actions function;
    JASS:
        set b = null
        set g = null
        set ug = null
    They are already initialized as null. I'm talking about under the else block.

Nether Glaive

  • Take the suggestions from swing slash, and use them here (dynamic groups, levelable constants ect..)
  • In your filter_actions function you need to set local unit u = GetFilterUnit() to null.
  • You need to add some bound safety when you set a units position to make sure they're inside the map (call SetUnitPosition(gl, newX, newY))

Thank you, finally go some suggestions on how to improve.
Ok, let's see:
1. I can't make them all level-able, I don't really see the point in here.
2. Ok, will try this with a group. But how will that remove udg_temp_group dependency when I still need to make a global group, and name it?
3. oops for null xD. I just c'n'p them from the upper code. Removed!

For Nether Glaive:

2. Ok, will set it to null, thx.
3. I thought actually I don't need pathing settings for this one. It targets an enemy unit and a caster, since they can't go outside the map bounds, that means the glaive won't either, so that's really unnecessary.

Thank you for your comment!
 
Top