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

Wrath Of The Light Version 0.5

  • Like
Reactions: nGy
Wrath Of The Light Version 0.5 -


Heals a number of friendly non-undead units within an Area of effect of the targeted point, all enemy undead units within the same area will then be damaged by the total number of hit points healed, halved, and divided by the number of undead damaged units.

Level 1: 3 maximum units, 550 Area of effect, 80 hit points healed
Level 2: 4 maximum units, 600 Area of effect, 110 hit points healed
Level 3: 5 maximum units, 650 Area of effect, 140 hit points healed

Having WOTL_Heal_By_Percentage or WOTL_Heal_By_Current_Percentage equal to true will give you the option to allow the spell to heal units by either a percentage of their max or current hp.


JASS:
// Wrath of the light 0.5
// Created by Dangles20

   
// Wrath of the light editable/custom settings
// Ability ID
constant function Ability_Id takes nothing returns integer
   return 'A000'
endfunction
// Maximum Units
constant function Number_Of_Units takes nothing returns integer
   return 2
endfunction
// Maximum Units Per Level
constant function Number_Of_Units_Per_Level takes nothing returns integer
   return 1
endfunction
// Area Of Effect
constant function Area_Of_Effect_Base takes nothing returns real
   return 500.00
endfunction
// Area Of Effect Per Level
constant function Area_Of_Effect_Per_Level takes nothing returns real
   return 50.00
endfunction
// Amount Of Hit Points Healed
constant function Amount_Healed takes nothing returns real
   return 50.00
endfunction
// Amount Of Hit Points Healed Per Level
constant function Amount_Healed_Per_Level takes nothing returns real
   return 30.00
endfunction
// If true combined healed damage will be halved before delt upon the undead
constant function Halves_Damage takes nothing returns boolean
   return true
endfunction
// Effect to be used when a target is healed
constant function Heal_Effect takes nothing returns string
   return "Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl"
endfunction
// Effect to be used when a target is damaged
constant function Damage_Effect takes nothing returns string
   return "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl"
endfunction      
// If true then the ability heals targets based on their maximum life percentage
constant function Heal_By_Percentage takes nothing returns boolean
   return false
endfunction
// If true then the ability heals targets based on their current life percentage (this cancels out the previous boolean value if both are true)
constant function Heal_By_Current_Percent takes nothing returns boolean
   return false
endfunction
// Percentage healed if one of the boolean values are true
constant function Heal_Percentage takes nothing returns real
   return 10.00
endfunction
// Percentage healed per level if one of the boolean values are true
constant function Heal_Percentage_Per_Level takes nothing returns real
   return 5.00
endfunction
// If this option is true then the maximum number of undead units affected will be capped to the total number of healed units
constant function Cap_Max takes nothing returns boolean
   return true
endfunction
// Damage Type
constant function Damage_Type takes nothing returns damagetype
   return DAMAGE_TYPE_UNKNOWN
endfunction
// Weapon Type 
constant function Weapon_Type takes nothing returns weapontype
   return null
endfunction
// Attack Type
constant function Attack_Type takes nothing returns attacktype
   return ATTACK_TYPE_CHAOS
endfunction

// If condition for the heal, change/add to this in order to specify a needed unit type or remove unit types 
// (example): and IsUnitType(target, UNIT_TYPE_STRUCTURE) would only work if the unit is a structure   
// not means that anything that returns true will return false so basically returns the opposite, and just means both statements must be correct.
constant function Heal_If_Filter takes unit target returns boolean
   return not IsUnitType(target, UNIT_TYPE_UNDEAD) and not IsUnitType(target, UNIT_TYPE_DEAD) and not IsUnitType(target, UNIT_TYPE_STRUCTURE) and not IsUnitType(target, UNIT_TYPE_MECHANICAL)
endfunction
// Same as above but this one controls the unit types for the undead damaged unit
constant function Damage_If_Filter takes unit target returns boolean
   return  IsUnitType(target, UNIT_TYPE_UNDEAD) and not IsUnitType(target, UNIT_TYPE_DEAD) and not IsUnitType(target, UNIT_TYPE_STRUCTURE) and not IsUnitType(target, UNIT_TYPE_MECHANICAL)
endfunction
   

function WOTL_Group_Filter takes group unitGroup returns unit  
    // Integer variables
    local integer count = 0
    local integer random = 0
    // unit value for filtering the group
    local unit u
    // loops through the group saving and removing all units
    loop
       set u = FirstOfGroup(unitGroup)
       exitwhen u == null
       set udg_WOTL_Units[count] = u
       set count = count + 1
       call GroupRemoveUnit(unitGroup, u)
    endloop
    // If the count variable integer equals zero meaning no units within the unit group then the function returns null
    if count == 0 then
       return null
    endif
    set random = GetRandomInt(0, count - 1)
    loop
       set count = count - 1
       call GroupAddUnit(unitGroup, udg_WOTL_Units[count])
       exitwhen count == 0
    endloop
    return udg_WOTL_Units[random]
endfunction
                

function WOTL_Cast takes nothing returns boolean   
   // Unit locals
   local unit caster = GetTriggerUnit()         
   local unit target            
   // Integer locals             
   local integer level = GetUnitAbilityLevel(caster, Ability_Id())   
   local integer count = 0           
   local integer maxUnits = Number_Of_Units() + (Number_Of_Units_Per_Level() * level)       
   // Real locals 
   local real percentage = Heal_Percentage() + (Heal_Percentage_Per_Level() * level)     
   local real areaOfEffect = Area_Of_Effect_Base() + (Area_Of_Effect_Per_Level() * level)     
   local real healValue = Amount_Healed() + (Amount_Healed_Per_Level() * level)      
   local real before     
   local real damageHealed = 0    
   local real x = GetSpellTargetX()       
   local real y = GetSpellTargetY()
   local real widgetLife 
   local real maxLife 
   // Creates the player variable and sets it to the owner of the casting unit
   local player p = GetTriggerPlayer()
   if GetSpellAbilityId() != Ability_Id()  then
      return false
   endif
   call GroupEnumUnitsInRange(udg_WOTL_Unit_Group, x, y, areaOfEffect, null )     
   loop   
      set target = WOTL_Group_Filter(udg_WOTL_Unit_Group) 
      set widgetLife = GetWidgetLife(target)
      set maxLife = GetUnitState(target, UNIT_STATE_MAX_LIFE)   
      exitwhen target == null or count == maxUnits    
      if  Heal_If_Filter(target) and IsUnitAlly(target, p) and caster != target and widgetLife < maxLife   then 
         if Heal_By_Percentage()   then
            set healValue = percentage / 100 * maxLife       
         endif 
         if Heal_By_Current_Percent()   then
            set healValue = percentage / 100 * widgetLife          
         endif 
         set before = widgetLife         
         call SetWidgetLife(target, widgetLife + healValue)   
         set damageHealed = damageHealed + (GetWidgetLife(target) - before)  
         call DestroyEffect(AddSpecialEffectTarget(Heal_Effect(), target, "origin"))     
         set count = count + 1       
      endif
      call GroupRemoveUnit(udg_WOTL_Unit_Group, target)     
   endloop            
   if damageHealed != 0  then    
      if Cap_Max()  then
         set maxUnits = count
      endif
      call GroupEnumUnitsInRange(udg_WOTL_Unit_Group, x, y, areaOfEffect, null)   
      set count = 0           
      set healValue = damageHealed      
   
      if Halves_Damage()  then
         set healValue = healValue / 2    
      endif
   
      loop
         set target = WOTL_Group_Filter(udg_WOTL_Unit_Group) 
         exitwhen target == null or count == maxUnits          
         if IsUnitEnemy(target, p) and Damage_If_Filter(target)   then
            set count = count + 1  
            call GroupAddUnit(udg_WOTL_Unit_Group_2, target)     
         endif  
         call GroupRemoveUnit(udg_WOTL_Unit_Group, target)   
      endloop  
      set healValue = healValue / count     
      
      loop
         set target = FirstOfGroup(udg_WOTL_Unit_Group_2) 
         exitwhen target == null       
         call UnitDamageTarget(caster, target, healValue, false, false, Attack_Type(), Damage_Type(), Weapon_Type())   
         call DestroyEffect(AddSpecialEffectTarget(Damage_Effect(), target, "origin"))    
         call GroupRemoveUnit(udg_WOTL_Unit_Group_2, target)     
      endloop    
   endif
   

                                                                                                  
   // Clears leaks and returns false 
   set p = null                                                                                      
   set target = null
   set caster = null
   return false
endfunction
   
// Wrath of the light event
    function InitTrig_Wrath_Of_The_Light takes nothing returns nothing
        local trigger trig = CreateTrigger()     
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)    
        call TriggerAddCondition(trig, Condition(function WOTL_Cast)) 
        set trig = null        
   endfunction


Version 0.1 = Spell uploaded
Version 0.2 = Changed local names, removed most globals, Created a group filter for picking a random unit instead of the same unit over and over, removed the location, used get/setwidgetlife instead of getunitstate for obtaining current life, updated import instructions, changed function settings to a bunch of constant functions for optimization, and fixed the condition.
Version 0.3 = Optimized group filter function, changed local names once again.
Version 0.4 = Moved if function filters to the top of the code as configurable constant functions, Changed the main function to run in a condition to the event, added comments describing what the code does for readability.
Version 0.5 = Removed comments as it really made it harder to read the code, added a new boolean value to configure if the maximum number of undead units damaged are capped to the total number of units healed.



Keywords:
Jass, Wrath, Of, The, Light, Wrath Of The Light, Holy, Heal, Damage, Undead, Paladin
Contents

Just another Warcraft III map (Map)

Reviews
14:57, 28th Nov 2012 Magtheridon96: Approved. The code has improved quite a lot from when you uploaded it. :D Here are some cool improvements: - You can use configurable filter functions at the top of the spell so the user can choose which units...

Moderator

M

Moderator

14:57, 28th Nov 2012
Magtheridon96: Approved.
The code has improved quite a lot from when you uploaded it. :D

Here are some cool improvements:
- You can use configurable filter functions at the top of the spell so the user can choose which units are going to be healed and which aren't.
- You can add the main function as a condition and just return false at the end instead of having it as an action. (Conditions are faster (and c00l3r :D))
 
Level 10
Joined
Aug 21, 2010
Messages
316
These shitty udg prefixes irritate eyes.

GetOwningPlayer -> GetTriggerPlayer or GetLocalPlayer in some cases !

This is totally unnecessary

call ForGroup( group, code )

this also

WOTL_Count

bj_groupCountUnits [still there]

There is no need for the two local groups

bj_lastCreatedGroup [still there]

and so on...

Given that this is jass...hmm poorly 2.25/5
This spell requires more work
 
Level 4
Joined
Feb 19, 2010
Messages
22
But i was just told not to use globals in the moderator review so I removed them, you can still configure the spell the same using the constant functions at the top of the code and I do believe that I commented what each setting does.
 
Level 10
Joined
Aug 21, 2010
Messages
316
Stay on this method of configuration because in this case you do not need any global variable.

JASS:
constant function Amount_Healed_Per_Level takes nothing returns real
   return 30.00
endfunction

or

JASS:
constant function Amount_Healed_Per_Level takes real level returns real
   return 30. * level
endfunction

or you can use an integer instead of real

JASS:
constant function Amount_Healed_Per_Level takes integer level returns real
   return 30. * level
endfunction
 
Top