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

Doom Heal v 1.0.5

This is an aoe heal that once cast it heals that players units in the aoe for the interval of time u want. This is not a channel spell it is a single cast spell.
The thing that makes this unique is that you can change the amount of healing per interval. In the example i have it heals 50 health for the first interval. Then 45 for the second interval. Then 40 for the third interval. And so on until the full time period is over.

ALL OF MY SPELLS ARE GUI FRIENDLY

HOW TO IMPORT
I try to make my spells easy to import for both GUIers and Jassers.
Step 1) Copy the config copy trigger into your map.
Step 2) After copying that trigger u can rename it and get rid of the copy.
Step 3) Copy the cast trigger into your map.
Step 4) Go back to the config trigger and delete the variables after the line that says delete everything after this.

note: Make sure that the trigger name for the Jass is the same as the trigger name in the map.

  • DoomHeal Config
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- These are the base values that u can set. --------
      • -------- Here u set the poison base. For every second u need 32. So 5 seconds is 160. --------
      • Set doomHealIntervalBase = 160
      • -------- --------
      • -------- Here u set the max time for it to end. For every second u need 32. So 5 seconds is 160. --------
      • Set doomHealLengthBase = 1920
      • -------- --------
      • -------- This is the damage base. Every interval --------
      • Set doomHealHealBase = 50.00
      • -------- --------
      • -------- This is the radius base --------
      • Set doomHealRadiusBase = 500.00
      • -------- --------
      • -------- this is the base value that allows u to decrease or increase the amount of health u heal per interval. --------
      • -------- Example: the amount it heals at lvl 1 is 200. and u want it to decrease by 20. type in 20 in the variable. This does 200 first time. 180 the next interval 160 the third interval and so on --------
      • Set doomHealDecreaseBase = 5.00
      • -------- --------
      • -------- ---------------------------------------------------------------------------------------------------- --------
      • -------- These are the values that get added to the base per lvl that u can set. --------
      • -------- Here u set the poison interval per lvl. If u want the time to decrease set it to a positive number. If u want the interval to increase set it to a negative value --------
      • Set doomHealIntervalPerLvl = 0
      • -------- --------
      • -------- Here u set the max time for it to end per lvl. For every second u need 32. So 5 seconds is 160. --------
      • Set doomHealLengthPerLvl = 0
      • -------- --------
      • -------- This is the damage per lvl. Every interval --------
      • Set doomHealHealPerLvl = 0.00
      • -------- --------
      • -------- This is the radius per lvl --------
      • Set doomHealRadiusPerLvl = 0.00
      • -------- --------
      • -------- this is the base value that allows u to decrease or increase the amount of health u heal per interval. --------
      • -------- Example: the amount it heals at lvl 1 is 200. and u want it to decrease by 20. type in 20 in the variable. This does 200 first time. 180 the next interval 160 the third interval and so on --------
      • Set doomHealDecreasePerLvl = 0.00
      • -------- --------
      • -------- ---------------------------------------------------------------------------------------------------- --------
      • -------- These are the other values that u can change --------
      • -------- set the effect that shows on the units getting healed. --------
      • Set doomHealEffect = Abilities\Spells\Other\Doom\DoomTarget.mdl
      • -------- --------
      • -------- set the attachment point for the unit --------
      • Set doomHealEffectAttachment = origin
      • -------- --------
      • -------- Set the spell id here --------
      • Custom script: set udg_doomHealSpellId = 'A000'
      • -------- --------
      • -------- ---------------------------------------------------------------------------------------------------- --------
      • -------- This is what you use to filter out the units that can take damage and get hit by the spell --------
      • Custom script: endfunction
      • Custom script: function DoomHealFilterUnits takes unit u, unit c returns boolean
      • Custom script: set udg_tempTarget = u
      • Custom script: set udg_tempCaster = c
      • -------- Use tempTarget as the targeted unit --------
      • -------- Use tempCaster as the casting unit --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • tempTarget Not equal to tempCaster
          • (Unit-type of tempTarget) Equal to No unit-type
          • ((Unit-type of tempTarget) is A structure) Equal to False
          • (tempTarget is dead) Equal to False
        • Then - Actions
          • Custom script: return true
        • Else - Actions
      • Custom script: return false
      • -------- --------
      • -------- ---------------------------------------------------------------------------------------------------- --------
      • -------- After posting this into ur map delete the actions below here. This was just to make it easier for u to get the variables. --------
JASS:
// Doom Heal Spell made by deathismyfriend
// version 1.0.5

function DoomHealDamageLoop takes nothing returns nothing
    local integer L = 1
    local integer m = udg_doomHealMaxIndex
    loop
        exitwhen L > m
        set udg_doomHealIntervalCounter[ L] = udg_doomHealIntervalCounter[ L] + 1
        if udg_doomHealIntervalCounter[ L] == udg_doomHealInterval[ L] then
            set udg_doomHealIntervalCounter[ L] = 0
            call SetWidgetLife( udg_doomHealTarget[ L], GetWidgetLife( udg_doomHealTarget[ L]) + udg_doomHealHeal[ L])
            set udg_doomHealHeal[ L] = udg_doomHealHeal[ L] - udg_doomHealDecrease[ L]
        endif
        set udg_doomHealLengthCounter[ L] = udg_doomHealLengthCounter[ L] + 1
        if udg_doomHealLengthCounter[ L] == udg_doomHealLength[ L] or IsUnitType( udg_doomHealTarget[ L], UNIT_TYPE_DEAD) or GetUnitTypeId( udg_doomHealTarget[ L]) == 0 then
            set udg_doomHealInterval[ L] = udg_doomHealInterval[ m]
            set udg_doomHealLength[ m] = udg_doomHealLength[ m]
            set udg_doomHealHeal[ L] = udg_doomHealHeal[ m]
            set udg_doomHealDecrease[ L] = udg_doomHealDecrease[ m]
            set udg_doomHealIntervalCounter[ L] = udg_doomHealIntervalCounter[ m]
            set udg_doomHealLengthCounter[ L] = udg_doomHealLengthCounter[ m]
            set udg_doomHealTarget[ L] = udg_doomHealTarget[ m]
            set udg_doomHealTarget[ m] = null
            call DestroyEffect( udg_doomHealEffectTarget[ L])
            set udg_doomHealEffectTarget[ L] = udg_doomHealEffectTarget[ m]
            set udg_doomHealEffectTarget[ m] = null
            set m = m - 1
            set udg_doomHealMaxIndex = m
            set L = L - 1
        endif
        set L = L + 1
    endloop
endfunction

function DoomHealSetup takes nothing returns nothing
    local unit c = GetTriggerUnit()
    local unit u
    local integer m = udg_doomHealMaxIndex
    local integer p = GetPlayerId( GetTriggerPlayer())
    local integer abiLvl = GetUnitAbilityLevel( c, udg_doomHealSpellId)
    local integer interval = udg_doomHealIntervalBase - ( abiLvl * udg_doomHealIntervalPerLvl)
    local integer length = udg_doomHealLengthBase - ( abiLvl * udg_doomHealLengthPerLvl)
    local real heal = udg_doomHealHealBase - ( abiLvl * udg_doomHealHealPerLvl)
    local real x = GetUnitX( c)
    local real y = GetUnitY( c)
    local real r = udg_doomHealRadiusBase - ( abiLvl * udg_doomHealRadiusPerLvl)
    local real decrease = udg_doomHealDecreaseBase - ( abiLvl * udg_doomHealDecreasePerLvl)
    
    call GroupEnumUnitsInRange( udg_doomHealGroup, x, y, r, null)
    
    loop
        set u = FirstOfGroup( udg_doomHealGroup)
        exitwhen u == null
        if DoomHealFilterUnits( u, c) then
            set m = m + 1
            set udg_doomHealInterval[ m] = interval
            set udg_doomHealLength[ m] = length
            set udg_doomHealHeal[ m] = heal
            set udg_doomHealDecrease[ m] = decrease
            set udg_doomHealIntervalCounter[ m] = 0
            set udg_doomHealLengthCounter[ m] = 0
            set udg_doomHealTarget[ m] = u
            set udg_doomHealEffectTarget[ m] = AddSpecialEffectTarget( udg_doomHealEffect, u, udg_doomHealEffectAttachment)
            
            if m == 1 then
                call TimerStart( udg_doomHealTimer, 0.031250000, true, function DoomHealDamageLoop)
            endif
        endif
        call GroupRemoveUnit( udg_doomHealGroup, u)
    endloop
    
    set udg_doomHealMaxIndex = m
    set c = null
endfunction

function DoomHealCastConditions takes nothing returns boolean
    if GetSpellAbilityId() == udg_doomHealSpellId then
        call DoomHealSetup()
    endif
    return false
endfunction

//===========================================================================
function InitTrig_DoomHeal_Cast takes nothing returns nothing
    local trigger t = CreateTrigger()
    set udg_doomHealTimer = CreateTimer()
    set udg_doomHealGroup = CreateGroup()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_CAST)
    call TriggerAddCondition( t, Condition( function DoomHealCastConditions))
    set t = null
endfunction

JASS:
library DoomHeal

// Doom Heal Spell made by deathismyfriend
// Alloc by Nestharus can be found here. http://www.hiveworkshop.com/forums/jass-resources-412/snippet-alloc-alternative-221493/
// vJass version 1.0.5

globals
    // These are the base values that u can set.
    // Here u set the heal interval base. For every second u need 32. So 5 seconds is 160.
    private integer intervalBase = 160                                                           
    // Here u set the max time for it to end. For every second u need 32. So 5 seconds is 160.
    private integer lengthBase = 1920                                                             
    // This is the damage base. Every interval
    private real healBase = 50.00                                                               
    // This is the radius base
    private real radiusBase = 500.00                                                                 
    // this is the base value that allows u to decrease or increase the amount of health u heal per interval. 
    // Example: the amount it heals at lvl 1 is 200. and u want it to decrease by 20. type in 20 in the variable. This does 200 first time. 180 the next interval 160 the third interval and so on
    private real decreaseBase = 5.00                                                                
    // ----------------------------------------------------------------------------------------------------
    // These are the values that get added to the base per lvl that u can set.
    // Here u set the heal interval per lvl. If u want the time to decrease set it to a positive number. If u want the interval to increase set it to a negative value
    private integer intervalPerLvl = 0                                                                 
    // Here u set the max time for it to end per lvl. For every second u need 32. So 5 seconds is 160.
    private integer lengthPerLvl = 0                                                                  
    // This is the damage per lvl. Every interval
    private real healPerLvl = 0.00                                                                   
    // This is the radius per lvl
    private real radiusPerLvl = 0.00                                                                 
    // this is the base value that allows u to decrease or increase the amount of health u heal per interval. 
    // Example: the amount it heals at lvl 1 is 200. and u want it to decrease by 20. type in 20 in the variable. This does 200 first time. 180 the next interval 160 the third interval and so on
    private real decreasePerLvl = 0.00                                                              
    // ----------------------------------------------------------------------------------------------------
    // These are the other values that u can change                                   
    // set the effect that shows on the units getting healed.
    private constant string EFFECT = "Abilities\\Spells\\Other\\Doom\\DoomTarget.mdl"                              
    // set the attachment point for the unit
    private string EFFECT_ATTACHMENT = "origin"                                                        
    // Set the spell id here
    private integer SPELL_ID = 'A000'
    //Dont change the next couple of things
    private integer maxIndex = 0
    private integer array structIndex
    private timer tmr = CreateTimer()
    private group grp = CreateGroup()
endglobals

    private struct doomHeal extends array
        implement Alloc
        
        private real decrease
        private effect effectTarget
        private real heal
        private integer interval
        private integer intervalCounter
        private integer length
        private integer lengthCounter
        private unit target
        
        // You can add the conditions you want the spell to follow here.
        private static method filterUnits takes unit u, unit c, integer p returns boolean
            if IsUnitOwnedByPlayer( u, Player(p)) and not IsUnitType( u, UNIT_TYPE_STRUCTURE) and u != c /*
                */ and not IsUnitType( u, UNIT_TYPE_DEAD) and GetUnitTypeId( u) != 0 then
                return true
            endif
            return false
        endmethod
        
        private static method create takes real dec, real hl, integer inter, integer lgth, unit u returns thistype
            local thistype this = thistype.allocate()
            set maxIndex = maxIndex + 1
            set this.interval = inter
            set this.length = lgth
            set this.heal = hl
            set this.decrease = dec
            set this.intervalCounter = 0
            set this.lengthCounter = 0
            set this.target = u
            set this.effectTarget = AddSpecialEffectTarget( EFFECT, u, EFFECT_ATTACHMENT)
            return this
        endmethod
        
        private method destroy takes nothing returns nothing
            set this.target = null
            call DestroyEffect( this.effectTarget)
            set this.effectTarget = null
            call this.deallocate()
        endmethod
        
        private static method damageLoop takes nothing returns nothing
            local thistype this
            local integer L = 1
            loop
                exitwhen L > maxIndex
                set this = structIndex[ L]
                set this.intervalCounter = this.intervalCounter + 1
                if this.intervalCounter == this.interval then
                    set this.intervalCounter = 0
                    call SetWidgetLife( this.target, GetWidgetLife( this.target) + this.heal)
                    set this.heal = this.heal - this.decrease
                endif
                set this.lengthCounter = this.lengthCounter + 1
                if this.lengthCounter == this.length or IsUnitType( this.target, UNIT_TYPE_DEAD) or GetUnitTypeId( this.target) == 0 then
                    call this.destroy()
                    set structIndex[ L] = structIndex[ maxIndex]
                    set maxIndex = maxIndex - 1
                    if maxIndex == 0 then
                        call PauseTimer( tmr)
                    endif
                endif
                set L = L + 1
            endloop
        endmethod

        private static method setup takes nothing returns nothing
            local thistype this
            local unit c = GetTriggerUnit()
            local unit u
            local integer p = GetPlayerId( GetTriggerPlayer())
            local integer abiLvl = GetUnitAbilityLevel( c, SPELL_ID)
            local integer inter = intervalBase - ( abiLvl * intervalPerLvl)
            local integer lgth = lengthBase - ( abiLvl * lengthPerLvl)
            local real hl = healBase - ( abiLvl * healPerLvl)
            local real x = GetUnitX( c)
            local real y = GetUnitY( c)
            local real r = radiusBase - ( abiLvl * radiusPerLvl)
            local real dec = decreaseBase - ( abiLvl * decreasePerLvl)
            
            call GroupEnumUnitsInRange( grp, x, y, r, null)
            
            loop
                set u = FirstOfGroup( grp)
                exitwhen u == null
                if thistype.filterUnits(u, c, p) then
                    set this = thistype.create( dec, hl, inter, lgth, u)
                    set structIndex[ maxIndex] = this
                    
                    if maxIndex == 1 then
                        call TimerStart( tmr, 0.031250000, true, function thistype.damageLoop)
                    endif
                endif
                call GroupRemoveUnit( grp, u)
            endloop
            
            set c = null
        endmethod

        private static method castConditions takes nothing returns boolean
            if GetSpellAbilityId() == SPELL_ID then
                call setup()
            endif
            return false
        endmethod

        //===========================================================================
        private static method onInit takes nothing returns nothing
            local trigger t = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_CAST)
            call TriggerAddCondition( t, Condition( function thistype.castConditions))
            set t = null
        endmethod
    
    endstruct
    
endlibrary


version 1.0.5
fixed destroy method​
version 1.0.4
fixed minor mistakes.​
version 1.0.3
fixed things suggested.​
version 1.0.2
fixed the things suggested.
Did not change the multiple constant functions as i believe its nicer when everything is in the globals block​
version 1.0.0.1
made some fixes to code.
made the code easier to read​
version 1.0.0.0
first version released​


Keywords:
GUI, GUI friendly, friendly, Jass, vJass, heal, degrade heal, degrade, deathismyfriend
Contents

Template Map (Map)

Reviews
13:38, 2nd Jun 2013 Magtheridon96: Approved. Pretty much all of these should be constants: // These are the base values that u can set. // Here u set the poison base. For every second u need 32. So 5 seconds is 160. private integer...

Moderator

M

Moderator

13:38, 2nd Jun 2013
Magtheridon96: Approved.

  • Pretty much all of these should be constants:
    JASS:
    // These are the base values that u can set.
        // Here u set the poison base. For every second u need 32. So 5 seconds is 160.
        private integer intervalBase = 160                                                           
        // Here u set the max time for it to end. For every second u need 32. So 5 seconds is 160.
        private integer lengthBase = 1920                                                             
        // This is the damage base. Every interval
        private real healBase = 50.00                                                               
        // This is the radius base
        private real radiusBase = 500.00                                                                 
        // this is the base value that allows u to decrease or increase the amount of health u heal per interval. 
        // Example: the amount it heals at lvl 1 is 200. and u want it to decrease by 20. type in 20 in the variable. This does 200 first time. 180 the next interval 160 the third interval and so on
        private real decreaseBase = 5.00                                                                
        // ----------------------------------------------------------------------------------------------------
        // These are the values that get added to the base per lvl that u can set.
        // Here u set the poison interval per lvl. If u want the time to decrease set it to a positive number. If u want the interval to increase set it to a negative value
        private integer intervalPerLvl = 0                                                                 
        // Here u set the max time for it to end per lvl. For every second u need 32. So 5 seconds is 160.
        private integer lengthPerLvl = 0                                                                  
        // This is the damage per lvl. Every interval
        private real healPerLvl = 0.00                                                                   
        // This is the radius per lvl
        private real radiusPerLvl = 0.00                                                                 
        // this is the base value that allows u to decrease or increase the amount of health u heal per interval. 
        // Example: the amount it heals at lvl 1 is 200. and u want it to decrease by 20. type in 20 in the variable. This does 200 first time. 180 the next interval 160 the third interval and so on
        private real decreasePerLvl = 0.00                                                              
        // ----------------------------------------------------------------------------------------------------
        // These are the other values that u can change                                   
        // set the effect that shows on the units getting healed.
        private constant string EFFECT = "Abilities\\Spells\\Other\\Doom\\DoomTarget.mdl"                              
        // set the attachment point for the unit
        private string EFFECT_ATTACHMENT = "origin"                                                        
        // Set the spell id here
        private integer SPELL_ID = 'A000'
 
Level 33
Joined
Apr 24, 2012
Messages
5,113
Ok here is something that is lighter for variables.
If you want to have constants in JASS, create a constant function
E.g:
JASS:
constant function Value takes nothing returns real
    return 515125.5555
endfunction


This only works for non-handles.


Btw,the globals indention must be aligned with structs.
 
Last edited:
Level 23
Joined
Apr 16, 2012
Messages
4,041
inline castConditions and setup(initialize the locals and if the condition is good, make the stuff happen, then null/destroy the locals in else block or under the script)

JASS:
local group g = CreateGroup()

change local group to global one

Groups have a loot of overhead on them(takes a shit ton of time creating and destroying them, it can even lagg the loop)
make it a global one and clear it after the setup has finished running

I know its your style, but why do you write stuff like ( a, b, c) and not (a, b, c)?
I mean the space after (

also link the Alloc resource, you are using it but you didnt provide a link to it, people may wonder why it doesnt even compile
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
Your group block in the Setup func seems iffy. The loop exits when u == null and you null u after the first iteration. You may want to check that again.

Setup should be combined with Condition. I see no point in separating them. Elaborate if you deem necessary.

I am not really a fan of GUI/JASS hybrid so I found your code slightly repulsive. Besides, too many globals for a JASS code is peculiar imo. Why don't you just stick with pure GUI and custom scripts instead?
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
inline castConditions and setup(initialize the locals and if the condition is good, make the stuff happen, then null/destroy the locals in else block or under the script)

JASS:
local group g = CreateGroup()

change local group to global one

Groups have a loot of overhead on them(takes a shit ton of time creating and destroying them, it can even lagg the loop)
make it a global one and clear it after the setup has finished running

I know its your style, but why do you write stuff like ( a, b, c) and not (a, b, c)?
I mean the space after (

also link the Alloc resource, you are using it but you didnt provide a link to it, people may wonder why it doesnt even compile

ill change the group to a global one. That makes a lot of sense lol.
i write it like this ( a, b, c) because when i had to edit the things before and including the ( it just made it easier to read.

oops i thought i put the link in the spell thing lol sry about that.

Your group block in the Setup func seems iffy. The loop exits when u == null and you null u after the first iteration. You may want to check that again.

Setup should be combined with Condition. I see no point in separating them. Elaborate if you deem necessary.

I am not really a fan of GUI/JASS hybrid so I found your code slightly repulsive. Besides, too many globals for a JASS code is peculiar imo. Why don't you just stick with pure GUI and custom scripts instead?

the set u = null was a mistake lol ill remove that.
it made it easier for the conditions to put them in the group loop rather than to make another function. I would also need to use a lot of GetFilterUnit() in the condition for it if i made it in the function. Almia also suggested it and it seemed like a good idea.

I cant write to much in GUI as the white background gives me migraines after a while. Also ive never really written in normal jass. I switched from GUI to vJass.
I wanted a code that was GUI friendly but something written in Jass because i hate GUI with how slow it is. But i think that if i submit a spell that a GUIer should be able to use it to. I use the globals because otherwise they would have to edit the spell in jass which most GUIers dont like. And i believe they have to add the globals for the spell i use to the map header ? not sure i never used that thing lol.

edit: updated
 
Last edited:
Level 29
Joined
Mar 10, 2009
Messages
5,016
I dont like;
JASS:
// Here u set the poison base. For every second u need 32. So 5 seconds is 160

instead of 160, it could be 1;
JASS:
set this.intervalCounter = this.intervalCounter + 0.03125
if this.intervalCounter > this.interval then
   set this.intervalCounter = 0
endif
and same as lengthBase and a-like

this exitwhen L > maxIndex >> exitwhen L==maxIndex below the L=L+1

the destroy is useless without deallocate

EDIT:
if you wanna use vjass/jass, then post only those versions, not GUI...rating it 3/5 atm...
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
I dont like;
JASS:
// Here u set the poison base. For every second u need 32. So 5 seconds is 160

lol oops that was an old spell that this is based off of i mustve missed deleting that.

instead of 160, it could be 1;
JASS:
set this.intervalCounter = this.intervalCounter + 0.03125
if this.intervalCounter > this.interval then
   set this.intervalCounter = 0
endif
and same as lengthBase and a-like

this exitwhen L > maxIndex >> exitwhen L==maxIndex below the L=L+1

the destroy is useless without deallocate

im not changing the base i rather it be 160 it gives more flexibility for the interval for the spell.

i missed the deallocate tho thanks.

EDIT:
if you wanna use vjass/jass, then post only those versions, not GUI...rating it 3/5 atm...

All my spells are GUI friendly so i have the jass version because that is what i use for GUI friendly. That is how i code. I will not change that.

edit: updated with the fixes
 
Top