Help/Critique of JASS (new JASSer)

imakunee

New Member
Reaction score
4
JASS:
scope BobOmb initializer OnInit
    globals
        private real explosionRadius=200.
        private real blueHeroTargetRadius=450.
        private real blueTargetRadius=450.
        private real bobOmbTempReal=0.
        private unit bobOmbTempUnit=null
    endglobals
    
    private struct BobOmbAI
        private static unit tempUnit
        private static real tempReal
        private static real tempDur
        location walkTo
        real damage
        real stunDuration
        real boomTimer
        real offsetAngle
        unit bobomb
        unit latchUnit
        boolean isLatched
        boolean timedLife
        
        private static method damageCondition takes nothing returns boolean
            return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(thistype.tempUnit))==true and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)==false and IsUnitDeadBJ(GetFilterUnit())==false
        endmethod
        
        private static method isHero takes nothing returns boolean
            return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(thistype.tempUnit)) and IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO)==true and IsUnitDeadBJ(GetFilterUnit())==false
        endmethod
        
        private static method explode takes nothing returns nothing
            call Damage_Spell(thistype.tempUnit, GetEnumUnit(), thistype.tempReal)
            if(thistype.tempDur!=0.)then
                call stun(GetEnumUnit(), thistype.tempDur)
            endif
        endmethod
        
        private method destroy takes nothing returns nothing
            call .deallocate()
            set .bobomb=null
            set .latchUnit=null
            call RemoveLocation(.walkTo)
        endmethod
        
        private method periodic takes nothing returns nothing
            local location l=GetUnitLoc(.bobomb)
            local location l2=null
            local group g
            call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, GetUnitName(.bobomb))
            if(GetUnitTypeId(.bobomb)=='h002' or GetUnitTypeId(.bobomb)=='h003')then//red or green bobomb
            
                //if not moving, get it moving
                if(GetUnitCurrentOrder(.bobomb)!=OrderId("move"))then
                    call IssuePointOrder(.bobomb, "move", GetLocationX(.walkTo), GetLocationY(.walkTo))
                endif
                
                //if the bobomb has reached its destination, explode
                if(DistanceBetweenPoints(l, walkTo) < 50)then
                    set thistype.tempUnit=.bobomb
                    set g=GetUnitsInRangeOfLocMatching(explosionRadius, l, Condition(function thistype.damageCondition))
                    set thistype.tempReal=.damage
                    set thistype.tempDur=.stunDuration
                    call ForGroup(g, function thistype.explode)
                    call KillUnit(.bobomb)
                    call .stopPeriodic()
                    call .destroy()
                endif
            else
                if(GetUnitTypeId(.bobomb)=='h004' and Jump.isOn(.bobomb)==false)then//blue bobomb
                    
                    //blue bobombs explode 5 seconds after they land
                    set .boomTimer=.boomTimer+T32_PERIOD
                    if(.boomTimer >=5.)then
                        call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, "boom")
                        set thistype.tempUnit=.bobomb
                        set g=GetUnitsInRangeOfLocMatching(explosionRadius, l, Condition(function thistype.damageCondition))
                        set thistype.tempReal=.damage
                        call ForGroup(g, function thistype.explode)
                        call KillUnit(.bobomb)
                        call .stopPeriodic()
                        call .destroy() 
                    endif
                    
                    //blue bobombs look for a nearby enemy when they land, prioritizing heroes
                    if(.isLatched==false and .latchUnit==null)then
                        call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, "finding latchee")
                        set g = GetUnitsInRangeOfLocMatching(blueHeroTargetRadius, l, Condition(function thistype.isHero))
                        if(CountUnitsInGroup(g) == 0)then
                            call DestroyGroup(g)
                            set g = GetUnitsInRangeOfLocMatching(blueTargetRadius, l, Condition(function thistype.damageCondition))
                        endif
                        if(CountUnitsInGroup(g)>0)then
                            set .latchUnit=FirstOfGroup(g)
                        endif
                        
                    else
                        
                        //if the blue bobomb hasn't attached to the unit it wants to attach to, chase it down
                        if(.isLatched==false)then
                            if(GetUnitCurrentOrder(.bobomb)!=OrderId("move"))then
                                call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, "chasing latchee")
                                call IssuePointOrder(.bobomb, "move", GetUnitX(.latchUnit), GetUnitY(.latchUnit))
                            endif
                            
                            //if the unit it wishes to attach to dies or leaves the bobomb's vision, look for a new unit
                            if(IsUnitVisible(.latchUnit, GetOwningPlayer(.bobomb))==false or IsUnitDeadBJ(.latchUnit))then
                                set .isLatched=false
                                set .latchUnit=null
                            else
                                //otherwise, check if the bobomb is close enough to the target and if so latch to it
                                set l2=GetUnitLoc(.latchUnit)
                                if(DistanceBetweenPoints(l, l2) <= 50.)then
                                    call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, "latch")
                                    set .isLatched=true
                                    set .boomTimer=0.
                                    set .offsetAngle=AngleBetweenPoints(l2, l)//eye candy stuff
                                    call PauseUnit(.bobomb, true)
                                endif
                            endif
                        else
                            //if the bobomb is latched then coninuously move it with the unit it is latched to
                            set l2=GetUnitLoc(.latchUnit)
                            call RemoveLocation(l)
                            set l=PolarProjectionBJ(l2, 50., .offsetAngle)
                            call MoveUnit(.bobomb, l2)
                            call DisplayTextToForce(bj_FORCE_ALL_PLAYERS, "attached")
                        endif
                    endif
                endif
            endif
            
            call RemoveLocation(l)
            call RemoveLocation(l2)
            call DestroyGroup(g)
        endmethod
        implement T32x
        
        static method create takes unit bb, location wt, real damage, real stunDuration returns thistype
            local thistype bbai = BobOmbAI.allocate()
            set bbai.walkTo=wt
            set bbai.damage=damage
            set bbai.stunDuration=stunDuration
            set bbai.isLatched=false
            set bbai.bobomb=bb
            set bbai.timedLife=false
            set bbai.boomTimer=0.
            call bbai.startPeriodic()
            return bbai
        endmethod
    endstruct
    
    private function RedBombActions takes nothing returns nothing
        local location l=GetUnitLoc(GetTriggerUnit())
        local location lTar=GetSpellTargetLoc()
        local real level = I2R(GetUnitAbilityLevel(GetTriggerUnit(), 'rbob'))
        //used elsewhere
        set BobOmbStruct[GetTriggerUnit()].redBombs=BobOmbStruct[GetTriggerUnit()].redBombs-1
        if(BobOmbStruct[GetTriggerUnit()].redBombs > 0)then
            call refreshAbil(GetTriggerUnit(), 'rbob')
        endif
        //end used elsewhere
        set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(GetTriggerUnit()), 'h002', GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), AngleBetweenPoints(l, lTar))
        call SetUnitColor(bj_lastCreatedUnit, GetPlayerColor(Player(0)))
        call BobOmbAI.create(bj_lastCreatedUnit, lTar, 50.*level+2.*GetHeroInt(GetTriggerUnit(), true), .35+.15*level)
        call RemoveLocation(l)
    endfunction
    
    private function GreenBombActions takes nothing returns nothing
        local location l=GetUnitLoc(GetTriggerUnit())
        local location lTar=GetSpellTargetLoc()
        local real level = I2R(GetUnitAbilityLevel(GetTriggerUnit(), 'A08G'))
        //used elsewhere
        set BobOmbStruct[GetTriggerUnit()].greenBombs=BobOmbStruct[GetTriggerUnit()].greenBombs-1
        if(BobOmbStruct[GetTriggerUnit()].greenBombs > 0)then
            call refreshAbil(GetTriggerUnit(), 'A08G')
        endif
        //end used elsewhere
        set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(GetTriggerUnit()), 'h003', GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), AngleBetweenPoints(l, lTar))
        call SetUnitColor(bj_lastCreatedUnit, GetPlayerColor(Player(6)))
        call BobOmbAI.create(bj_lastCreatedUnit, lTar, 50 + 25.*level+(.5 + .5*level)*GetHeroInt(GetTriggerUnit(), true), 0)
        call RemoveLocation(l)
    endfunction
    
    private function BlueBombActions takes nothing returns nothing
        local location l=GetUnitLoc(GetTriggerUnit())
        local location lTar=GetSpellTargetLoc()
        local real level = I2R(GetUnitAbilityLevel(GetTriggerUnit(), 'A095'))
        //used elsewhere
        set BobOmbStruct[GetTriggerUnit()].blueBombs=BobOmbStruct[GetTriggerUnit()].blueBombs-1
        if(BobOmbStruct[GetTriggerUnit()].blueBombs > 0)then
            call refreshAbil(GetTriggerUnit(), 'A095')
        endif
        //end used elsewhere
        set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(GetTriggerUnit()), 'h004', GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), AngleBetweenPoints(l, lTar))
        call SetUnitColor(bj_lastCreatedUnit, GetPlayerColor(Player(1)))
        call Jump.apply(bj_lastCreatedUnit, .75, false, false, lTar, DistanceBetweenPoints(l, lTar)*.75, "", "walk", 1)
        call BobOmbAI.create(bj_lastCreatedUnit, lTar, 25. + 75.*level + 1.5*GetHeroInt(GetTriggerUnit(), true), 0)
        call RemoveLocation(l)
    endfunction
    
    private function OnInit takes nothing returns nothing
        call TriggerAddAction(GT_RegisterStartsEffectEvent(CreateTrigger(), 'rbob'), function RedBombActions)//h002
        call TriggerAddAction(GT_RegisterStartsEffectEvent(CreateTrigger(), 'A08G'), function GreenBombActions)//h003
        call TriggerAddAction(GT_RegisterStartsEffectEvent(CreateTrigger(), 'A095'), function BlueBombActions)//h004
    endfunction
endscope

Well, this is for a bob-omb character (as you may tell from the title). As odd as it may sound this character's powers make other bob-ombs (red, green, or blue) that do various things.

Red - runs to the destination then explodes and stuns

Green - runs to the destination and explodes

Blue - gets lobbed (tossed through the air) then attaches to the nearest enemy, prioritizing heroes, and blows up 5 seconds after landing

It pretty much all works (still have some testing to do) but I ran across an error that I'm sure is basic with structs. It seems that the BobOmbAI.bobomb variable is getting.... I dunno how to say it, temporarily overwritten? Each bob-omb works on its own but when thrown in conjunction things get screwy.

If I throw a red and a green bob-omb, or 2 reds or 2 greens, then they will only explode when all the red or green bob-ombs have stopped moving rather than as soon as they get where they're headed. The output shows that the bobomb will be the second one I throw until all stop then it quickly runs through all the stopped bobombs.

If I throw 2 or more blue bob-ombs then it depends when I throw them. If I throw the second blue before the first one lands, then they will both wait till their 5 second timers are up before exploding simultaneously. But if I wait for the first to land before throwing the second, then their 5 second timers work just fine.

Any and all help appreciated. Please forgive this noob for his lazy/bad coding and critique what you can as you will. :D
 

Sevion

The DIY Ninja
Reaction score
413
First off you're going to want to get rid of those BJ's. If you're not sure which ones are BJ's, look at them on the forums. They highlight red. Also, what is BobOmbStruct? It looks like a global or struct array, but I don't see it declared anywhere.
 

imakunee

New Member
Reaction score
4
Ya, I meant for the comments around where I use the BobOmbStruct to cue you in on not worrying about that part. It's another part of the hero that I have working perfectly at the moment so you wouldn't need to worry about it. XD

I'll put the code here though so you can glance through it if you'd like. (and maybe it's not working as perfectly as I thought)

Also, I figured removing the BJ's would be a good idea since looking at them they're just recalls of functions or math. Will be doing that.

On a side note, I've been looking around and people seem to disagree on what the best way to determine if a unit is dead or not. Some say using a native of your own (which I'm not sure how natives work), or checking if it's health is below a certain amount.

BobOmbStruct
JASS:
struct BobOmbStruct
    //! runtextmacro AIDS()
    integer redBombs//rbob
    integer greenBombs//A08G
    integer blueBombs//A095
    
    real redTimer
    real greenTimer
    real blueTimer
    
    real redMaxTimer
    real blueMaxTimer
    real greenMaxTimer
    
    texttag array redTags[4]
    texttag array greenTags[4]
    texttag array blueTags[4]
    
    private method periodic takes nothing returns nothing
        local integer i
        
        //
        //RED
        //
        if(GetUnitAbilityLevel(this.unit, 'rbob') > 0)then//if has red bomb ability
            set this.redMaxTimer = 40 - (GetHeroInt(this.unit, true)/5 + GetUnitAbilityLevel(this.unit, 'rbob')*3)//cd is 40-int/5-level*3
            if(this.redBombs >= 3)then//if already max bombs, keep timer at 0
                set this.redTimer=0
            else//if not max bombs, show the timer and increment it
                set this.redTimer=this.redTimer+T32_PERIOD//increment timer based on T32
                if(this.redTimer >=this.redMaxTimer)then//if timer reached
                    if(this.redBombs==0)then//if no bombs, refresh the red bomb ability
                        call refreshAbil(this.unit, 'rbob')
                    endif
                    set this.redBombs=this.redBombs+1
                    set this.redTimer=0
                endif//end if timer reached
            endif//end if max bombs
            
            set i=0
            //update the colors of the texts
            loop
            exitwhen i>=3
                if(i < this.redBombs)then
                    call SetTextTagColor(this.redTags<i>, 200, 0, 0, 0)
                else
                    call SetTextTagColor(this.redTags<i>, 70, 0, 0, 35)
                endif
                set i=i+1
            endloop
            if(this.redTimer &gt; 0)then
                call SetTextTagColor(this.redTags[3], 255, 0, 0, 0)
                call SetTextTagText(this.redTags[3], I2S(R2I(this.redTimer))+&quot;/&quot;+I2S(R2I(this.redMaxTimer)), 10. * 0.023 / 10)
            else
                call SetTextTagColor(this.redTags[3], 70, 70, 70, 35)
                call SetTextTagText(this.redTags[3], &quot;0/&quot;+I2S(R2I(this.redMaxTimer)), 10. * 0.023 / 10)
            endif
        endif//end red bomb
        
        //
        //GREEN
        //
        if(GetUnitAbilityLevel(this.unit, &#039;A08G&#039;) &gt; 0)then//if has red bomb ability
            set this.greenMaxTimer = 40 - (GetHeroInt(this.unit, true)/5 + GetUnitAbilityLevel(this.unit, &#039;A08G&#039;)*3)//cd is 40-int/5-level*3
            if(this.greenBombs &gt;= 3)then//if already max bombs, keep timer at 0
                set this.greenTimer=0
            else//if not max bombs, show the timer and increment it
                set this.greenTimer=this.greenTimer+T32_PERIOD//increment timer based on T32
                if(this.greenTimer &gt;=this.greenMaxTimer)then//if timer reached
                    if(this.greenBombs==0)then//if no bombs, refresh the red bomb ability
                        call refreshAbil(this.unit, &#039;A08G&#039;)
                    endif
                    set this.greenBombs=this.greenBombs+1
                    set this.greenTimer=0
                endif//end if timer reached
            endif//end if max bombs
            
            set i=0
            //update the colors of the texts
            loop
            exitwhen i&gt;=3
                if(i &lt; this.greenBombs)then
                    call SetTextTagColor(this.greenTags<i>, 0, 200, 0, 0)
                else
                    call SetTextTagColor(this.greenTags<i>, 0, 100, 0, 35)
                endif
                set i=i+1
            endloop
            if(this.greenTimer &gt; 0)then
                call SetTextTagColor(this.greenTags[3], 0, 255, 0, 0)
                call SetTextTagText(this.greenTags[3], I2S(R2I(this.greenTimer))+&quot;/&quot;+I2S(R2I(this.greenMaxTimer)), 10. * 0.023 / 10)
            else
                call SetTextTagColor(this.greenTags[3], 70, 70, 70, 35)
                call SetTextTagText(this.greenTags[3], &quot;0/&quot;+I2S(R2I(this.greenMaxTimer)), 10. * 0.023 / 10)
            endif
        endif//end red bomb
        
        //
        //BLUE
        //
        if(GetUnitAbilityLevel(this.unit, &#039;A095&#039;) &gt; 0)then//if has red bomb ability
            set this.blueMaxTimer = 40 - (GetHeroInt(this.unit, true)/5 + GetUnitAbilityLevel(this.unit, &#039;A095&#039;)*3)//cd is 40-int/5-level*3
            if(this.blueBombs &gt;= 3)then//if already max bombs, keep timer at 0
                set this.blueTimer=0
            else//if not max bombs, show the timer and increment it
                set this.blueTimer=this.blueTimer+T32_PERIOD//increment timer based on T32
                if(this.blueTimer &gt;=this.blueMaxTimer)then//if timer reached
                    if(this.blueBombs==0)then//if no bombs, refresh the red bomb ability
                        call refreshAbil(this.unit, &#039;A095&#039;)
                    endif
                    set this.blueBombs=this.blueBombs+1
                    set this.blueTimer=0
                endif//end if timer reached
            endif//end if max bombs
            
            set i=0
            //update the colors of the texts
            loop
            exitwhen i&gt;=3
                if(i &lt; this.blueBombs)then
                    call SetTextTagColor(this.blueTags<i>, 0, 0, 200, 0)
                else
                    call SetTextTagColor(this.blueTags<i>, 0, 0, 70, 35)
                endif
                set i=i+1
            endloop
            if(this.blueTimer &gt; 0)then
                call SetTextTagColor(this.blueTags[3], 0, 0, 255, 0)
                call SetTextTagText(this.blueTags[3], I2S(R2I(this.blueTimer))+&quot;/&quot;+I2S(R2I(this.blueMaxTimer)), 10. * 0.023 / 10)
            else
                call SetTextTagColor(this.blueTags[3], 70, 70, 70, 35)
                call SetTextTagText(this.blueTags[3], &quot;0/&quot;+I2S(R2I(this.blueMaxTimer)), 10. * 0.023 / 10)
            endif
        endif//end red bomb
        
        set i=0
        loop
        exitwhen i&gt;=4
            if(i&lt;3)then
                call SetTextTagPos(this.redTags<i>, GetUnitX(this.unit)+70+i*20, GetUnitY(this.unit), 50.)
                call SetTextTagPos(this.greenTags<i>, GetUnitX(this.unit)+70+i*20, GetUnitY(this.unit)-50, 50.)
                call SetTextTagPos(this.blueTags<i>, GetUnitX(this.unit)+70+i*20, GetUnitY(this.unit)-100., 50.)
            else
                call SetTextTagPos(this.redTags<i>, GetUnitX(this.unit)-150., GetUnitY(this.unit), 50.)
                call SetTextTagPos(this.greenTags<i>, GetUnitX(this.unit)-150., GetUnitY(this.unit)-50, 50.)
                call SetTextTagPos(this.blueTags<i>, GetUnitX(this.unit)-150., GetUnitY(this.unit)-100., 50.)
            endif         
            
            set i=i+1
        endloop
    endmethod
    implement T32x
    
    private static method ReviveBobOmb takes nothing returns boolean
        local thistype this=thistype[GetTriggerUnit()]
        set this.redBombs=2
        set this.greenBombs=2
        set this.blueBombs=2
        return false
    endmethod
    
    private static method AIDS_filter takes unit u returns boolean
        return GetUnitTypeId(u)==&#039;E00U&#039;
    endmethod
    
    private method AIDS_onCreate takes nothing returns nothing
        local trigger t=CreateTrigger()
        local integer i=0
        
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_REVIVE_FINISH)
        call TriggerAddCondition(t, Condition(function thistype.ReviveBobOmb))
        
        loop
        exitwhen i&gt;=4
            set this.redTags<i> = CreateTextTag()
            set this.greenTags<i> = CreateTextTag()
            set this.blueTags<i> = CreateTextTag()
            
            call SetTextTagColor(this.redTags<i>, 70, 70, 70, 35)
            call SetTextTagColor(this.greenTags<i>, 70, 70, 70, 35)
            call SetTextTagColor(this.blueTags<i>, 70, 70, 70, 35)
            
            call SetTextTagPermanent(this.redTags<i>, true)
            call SetTextTagPermanent(this.greenTags<i>, true)
            call SetTextTagPermanent(this.blueTags<i>, true)
            
            if(i&lt;3)then
                call SetTextTagPos(this.redTags<i>, GetUnitX(this.unit)+70+i*20, GetUnitY(this.unit), 50.)
                call SetTextTagPos(this.greenTags<i>, GetUnitX(this.unit)+70+i*20, GetUnitY(this.unit)-50, 50.)
                call SetTextTagPos(this.blueTags<i>, GetUnitX(this.unit)+70+i*20, GetUnitY(this.unit)-100., 50.)
                
                call SetTextTagText(this.redTags<i>, &quot;o&quot;, 10. * 0.023 / 10)
                call SetTextTagText(this.greenTags<i>, &quot;o&quot;, 10. * 0.023 / 10)
                call SetTextTagText(this.blueTags<i>, &quot;o&quot;, 10. * 0.023 / 10)
            else
                call SetTextTagPos(this.redTags<i>, GetUnitX(this.unit)-150., GetUnitY(this.unit), 50.)
                call SetTextTagPos(this.greenTags<i>, GetUnitX(this.unit)-150., GetUnitY(this.unit)-50, 50.)
                call SetTextTagPos(this.blueTags<i>, GetUnitX(this.unit)-150., GetUnitY(this.unit)-100., 50.)
                
                call SetTextTagText(this.redTags<i>, &quot;0/&quot;, 10. * 0.023 / 10)
                call SetTextTagText(this.greenTags<i>, &quot;0/&quot;, 10. * 0.023 / 10)
                call SetTextTagText(this.blueTags<i>, &quot;0/&quot;, 10. * 0.023 / 10)
            endif
            
            if(GetLocalPlayer()==GetOwningPlayer(this.unit))then
                call SetTextTagVisibility(this.redTags<i>, true)
                call SetTextTagVisibility(this.greenTags<i>, true)
                call SetTextTagVisibility(this.blueTags<i>, true)
            else
                call SetTextTagVisibility(this.redTags<i>, false)
                call SetTextTagVisibility(this.greenTags<i>, false)
                call SetTextTagVisibility(this.blueTags<i>, false)
            endif
            set i=i+1
        endloop
        set this.redBombs=1
        set this.greenBombs=1
        set this.blueBombs=1
        set this.redMaxTimer=40
        set this.blueMaxTimer=40
        set this.greenMaxTimer=40
        set this.redTimer=0
        set this.blueTimer=0
        set this.greenTimer=0
        set t=null
        call this.startPeriodic()
    endmethod
endstruct</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>
JASS:


I haven't annotated it much for clarity at the moment but the idea behind it is to show a timer for each of the 3 types of bob-ombs as well as 3 "o"s, all properly colored. The timer is an artificial cooldown based on ability level and hero intelligence and upon completion awards another "o" to that bob-omb's color.

When the player uses a bob-omb, that removes an "o", making that "o" fade out. That way the player has 3 bob-om's of each of the 3 types of bob-ombs but if they choose to use all 9 right away then they have to wait as the bob-ombs are slowly rebuilt.
 

Sevion

The DIY Ninja
Reaction score
413
I'm having trouble finding where [ljass].unit[/ljass] is even being set, let alone overwritten.
 

imakunee

New Member
Reaction score
4
Silly me, not being clear and concise. I'm so used to having it named .unit that I forgot I changed it to .bobomb. I clarified that in the beginning post now. Sorry about that.
 

Risen

New Member
Reaction score
4
The only thing with BJ's is that they make the code look ugly, once your map is finished and you run vex's optimizer on your map it cleans it up.

I'm not very familiar with structs, (I only use them when I actually need to) but wouldn't you need to declare your struct before you use it?

For example..

JASS:
    private function RedBombActions takes nothing returns nothing
        local location l=GetUnitLoc(GetTriggerUnit())
        local location lTar=GetSpellTargetLoc()
        local real level = I2R(GetUnitAbilityLevel(GetTriggerUnit(), &#039;rbob&#039;))
        //used elsewhere
        set BobOmbStruct[GetTriggerUnit()].redBombs=BobOmbStruct[GetTriggerUnit()].redBombs-1
        if(BobOmbStruct[GetTriggerUnit()].redBombs &gt; 0)then
            call refreshAbil(GetTriggerUnit(), &#039;rbob&#039;)
        endif
        //end used elsewhere
        set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(GetTriggerUnit()), &#039;h002&#039;, GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), AngleBetweenPoints(l, lTar))
        call SetUnitColor(bj_lastCreatedUnit, GetPlayerColor(Player(0)))
        call BobOmbAI.create(bj_lastCreatedUnit, lTar, 50.*level+2.*GetHeroInt(GetTriggerUnit(), true), .35+.15*level)
        call RemoveLocation(l)
    endfunction


-->

JASS:
    private function RedBombActions takes nothing returns nothing
        local location l=GetUnitLoc(GetTriggerUnit())
        local location lTar=GetSpellTargetLoc()
        local real level = I2R(GetUnitAbilityLevel(GetTriggerUnit(), &#039;rbob&#039;))
        local BombOmbStruct data = BombOmbAI.allocate() // &lt;----
        //used elsewhere
        set data.redBombs(GetTriggerUnit())=data.redBombs(GetTriggerUnit()-1
        if(data.redBombs(GetTriggerUnit().redBombs &gt; 0)then
            call refreshAbil(GetTriggerUnit(), &#039;rbob&#039;)
        endif
        //end used elsewhere
        set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(GetTriggerUnit()), &#039;h002&#039;, GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), AngleBetweenPoints(l, lTar))
        call SetUnitColor(bj_lastCreatedUnit, GetPlayerColor(Player(0)))
        call data.create(bj_lastCreatedUnit, lTar, 50.*level+2.*GetHeroInt(GetTriggerUnit(), true), .35+.15*level)
        call RemoveLocation(l)
    endfunction


Of course you'd use some pointer to keep track of what the struct ID is. In this way it's MUI and it fixes some of your problems, if not all.
 

imakunee

New Member
Reaction score
4
Oh, interesting. I thought that since I allocated the struct in the static ".create" method I wouldn't need to create a local variable for it when I wanted to make it. (Or did you not see that I did it there?)

Also, I thought the best way to run the same code for multiple units would be with a struct of some type. Is there a better way?

EDIT: On further reading I think you might've confused a bit of my code as well. The BobOmbStruct is seperate from the BobOmbAI struct. The BBStruct handles the seperate cooldown system I made for him (in 3rd post i think?). The BBAI struct handles the individually thrown bobombs.
 

Sevion

The DIY Ninja
Reaction score
413
When you make a struct variable, you need to set it to [ljass]thistype.create()[/ljass]

The create method should always allocate the struct instance and return it.
 

Risen

New Member
Reaction score
4
> Also, I thought the best way to run the same code for multiple units would be with a struct of some type. Is there a better way?
There's nothing wrong with your use of a struct in this situation, I was just saying that I don't have much struct knowledge because I don't come across many situations where I actually need one.

> When you make a struct variable, you need to set it to thistype.create()
I thought allocate and create were different, from what I read, allocate generates a unique ID.
 

Sevion

The DIY Ninja
Reaction score
413
For non-array structs, you set it to create. Allocate is private (IIRC) and it shouldn't be used outside of the create method anyhow. Neither should deallocate. In fact, the destroy method should not be overwritten. Use [ljass]onDestroy[/ljass] instead.

[ljass]thistype.create()[/ljass] is used to allocate an ID (by calling [ljass]thistype.allocate()[/ljass]) and set any parameters.

create is to be used outside of the create method, allocate is to be used inside the create method.

Again, this is all for non-array structs (normal structs).
 

imakunee

New Member
Reaction score
4
@Sevion: So what you're saying I did wrong is in my .create method I put BobOmbAI.allocate() instead of thistype.allocate()?
 

Sevion

The DIY Ninja
Reaction score
413
If you're using [ljass]BobOmbAI.allocate()[/ljass] inside the BobOmbAI struct, that's fine. It's better practice to use [ljass]thistype[/ljass] when referring to *this* struct instead of the struct's name. Otherwise, if you decide to rename the struct, you have to rename all instances of the name used in the script. That's not exactly wrong though.
 
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