• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] Struct Help

Status
Not open for further replies.
Level 3
Joined
Apr 7, 2007
Messages
48
Ok, so i have a spell, its a charging-type spell that is supposed to move you forward until you either bump into an enemy (in which case you grab them and do a piledriver . . . errm thingy . . . to them) or bump into some other impassable area. The problem is, I'm very new to JASS, so as tradition I have to pick the hardest frikin spell i can imagine to try. Well ... I don't move, at all, I use a struct to transfer the data from the starting to the movement timer but something isnt right and it well, doesnt work.

JASS:
struct Rush_Data
    unit u
    real d
    effect e
    real cos
    real sin
endstruct

JASS:
function TimerStartWithUserData takes timer t, real timeout, integer data, boolean periodic, code handlerFunc returns nothing
call TimerStart(t, timeout+data/67108871., periodic, handlerFunc)
endfunction
function GetTimerUserData takes timer t, real timeout returns integer
return R2I((TimerGetTimeout(t)-timeout)*67108871.+0.5)
endfunction

JASS:
function RushMove takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local Rush_Data rd = GetTimerUserData(t,.003)
    local real x = GetUnitX(rd.u) + 3 * rd.cos
    local real y = GetUnitY(rd.u) + 3 * rd.sin
    local group g = RushGroup(GetOwningPlayer(rd.u),rd.u)
    if CountUnitsInGroup(g) >= 1 then
        call RushFinal(rd.u,GroupPickRandomUnit(g))
        call DestroyEffect(rd.e)
        call Rush_Data.destroy(rd)
        call DestroyGroup(g)
        call DestroyTimer(t)
        return
    endif
    if CheckPathability(x,y) == false or rd.d <= 0.0 then
        call PauseUnit(rd.u,false)
        call SetUnitPathing(rd.u,true)
        call SetUnitInvulnerable(rd.u,false)
        call DestroyEffect(rd.e)
        call Rush_Data.destroy(rd)
        call DestroyTimer(t)
    endif
        call SetUnitX(rd.u,x)
        call SetUnitY(rd.u,y)
        set rd.d = rd.d - 3.0
endfunction

function RushStart takes unit u, location p returns nothing
    local Rush_Data rd = Rush_Data.create()
    local timer t = CreateTimer()
    call PauseUnit(u,true)
    call SetUnitInvulnerable(u,true)
    call SetUnitPosition(u, GetUnitX(u), GetUnitY(u))
    call SetUnitPathing(u,false)
    call SetUnitFacing(u, AngleBetweenPoints(GetUnitLoc(u),p))
    call AddSpecialEffectTarget("units\\human\\phoenix\\phoenix.mdl",u,"head") //funny hat
    set rd.cos = Cos(GetUnitFacing(u) * bj_DEGTORAD)
    set rd.sin = Sin(GetUnitFacing(u) * bj_DEGTORAD)
    set rd.e = GetLastCreatedEffectBJ()
    set rd.d = RushLvLValues(GetUnitAbilityLevel(u, RushAbility()))
    call TimerStartWithUserData(t,.003,integer(rd),true,function RushMove)
endfunction

I used Vexorian's check pathability function and DiscipleofLife's attacthment system, they were recommended to me earlier.
 
Level 6
Joined
Jun 30, 2006
Messages
230
Perhaps he has changed it, but that system was created for static timers, meaning 1 shot timers, not periodic timers. I am not entirely sure, as a quick google was fruitless on the system. Plus, even still, you have to know the timeout for the trigger and change it in two places. Also, in your case, this system does not have advantages over any other attachment system and was not created for structs (although they seemed to work at the time I checked). I recommend you use Cohadar's ABC when you use structs. His system is very good, and while the system is long, it is mainly just comments. Plus, you can attach things to triggers and dialogs instead of just timers.

Aside from that, what are RushLvLValues and RushFinal? You don't define it in this code.
You can also directly store the effect in the struct:
JASS:
//this
call AddSpecialEffectTarget("units\\human\\phoenix\\phoenix.mdl",u,"head")
set rd.e = GetLastCreatedEffectBJ()

//becomes this
set rd.e = AddSpecialEffectTarget("units\\human\\phoenix\\phoenix.mdl",u,"head")

That timer is very, very fast... did you mean .03?
 
Level 3
Joined
Apr 7, 2007
Messages
48
Hey guys, I fixed it on my own (after 3 hours of work) turns out CheckPathability was screwing me over and now the code works fine, thanks for the reference to ABC's that saved me! +rep for that.
 
Level 9
Joined
Mar 25, 2005
Messages
252
Perhaps he has changed it, but that system was created for static timers, meaning 1 shot timers, not periodic timers. I am not entirely sure, as a quick google was fruitless on the system. Plus, even still, you have to know the timeout for the trigger and change it in two places. Also, in your case, this system does not have advantages over any other attachment system and was not created for structs (although they seemed to work at the time I checked). I recommend you use Cohadar's ABC when you use structs. His system is very good, and while the system is long, it is mainly just comments. Plus, you can attach things to triggers and dialogs instead of just timers.

Erhm. TimerUserData was created especially for structs and it doesn't require 1 shot timers. Periodics are just fine. TUD has 6 lines while ABC has 2500+ [EDIT: I mean 1500+] lines (including comments though) . When TUD is inlined it is nearly twice (~188%) as fast as ABC or HSAS. Maybe its just me but these sound like advantages to me. I wonder where all of this false information of yours is coming from...

There are actually good reasons to not use TUD though. One is that it works only with timeouts in between 0 and 0.124999 when (0 <= data < ~10000). Another one is that you have to know the timeout before retrieving the data. Third one is that the way of TT (in other words the way that Vex explains here) is better for large amounts of structs.

Also I would recommend HSAS over ABC. It's as fast or faster on average as ABC and a lot shorter in code. Lenght doesnt matter much but 2/3 of the length of ABC is pure waste. If it actually did some good then it was ok but it's absolutely useless.
 
Last edited:
Level 6
Joined
Jun 30, 2006
Messages
230
Last time I checked your system (it was quick, I won't deny it), it could not do periodic timers (perhaps this was my fault, I cannot be sure). I even said I was not sure on the matter. I was not putting TUD down in any way. I tried to find your system, did a quick google could not find it, which I mentioned. I cannot recommend a system which I cannot find the authors own documentation, sorry.

Like you said, HSAS is not necessarily faster. In certain circumstances it is considerably faster, as noted by pandamine himself. However, in my own tests, on code I literally use, ABC is actually faster than HSAS. Not much, but it was faster. I cannot tell you exactly why, I just know that it is. Also, a lot of that 'useless' code in ABC is to prevent users from doing certain things. If you truly think it is useless, take it out, do extensive testing, and then come back and give your results to Cohadar. He's a bull-headed troll, sure, he'll listen to documented, replicable experiements.

By the way, ABC is only 400 lines with a lot of comments, not 2500+... so I quote:
I wonder where all of this false information of yours is coming from
Happy coding, mates.
 
Level 9
Joined
Mar 25, 2005
Messages
252
By the way, ABC is only 400 lines with a lot of comments, not 2500+...

Oh I ment 1500+ sry. It's 394 as it shows in the editor but 1557 when the textmacros are instantiated, which is actually what counts and what is saved in the war3map.j file. Without comments and spaces though its about 1000 lines long or so, which is still 8 times more than HSAS with it's 116 lines (with 1 instantiated HSAS_Static textmacro). They are rather identical when it comes to performance according to my tests, so I see no reason to use ABC over HSAS, which was the point I was trying to make earlier.

Btw incase you don't, I think you should use NewTimer & ReleaseTimer with HSAS and test involving it because it's performance depends on the handle id sizes, while ABC's doesn't.
 
Level 6
Joined
Jun 30, 2006
Messages
230
I'll try the test sometime. Although, in my opinion, that says more about ABC than HSAS. Also, that's timer specific, so HSAS may beat it on timers, but I DO attach things to triggers on occasion. (In reflection, I'm not sure that statement I just made is accurate...)

Edit: HSAS vs ABC

HSAS is faster, however, you have to be smarter when using it. Be careful, it does not null things and thus you have to do more yourself. It requires more user knowledge.

Because of this, ABC is BETTER. Pandamine himself admitted this, and has recommended ABC to several people. However... once you know enough, HSAS can be better, so to noobies I'll recommend ABC... which is the only time I'll be recommending a system anyways.
 
Last edited:
Status
Not open for further replies.
Top