call somefunctionname.execute()

prismpirate

New Member
Reaction score
2
My map fatal errors when I use a certain spell too much (Code found below)

I suspect that "call somefunctioname.execute() " causes this. Is it due to this or is it because of other reasons.

JASS:
scope tornado initializer Init
    globals
        private constant integer spellid = 'A014'
        private constant integer spellid2 = 'A01O'
        private constant integer tornadodummyid = 'u009'
        private constant integer tornadodummyspellid = 'A016'
        private constant real tornadodummylifespan = 8.0 //Lifespan of Tornado
        private constant real periodicinterval = 0.02 //How often the trigger runs. Lower values for smoother movement. Higher values for less lag
    endglobals  
    private function tornadomovementint takes unit tornado returns nothing
        local integer index = 0
        local real angle = GetUnitFacing(tornado)
        local real xoffset = 300*Cos(Deg2Rad(angle))
        local real yoffset = 300*Sin(Deg2Rad(angle))
        local group tempgroup
        local location temppoint
        loop
            exitwhen index > 50
            call IssuePointOrder(tornado,"move",GetUnitX(tornado) + xoffset,GetUnitY(tornado) + yoffset)
            call TriggerSleepAction(0.025)
            call SetUnitX(tornado, GetUnitX(tornado) + xoffset)
            call SetUnitY(tornado, GetUnitY(tornado) + yoffset)
            set index = index+1
        endloop
        call RemoveLocation(temppoint)
        call DestroyGroup(tempgroup)
    endfunction
    private function tornadoactions takes nothing returns nothing
        local unit tornado
        local real x = GetUnitX(GetTriggerUnit())
        local real y = GetUnitY(GetTriggerUnit())
        local real angle = GetUnitFacing(GetTriggerUnit())
        set tornado = CreateUnit(GetOwningPlayer(GetTriggerUnit()),tornadodummyid,x,y,angle)
        call UnitAddAbility(tornado,tornadodummyspellid)
        call UnitApplyTimedLife(tornado, 'BTLF', 3)
        call tornadomovementint.execute(tornado)
        set tornado = null
    endfunction
    private function tornadocondition takes nothing returns boolean
        return GetSpellAbilityId() == spellid or GetSpellAbilityId() == spellid2
    endfunction
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()    
        local integer index = 0
        loop
            call TriggerRegisterPlayerUnitEvent(t, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
            set index = index + 1
            exitwhen index == 15
        endloop
        call TriggerAddCondition(t, Condition(function tornadocondition))
        call TriggerAddAction(t, function tornadoactions)
        endfunction
endscope
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
It is this :
JASS:
call tornadomovementint(tornado)


Inline the function in the action is better.
And, your function name is confusing. Just put Cond, Act, Effect is enough and easy to read.
 

Exide

I am amazingly focused right now!
Reaction score
448
OnTopic:
EDIT: Actually, it does seem like .execute causes the crash.
You can probably fix it by making 'tornado' a global unit. (And don't null it.)

I'm too lazy to read all your code. (Though I sugest you put a few spaces here and there for readability.)
This looks a bit faulty, imo:
JASS:

local real xoffset = 300*Cos(Deg2Rad(angle))
local real yoffset = 300*Sin(Deg2Rad(angle))


Also, why do you set a tempgroup and temppoint, that you don't use?


What is inlining?

Inlining = when you put all values in the same line.
For example:

JASS:

call DestroyEffect(AddSpecialEffect("blabla.mdl", x, y))

-this is inlined.

Why is there the .execute part? remove it

.execute is there to do some magic, that allows the function to run by itself. -Very useful when using waits.
If you run a function, from another function, that has waits in it, both functions will wait, until the waits are done.
With .execute you can run both functions at the same time, independent of each other.
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
I means :
You should inline it like this
JASS:
scope tornado initializer Init
    globals
        private constant integer SPELL_ID = 'A014'
        private constant integer SPELL_ID2 = 'A01O'
        private constant integer DUMMY_ID = 'u009'
        private constant integer DUMMY_SPELL_ID = 'A016'
        private constant real DUMMY_LIFE = 8.0 //Lifespan of Tornado
        private constant real INTERVAL = 0.02 //How often the trigger runs. Lower values for smoother movement. Higher values for less lag
    endglobals  
    
    private function Act takes nothing returns nothing
        local real x = GetUnitX(GetTriggerUnit())
        local real y = GetUnitY(GetTriggerUnit())
        local real angle = GetUnitFacing(GetTriggerUnit())
        local integer index = 0
        local real xoffset = 300.*Cos(Deg2Rad(angle))
        local real yoffset = 300.*Sin(Deg2Rad(angle))
        local group tempgroup
        local location temppoint
        local unit tornado = CreateUnit(GetOwningPlayer(GetTriggerUnit()),DUMMY_ID,x,y,angle)
        call UnitAddAbility(tornado,DUMMY_SPELL_ID)
        call UnitApplyTimedLife(tornado, 'BTLF', 3)
        loop
            exitwhen index > 50
            call IssuePointOrder(tornado,"move",GetUnitX(tornado) + xoffset,GetUnitY(tornado) + yoffset)
            call SetUnitX(tornado, GetUnitX(tornado) + xoffset)
            call SetUnitY(tornado, GetUnitY(tornado) + yoffset)
            call TriggerSleepAction(0.025)
            set index = index+1
        endloop
        call RemoveLocation(temppoint)
        call DestroyGroup(tempgroup)
        set tornado = null
    endfunction
    
    private function Cond takes nothing returns boolean
        return GetSpellAbilityId() == SPELL_ID or GetSpellAbilityId() == SPELL_ID2
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()    
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        //Since there is a BJ simplifies your code, why not use it?
        //Plus, it will not affect performance because it is only loaded at map initialization
        call TriggerAddCondition(t, Condition(function Cond))
        call TriggerAddAction(t, function Act)
    endfunction
endscope
 

RaiJin

New Member
Reaction score
40
I means :
You should inline it like this
JASS:
scope tornado initializer Init
    globals
        private constant integer SPELL_ID = 'A014'
        private constant integer SPELL_ID2 = 'A01O'
        private constant integer DUMMY_ID = 'u009'
        private constant integer DUMMY_SPELL_ID = 'A016'
        private constant real DUMMY_LIFE = 8.0 //Lifespan of Tornado
        private constant real INTERVAL = 0.02 //How often the trigger runs. Lower values for smoother movement. Higher values for less lag
    endglobals  
    
    private function Act takes nothing returns nothing
        local real x = GetUnitX(GetTriggerUnit())
        local real y = GetUnitY(GetTriggerUnit())
        local real angle = GetUnitFacing(GetTriggerUnit())
        local integer index = 0
        local real xoffset = 300.*Cos(Deg2Rad(angle))
        local real yoffset = 300.*Sin(Deg2Rad(angle))
        local group tempgroup
        local location temppoint
        local unit tornado = CreateUnit(GetOwningPlayer(GetTriggerUnit()),DUMMY_ID,x,y,angle)
        call UnitAddAbility(tornado,DUMMY_SPELL_ID)
        call UnitApplyTimedLife(tornado, 'BTLF', 3)
        loop
            exitwhen index > 50
            call IssuePointOrder(tornado,"move",GetUnitX(tornado) + xoffset,GetUnitY(tornado) + yoffset)
            call SetUnitX(tornado, GetUnitX(tornado) + xoffset)
            call SetUnitY(tornado, GetUnitY(tornado) + yoffset)
            call TriggerSleepAction(0.025)
            set index = index+1
        endloop
        call RemoveLocation(temppoint)
        call DestroyGroup(tempgroup)
        set tornado = null
    endfunction
    
    private function Cond takes nothing returns boolean
        return GetSpellAbilityId() == SPELL_ID or GetSpellAbilityId() == SPELL_ID2
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()    
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        //Since there is a BJ simplifies your code, why not use it?
        //Plus, it will not affect performance because it is only loaded at map initialization
        call TriggerAddCondition(t, Condition(function Cond))
        call TriggerAddAction(t, function Act)
    endfunction
endscope

remove call RemoveLocation(temppoint) and the variable itself

same with the group variable, your basically doing call RemoveLocation(null) and call DestroyGroup(null) which is bad

get a local unit and set it to trigger unit because your calling to way to much and it could be much faster with a local
 

prismpirate

New Member
Reaction score
2
The remove location and groups were leftover from previous code. I must have missed them. The thing still hangs when many tornadoes are spammed. I am no longer using .execute. Could it be the loop?
 

RaiJin

New Member
Reaction score
40
JASS:
call IssuePointOrder(tornado,"move",GetUnitX(tornado) + xoffset,GetUnitY(tornado) + yoffset)


whats the point of this function call when you already set the unit to that x and y?

it may be because its not "mui" then again you are just using locals here

edit: honestly remove that loop and use a timer instead, because waits are horrid because of inaccuracy, my solution to your problem is using a timer, if you need this to be MUI then use structs with a timer attachment system
 

prismpirate

New Member
Reaction score
2
Hmm, any link to a tutorial on timers? I see people mention them, but can't seem to understand how they work
 

prismpirate

New Member
Reaction score
2
I understand structs now, but can't follow his tutorials. Is there any example that uses timers in spells that I can refer to. I learn better from example.
 

Larcenist

REP: Respect, Envy, Prosperity?
Reaction score
211
JASS:
scope StructStack initializer Init
    
    private keyword Data
    
    globals
        private constant integer ABIL_ID = 'A000'
        private constant real TIMER_PERIOD = 0.03125
        
        private Data array D    //Could be added in a global block below the struct declaration, which removes the use of the keyword.
                                //Can also be an integer variable with a little altering rather than struct variable.
        private timer T = CreateTimer() //Our global timer that'll handle all instances running.
        private integer N = 0   //Instance counter
    endglobals
    
    private struct Data
        real elapsedtime = 0.  //Example member
        real maxtime = 2.  //Example member
    endstruct
    
    private function TimerCallback takes nothing returns nothing
        local integer i = N //Looping backwards is a lot easier than looping forwards imo
        local Data d
        loop
            exitwhen i <= 0
            set d = i<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" /> //This is the same as &quot;set d = D<i>&quot;
            set d.elapsedtime = d.elapsedtime + TIMER_PERIOD
            if (d.elapsedtime &gt;= d.maxtime) then    //Some condition that tells when to remove the struct instance from the stack.
                call d.destroy()
                
                set i<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" /> = N<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />   //Recycles the struct stack, moving the top instance to the location of the removed instance.
                set N = N - 1
                if (N == 0) then
                    call PauseTimer(T)
                endif
            else
                //Do actions
            endif
            
            set i = i - 1
        endloop
    endfunction
    
    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == ABIL_ID
    endfunction
    
    private function Actions takes nothing returns nothing
        local Data d = Data.create()
        
        //Set whatever data that needs setting in the struct, either here or by using a create method.
        
        set N = N + 1
        set N<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" /> = d //Same as &quot;set D[N] = d&quot;
        if (N == 1) then
            call TimerStart(T, TIMER_PERIOD, true, function TimerCallback)
        endif
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger trig = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(trig, Condition(function Conditions))
        call TriggerAddAction(trig, function Actions)
    endfunction
endscope</i>


This is basically how to deal with a simple struct stack. With a little experimentation you'll learn these methods in no time at all as long as you put some effort into it. Might not be very well explained, but some parts should be self explanatory. Do ask if something's very unclear.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • WildTurkey WildTurkey:
    is there a stephen green in the house?
    +1
  • The Helper The Helper:
    What is up WildTurkey?
  • The Helper The Helper:
    Looks like Google fixed whatever mistake that made the recipes on the site go crazy and we are no longer trending towards a recipe site lol - I don't care though because it motivated me to spend alot of time on the site improving it and at least now the content people are looking at is not stupid and embarrassing like it was when I first got back into this like 5 years ago.
  • The Helper The Helper:
    Plus - I have a pretty bad ass recipe collection now! That section of the site is 10 thousand times better than it was before
  • The Helper The Helper:
    We now have a web designer at my job. A legit talented professional! I am going to get him to redesign the site theme. It is time.
  • Varine Varine:
    I got one more day of community service and then I'm free from this nonsense! I polished a cop car today for a funeral or something I guess
  • Varine Varine:
    They also were digging threw old shit at the sheriff's office and I tried to get them to give me the old electronic stuff, but they said no. They can't give it to people because they might use it to impersonate a cop or break into their network or some shit? idk but it was a shame to see them take a whole bunch of radios and shit to get shredded and landfilled
  • The Helper The Helper:
    whatever at least you are free
  • Monovertex Monovertex:
    How are you all? :D
    +1
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top