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

[JASS] [Solved] How to check units buff state - and enhance Caster per buff state each period?

Status
Not open for further replies.
Level 8
Joined
May 12, 2018
Messages
106
I'm looking to make a spell that gives Rejuvenation to our allies in the target area, and heals immediate additionally when the Rejuvenation buff is gone. (It would be convenient to think that AoE spell version of Lifebloom of WoW Restoration Druid..)
and also, I want to heal Caster as much as Rejuv buffs are remaining in target units if Caster get Ultimate Ability.

I am using RegisterPlayerUnitEvent, SpellEffectEvent, PluginSpellEffect, Utilities, TimerUtils.
The following is a script that I wrote referring to utilities and Jass experts' scripts, but I am experiencing the problem of generating only one Timer and related array(maybe).
Even if there are more than two Rejuv Buffs, only one Healing caster effect occurs. It's hard to write a script beyond my knowledge. I need a hand.

Solved.

JASS:
library DrakonidLifebloom requires RegisterPlayerUnitEvent, SpellEffectEvent, PluginSpellEffect, Utilities, TimerUtils

    globals
      private constant integer SPELL = 'A09D' // HealingSpray
      private constant integer SPELLHEAL = 'A09F' // Caster gets HealingWave each period if he learned ultimate
      private constant integer SPELLDUMMY = 'A09G' // Units within HealingSpray AOE get Rejuvenation Dummy
      private constant integer SPELLFINISHDUMMY = 'A09H' // Target units are healed when rejuvenation buff is gone (time over/dispelled)
      private constant integer YSERA = 'A09E' // Ultimate ability
      private constant integer BUFF0 = 'B01X'  // Rejuvenation Buff
      private constant real period = 0.5
      private constant real HEALEDMANA = 0.75
      private constant real RADIUS = 275
    endglobals
  
    private function filtered takes nothing returns boolean
        //return IsUnitAlly(tia, op) and UnitAlive(target) and not IsUnitType(tia, UNIT_TYPE_MECHANICAL) and not
        return filterG_NdNhidNimmNsNw() and not IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL)
       // filterGs for not dead, not hidden, not immune, not structure, not ward
    endfunction

    private struct Bloom
        static thistype array blooming
      
        timer timer
        unit source
        unit target
        player player
        integer id
        boolean hasbuff = false
                //group units
                integer spelllevel
      
        method destroy takes nothing returns nothing
                    local real x = GetUnitX(target)
                    local real y = GetUnitY(target)
                    local unit locust = CreateUnit(player, 'u003', x, y, dummylife1)

                    call UnitApplyTimedLife(locust, 'BTLF', dummylife1)
                    call UnitAddAbility( locust, SPELLFINISHDUMMY )
                    call SetUnitAbilityLevel( locust, SPELLFINISHDUMMY, spelllevel )
                    call IssueTargetOrderById( locust, OrderId_healwave, target )
                  

            set blooming[id] = 0
          
            call ReleaseTimer(timer)
            call deallocate()
          
            set timer = null
            set source = null
            set target = null
            set player = null
                    set locust = null
        endmethod
      
        private static method onDeath takes nothing returns nothing
            local integer id = GetUnitUserData(GetTriggerUnit())
            local thistype this
          
            if blooming[id] != 0 then
                set this = blooming[id]
                call destroy()
            endif
        endmethod
      
        static method Loop takes nothing returns nothing
            local thistype this = GetTimerData(GetExpiredTimer())
                    local real x = GetUnitX(source)
                    local real y = GetUnitY(source)
                    local integer yseragift = GetUnitAbilityLevel(source, YSERA)
                    local unit locust
          
                    if GetUnitAbilityLevel(target, BUFF0) > 0 then
              if not hasbuff then
                        set hasbuff = true
                      endif
                      if yseragift > 0 then
                        call SetUnitState( source, UNIT_STATE_MANA, GetUnitState(source, UNIT_STATE_MANA)+(HEALEDMANA * yseragift) )
                        set locust = CreateUnit(player, 'u003', x, y, dummylife1)
                        call UnitApplyTimedLife(locust, 'BTLF', dummylife1)
                        call UnitAddAbility( locust, SPELLHEAL )
                        call SetUnitAbilityLevel( locust, SPELLHEAL, yseragift )
                        call IssueTargetOrderById( locust, OrderId_healwave, source )
                        set locust = null
                      endif
                    endif
                if hasbuff then
                      if GetUnitAbilityLevel(target, BUFF0) < 1 then
                        call destroy()
                      endif
                    endif

                    /*if not hasbuff then
                      if GetUnitAbilityLevel(target, BUFF0) < 1 and GetUnitAbilityLevel(target, BUFF1) < 1 and GetUnitAbilityLevel(target, BUFF2) < 1 then
                        call destroy()
                      endif
                    endif*/

                   set locust = null
        endmethod
      
        static method onCast takes nothing returns nothing
            local thistype this
                    local unit thefirst
                    local real x = Spell.x
                    local real y = Spell.y
                    local group unitsdispos = CreateGroup()
                    local group unitsdispos2 = CreateGroup()
                    local integer size
                    local player playerlocal = Spell.source.player
                    local unit locust

                    //call GroupEnumUnitsInRange(unitsdispos, x, y, RADIUS, Filter(function filterG_NdNhidNimmNinvNsNw))
                    call GroupEnumUnitsInRange(unitsdispos, x, y, RADIUS, Filter(function filtered))
                    set size = BlzGroupGetSize(unitsdispos)
                    if size > 0 then
                      loop
                        set thefirst = FirstOfGroup(unitsdispos)
                        exitwhen thefirst == null

                        if IsUnitAlly(thefirst, playerlocal) then
                          call GroupAddUnit(unitsdispos2, thefirst)
                        endif

                        call GroupRemoveUnit(unitsdispos, thefirst)
                        set thefirst = null
                      endloop
                    endif
                    set size = BlzGroupGetSize(unitsdispos2)
                    if size > 0 then
                      loop
                        set thefirst = FirstOfGroup(unitsdispos2)
                        exitwhen thefirst == null
                    
                        //if IsUnitAlly(thefirst, player) and not IsUnitType(thefirst, UNIT_TYPE_MECHANICAL) then
                          if blooming[GetUnitUserData(thefirst)] != 0 then
                            set this = blooming[GetUnitUserData(thefirst)]
                          else
                            set this = thistype.allocate()
                            set timer = NewTimerEx(this)
                            set id = GetUnitUserData(thefirst)
                        set target = thefirst
                            set blooming[id] = this
                            set spelllevel = Spell.level

                            set locust = CreateUnit(playerlocal, 'u003', x, y, dummylife1)
                            call UnitApplyTimedLife(locust, 'BTLF', dummylife1)
                            call UnitAddAbility( locust, SPELLDUMMY )
                            call SetUnitAbilityLevel( locust, SPELLDUMMY, spelllevel )
                            call IssueTargetOrderById( locust, OrderId_rejuv, thefirst )

                            call TimerStart(timer, period, true, function thistype.Loop)
                          endif
                        //endif

                        //call GroupAddUnit(units, thefirst)
                        call GroupRemoveUnit(unitsdispos2, thefirst)
                        set thefirst = null
                      endloop
                    endif
          
                set source = Spell.source.unit
                    set player = Spell.source.player
          
                    call DestroyGroup(unitsdispos)
                    call DestroyGroup(unitsdispos2)
                    set unitsdispos = null
                    set unitsdispos2 = null
                    set thefirst = null
                    set playerlocal = null
                    set locust = null
        endmethod
  
        private static method onInit takes nothing returns nothing
            call RegisterSpellEffectEvent(SPELL, function thistype.onCast)
            call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function thistype.onDeath)
        endmethod
    endstruct
endlibrary
 
Last edited:
Status
Not open for further replies.
Top