Spell Golden Strike

WolfieeifloW

WEHZ Helper
Reaction score
372
I leave them up here in case people want to see how the spell has progressed.
And for me, since I delete/overwrite old versions :rolleyes: .

And glad you like it ;) !
 

Viikuna

No Marlo no game.
Reaction score
265
Using one global caster dummy would be a good idea.
 

WolfieeifloW

WEHZ Helper
Reaction score
372
It's basically the same thing.
With no real noticeable change in speed/efficiency.

Thanks for the kind comment BRUTAL :) .
 

Viikuna

No Marlo no game.
Reaction score
265
CreateUnit is probably the slowest native there is, so you should avoid it whenever you can. ( Isnt that what they call optimization? The reason why we dont support most BJ functions and slow ways of doing things. )
 

Azlier

Old World Ghost
Reaction score
461
That, and units leave quite a bit of data behind even after removal. You could say that units are unfixable leaks. Unit recycling solves a lot of problems.
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
Use estimated countdown instead of counting distance between target.
It is better since it is no need to count the distance every execution.

The script is here

JASS:
  private struct data
        unit caster
        unit target
        unit dummy
        unit sfxdum
        real cx
        real cy
        real tx
        real ty
        real xx
        real yy
        real facing
        integer level
        group hit
        timer t
        integer loopz
        
        method onDestroy takes nothing returns nothing
            call GroupClear(.hit)
        endmethod
    endstruct

    globals
        private constant real PERIOD = 0.03125
        private constant real DSPEED = SPEED * PERIOD
        private real dbx = 0.
        private real dby = 0.
        private player GSPLAYER
        private group GSGROUP = CreateGroup()
        private data DATA 
    endglobals
    
//====================================================================================================    
    private function OtherActions takes nothing returns boolean
        if (GetTriggerEventId() == EVENT_PLAYER_HERO_SKILL and GetLearnedSkill() == GSID) then
            call UnitAddAbility(GetLearningUnit(), GPID)
        elseif (GetTriggerEventId() == EVENT_PLAYER_UNIT_DEATH and GetUnitAbilityLevel(GetKillingUnit(), GSID) > 0 and GetUnitAbilityLevel(GetKillingUnit(), GPID) <= 19 + (GetUnitAbilityLevel(GetKillingUnit(), GSID) * 15) and not IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE)) then
            call SetUnitAbilityLevel(GetKillingUnit(), GPID, GetUnitAbilityLevel(GetKillingUnit(), GPID) + 1)
        endif
        return false
    endfunction
    
    private function GroupConditions takes nothing returns boolean
        return not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) and GetWidgetLife(GetFilterUnit()) >= 0.405 and IsUnitEnemy(GetFilterUnit(), GSPLAYER) and not IsUnitInGroup(GetFilterUnit(), DATA.hit)// and GetUnitAbilityLevel(GetFilterUnit(), DEBUFF) <= 0
    endfunction
    
//====================================================================================================
    private function Periodic takes nothing returns nothing
        local data d = GetTimerData(GetExpiredTimer())
        local unit FoG

        set d.tx = GetUnitX(d.target)
        set d.ty = GetUnitY(d.target)
        set dbx = d.tx - d.xx
        set dby = d.ty - d.yy
        if d.loopz < 0 then
            call DestroyEffect(AddSpecialEffect(SFX, d.xx, d.yy))
            set GSPLAYER = GetOwningPlayer(d.caster)
            set DATA = d
            call GroupEnumUnitsInRange(GSGROUP, d.xx, d.yy, AOE(d.level), Condition(function GroupConditions))
            loop
            set FoG = FirstOfGroup(GSGROUP)
            exitwhen FoG == null
                set d.dummy = CreateUnit(GetOwningPlayer(d.caster), DUMID, GetUnitX(FoG), GetUnitY(FoG), bj_UNIT_FACING)
                call UnitAddAbility(d.dummy, GKID)
                call SetUnitAbilityLevel(d.dummy, GKID, d.level)
                call IssueTargetOrder(d.dummy, DEBUFFORDER, FoG)
                call UnitApplyTimedLife(d.dummy, 'BTLF', 1.00)
                call UnitDamageTarget(d.caster, FoG, DAMAGE(GetUnitAbilityLevel(d.caster, GPID)), true, true, ATKTYPE, DMGTYPE, WEAPON_TYPE_WHOKNOWS)
                call GroupRemoveUnit(GSGROUP, FoG)
                call GroupAddUnit(d.hit, FoG)
            endloop
            call RemoveUnit(d.sfxdum)
            call SetUnitAbilityLevel(d.caster, GPID, 1)
            call ReleaseTimer(d.t)
            call d.destroy()
        endif
        set d.facing = Atan2(d.ty - d.yy, d.tx - d.xx)
        set d.xx = d.xx + DSPEED * Cos(d.facing)
        set d.yy = d.yy + DSPEED * Sin(d.facing)
        call SetUnitX(d.sfxdum, d.xx)
        call SetUnitY(d.sfxdum, d.yy)
        call DestroyEffect(AddSpecialEffect(SFX, d.xx, d.yy))
        set GSPLAYER = GetOwningPlayer(d.caster)
        set DATA = d
        call GroupEnumUnitsInRange(GSGROUP, GetUnitX(d.sfxdum), GetUnitY(d.sfxdum), AOE(d.level), Condition(function GroupConditions))
        loop
        set FoG = FirstOfGroup(GSGROUP)
        exitwhen FoG == null
            set d.dummy = CreateUnit(GetOwningPlayer(d.caster), DUMID, GetUnitX(FoG), GetUnitY(FoG), bj_UNIT_FACING)
            call UnitAddAbility(d.dummy, GKID)
            call SetUnitAbilityLevel(d.dummy, GKID, d.level)
            call IssueTargetOrder(d.dummy, DEBUFFORDER, FoG)
            call UnitApplyTimedLife(d.dummy, 'BTLF', 1.00)
            call UnitDamageTarget(d.caster, FoG, DAMAGE(GetUnitAbilityLevel(d.caster, GPID)), true, true, ATKTYPE, DMGTYPE, WEAPON_TYPE_WHOKNOWS)
            call GroupRemoveUnit(GSGROUP, FoG)
            call GroupAddUnit(d.hit, FoG)
        endloop
        set d.loopz = d.loopz - 1
    endfunction
    
    private function Conditions takes nothing returns boolean
        local data d
        if (GetSpellAbilityId() == GSID and GetUnitTypeId(GetDyingUnit()) != SFXID and GetUnitTypeId(GetDyingUnit()) != DUMID) then
            set d = data.create()
            if d.hit == null then
                set d.hit = CreateGroup()
            endif
            set d.caster = GetTriggerUnit()
            set d.target = GetSpellTargetUnit()
            set d.cx = GetUnitX(d.caster)
            set d.cy = GetUnitY(d.caster)
            set d.level = GetUnitAbilityLevel(d.caster, GSID)
            set d.tx = GetUnitX(d.target)
            set d.ty = GetUnitY(d.target)
            set d.sfxdum = CreateUnit(GetOwningPlayer(d.caster), SFXID, d.cx, d.cy, bj_UNIT_FACING)
            set d.xx = GetUnitX(d.sfxdum)
            set d.yy = GetUnitY(d.sfxdum)
            set d.loopz = R2I(SquareRoot(d.cx * d.tx + d.cy * d.ty) / DSPEED)
            
            set d.t = NewTimer()
            call SetTimerData(d.t, d)
            call TimerStart(d.t, PERIOD, true, function Periodic)
        endif
        return false
    endfunction
 

WolfieeifloW

WEHZ Helper
Reaction score
372
kingkingyyk3;
That wouldn't work because as soon as the target moves the spell will stop before it reaches him/her.

As for using one dummy;
It causes the infinite SFX bug to occur for some reason :confused: .
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top