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.
  • 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 The Helper:
    Happy Thursday!
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though

      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