Spell never Executes?

Gtam

Lerning how to write and read!! Yeah.
Reaction score
164
JASS:
scope SoB initializer Init

    globals
        private constant integer AbilId = 'A017'
        private constant integer DumyId = 'D017'
        private constant string FX = "Abilities\\Spells\\Human\\StormBolt\\StormBoltMissile.mdl"
    endglobals
    
    private function Conditions takes nothing returns boolean
        call BJDebugMsg("Conds")
        return GetSpellAbilityId() == AbilId
    endfunction
    
    struct SoB extends array
        //! runtextmacro AIDS()
        group g
        real x
        real y
        real ang
        unit dumy
        effect e
        integer lvl
        integer t
        
        method AIDS_OnCreate takes nothing returns nothing
            set .g = CreateGroup()
        endmethod
    endstruct
    
    private function Filt takes nothing returns boolean
        local unit u = GetFilterUnit()
        return IsUnitType(u, UNIT_TYPE_STRUCTURE) == false and IsUnitEnemy(u, GetOwningPlayer(GetTriggerUnit())) == true
    endfunction
    
    private function Periodic takes nothing returns nothing
        local SoB data = GetTimerData(GetExpiredTimer())
        local unit u
        local unit d
        set data.t = data.t - 1
        if data.t >= 0 then
            set data.x = GetOffsetX(GetUnitX(data.dumy), 10, data.ang)
            set data.y = GetOffsetY(GetUnitY(data.dumy), 10, data.ang)
            call SetUnitX(data.dumy, data.x)
            call SetUnitY(data.dumy, data.y)
            call GroupEnumUnitsInRange(data.g, data.x, data.y, 225, Condition(function Filt))
            set d = GetCaster(data.x, data.y)
            call UnitAddAbility(d, DumyId)
            call SetUnitAbilityLevel(d, DumyId, data.lvl)
            loop
                set u = FirstOfGroup(data.g)
                exitwhen u == null
                call IssueTargetOrder(d, "stormbolt", u)
            endloop
        else
            call CasterDone(data.dumy, 0)
            call DestroyEffect(data.e)
            call FreeDTimer(GetExpiredTimer())
        endif
    endfunction
    
    private function Actions takes nothing returns nothing
        local SoB data = SoB[GetTriggerUnit()]
        local timer ti = GetDTimer()
        set data.lvl = GetUnitAbilityLevel(GetTriggerUnit(), AbilId)
        set data.t = 96
        set data.x = GetUnitX(GetTriggerUnit())
        set data.y = GetUnitY(GetTriggerUnit())
        set data.ang = GetAngleBetweenXY(data.x, data.y, GetSpellTargetX(), GetSpellTargetY())
        set data.dumy = GetCaster(data.x, data.y)
        set data.e = AddSpecialEffectTarget(FX, data.dumy, "origin")
        call SetTimerData(ti, data)
        call TimerStart(ti, 0.03125, true, function Periodic)
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call BJDebugMsg("Init")
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition(function Conditions))
        call TriggerAddAction(t, function Actions)
    endfunction

endscope


Is see the Two BJDebugMsg but when i put one in the actions i dont see it?
Whats wrong?
 

Komaqtion

You can change this now in User CP.
Reaction score
469
Ok, well then please tell what this is:
JASS:
local timer ti = GetDTimer()
//
GetAngleBetweenXY(data.x, data.y, GetSpellTargetX(), GetSpellTargetY())
//
set data.dumy = GetCaster(data.x, data.y)


?

Maybe it's one of them that's breaking the thread in the actions...
Btw, where did yo put the debug msg in the actions ?

Since, if it shows if it's the first line (After the locals) that means something inside there is breaking the thread ;)
 

Gtam

Lerning how to write and read!! Yeah.
Reaction score
164
they are my system functions and they work fine in other spells
 

Komaqtion

You can change this now in User CP.
Reaction score
469
Well, try putting debug messages after each line in that actions function... See if any of them displays :D
 

Gtam

Lerning how to write and read!! Yeah.
Reaction score
164
Okay this is what i have now the bolt is moving but the only problem now is it lags a little and the dummies never casts the bolts on the group.

JASS:
scope SoB initializer Init

    globals
        private constant integer SoBId = 'A017'
        private constant integer DumyId = 'D017'
        private constant integer BoltId = 'u000'
    endglobals
    
    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == SoBId
    endfunction
    
    struct SoB extends array
        //! runtextmacro AIDS()
        group g
        real x
        real y
        real ang
        unit Cast
        unit dumy
        integer lvl
        integer t
        
        static method filt takes nothing returns boolean
            local unit u = GetFilterUnit()
            return IsUnitType(u, UNIT_TYPE_STRUCTURE) == false and IsUnitEnemy(u, GetOwningPlayer(GetTriggerUnit())) == true
        endmethod
    endstruct
    
    private function Periodic takes nothing returns nothing
        local SoB data = GetTimerData(GetExpiredTimer())
        local unit u
        local unit d
        set data.t = data.t - 1
        if data.t >= 0 then
            set data.x = GetOffsetX(GetUnitX(data.dumy), 20, data.ang)
            set data.y = GetOffsetY(GetUnitY(data.dumy), 20, data.ang)
            call SetUnitX(data.dumy, data.x)
            call SetUnitY(data.dumy, data.y)
            call GroupEnumUnitsInRange(data.g, data.x, data.y, 225, Condition(function SoB.filt))
            set d = GetCaster(GetOwningPlayer(data.Cast),data.x, data.y)
            call UnitAddAbility(d, DumyId)
            call SetUnitAbilityLevel(d, DumyId, data.lvl)
            loop
                set u = FirstOfGroup(data.g)
                exitwhen u == null
                call IssueTargetOrder(d, "thunderbolt", u)
            endloop
            call CasterDone(d, DumyId)
        else
            call RemoveUnit(data.dumy)
            call DestroyGroup(data.g)
            call CasterDone(data.dumy, 0)
            call FreeDTimer(GetExpiredTimer())
        endif
    endfunction
    
    private function Actions takes nothing returns nothing
        local SoB data = SoB[GetTriggerUnit()]
        local timer ti = GetDTimer()
        set data.Cast = GetTriggerUnit()
        set data.lvl = GetUnitAbilityLevel(data.Cast, SoBId)
        set data.g = CreateGroup()
        set data.t = 64
        set data.x = GetUnitX(data.Cast)
        set data.y = GetUnitY(data.Cast)
        set data.ang = GetAngleBetweenXY(data.x, data.y, GetSpellTargetX(), GetSpellTargetY())
        set data.dumy = CreateUnit(GetOwningPlayer(data.Cast), BoltId, GetOffsetX(data.x, 50, data.ang), GetOffsetY(data.y, 50, data.ang), data.ang)
        call SetUnitPathing(data.dumy, false)
        call SetTimerData(ti, data)
        call TimerStart(ti, 0.03125, true, function Periodic)
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition(function Conditions))
        call TriggerAddAction(t, function Actions)
    endfunction

endscope
 

Gtam

Lerning how to write and read!! Yeah.
Reaction score
164
The timer. I made my system preload more timers and it worked.
And what about the Lag? any way to make code more effeciant

Oh no it should be DumyId, BoltId it the dummy unit that looks like the bolt.
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216

Gtam

Lerning how to write and read!! Yeah.
Reaction score
164
what do you mean by passing struct to filter functions? The Struct instance?
 

Immolation

Member
Reaction score
20
1) No point in using AIDS with this.
2) Use GTrigger, run your functions through a condition instead of an action.
3) Remove the FirstOfGroup() loop and do the stuff inside it directly in the enum.
4) Implement DummyCaster too and use it for your needs.
5) Use KT/T32 for your timers since I bet they're better than whatever you're currently using(seems like a strange version of TimerUtils).
They run better on these lows periods.

If you have any questions, feel free to ask.
 

Jesus4Lyf

Good Idea™
Reaction score
397
JASS:
        method AIDS_OnCreate takes nothing returns nothing
            set .g = CreateGroup()
        endmethod

-->
JASS:
        method AIDS_/*note the case of the next letter, then delete this comment*/onCreate takes nothing returns nothing
            if .g!=null then /* saves a leak */
                set .g = CreateGroup()
            endif
        endmethod

>No point in using AIDS with this.
Whilst I agree, I don't think you should hound this point. It's actually more efficient to use AIDS to get an index than create/destroy a struct. Easily. So if it's for personal use, let him - it may be a good thing.
 

Gtam

Lerning how to write and read!! Yeah.
Reaction score
164
Found the problem guys.
I was never removing the FirstOfGroup() unit at the end of a loop causing infinite loop == lag.

Hehe Post 3,123
And yes its for my own map that im createing and i like using AIDS.
 

Gtam

Lerning how to write and read!! Yeah.
Reaction score
164
Okay ill get T32 and im using a modified Dummy Caster. Instead of one i have 5. Why not use AIDS? If i use ForGroup how will i get the struct instance without AIDS?
 

Immolation

Member
Reaction score
20
Make filt a function, and do all the things you do in the loop there.

JASS:
call GroupEnumUnitsInRange(..., Filter(function YourFunction))

private function YourFunction takes nothing returns boolean
      if (your conditions) then
          ...
      endif
      return false
endfunction.


Also, convert your actions to conditions(implement GT too), the latter are much faster.
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
If missle is still sliding and the unit casts same spell, you will be in trouble.

Anyway, fixed version here :
JASS:
scope SoB initializer Init
    
    private keyword Data
    
    globals
        private constant integer SoBId = 'A017'
        private constant integer DumyId = 'D017'
        private constant integer BoltId = 'u000'
        
        private group enumGroup = CreateGroup()
        private conditionfunc cf
        private Data d
        private unit DummyCaster
    endglobals
    
    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == SoBId
    endfunction
    
    private struct Data
        group g
        real x
        real y
        real tx
        real ty
        real ang
        real cos
        real sin
        unit cs
        unit dummy
        integer lv
        integer tick
        timer t
        player p
        
        static method effects takes nothing returns boolean
            local unit u = GetFilterUnit()
            local thistype this = d
            if IsUnitEnemy(u,.p) and IsUnitType(u,UNIT_TYPE_STRUCTURE) == false and not IsUnitInGroup(u,.g) then
                call IssueTargetOrder(DummyCaster,"thunderbolt",u)
                call GroupAddUnit(.g,u)
            endif
            set u = null
            return false
        endmethod
        
        static method periodic takes nothing returns nothing
            local thistype this = GetTimerData(GetExpiredTimer())
            if .tick > 0 then
                set .tick = .tick - 1
                set .x = .x + .cos
                set .y = .y + .sin
                call SetUnitX(.dummy,.x)
                call SetUnitY(.dummy,.y)
                set d = this
                set DummyCaster = GetCaster(.p,.x,.y)
                call UnitAddAbility(DummyCaster, DumyId)
                call SetUnitAbilityLevel(DummyCaster, DumyId, .lv)
                call GroupEnumUnitsInRange(enumGroup,.x,.y,225.,cf)
                call CasterDone(DummyCaster, DumyId)
            else
                call .destroy()
            endif
        endmethod
        
        static method add takes nothing returns nothing //Darn, the create method needs the returning of instance. ><
            local thistype this = thistype.create()
            local real dx
            local real dy
            set .cs = GetTriggerUnit()
            set .tx = GetSpellTargetX()
            set .ty = GetSpellTargetY()
            set .x = GetUnitX(.cs)
            set .y = GetUnitY(.cs)
            set dx = .tx - .x
            set dy = .ty - .y
            set .angle = Atan2(dy,dx)
            set .cos = 20. * .angle
            set .sin = 20. * .angle
            set .tick = R2I(SquareRoot(dx * dx + dy * dy) / 20.)
            if .g == null then
                set .g = CreateGroup()
            endif
            set .p = GetOwningPlayer(.cs)
            set .dummy = CreateUnit(.p,BoltId,.x,.y,.angle * 57.2958)
            set .lv = GetUnitAbilityLevel(.cs,SoBId)
            set .t = GetDTimer()
            call SetTimerData(.t,this)
            call TimerStart(.t,.03125,true,function periodic)
        endmethod
        
        method onDestroy takes nothing returns nothing
            call RemoveUnit(.dummy)
            call GroupClear(.g)
            call FreeDTimer(.t)
        endmethod
    endstruct
    
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition(function Conditions))
        call TriggerAddAction(t, function Data.add)
    endfunction

endscope


Also, convert your actions to conditions(implement GT too), the latter are much faster.
Hmm, faster by nanoseconds. :p
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
This is depends on people's preference. For me, I am using my spell system instead the old style init. The old style init is bad ><. It will evaluates all spells' condition, works inefficiently.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top