Snippet Trackable2

I know the basic process, but how to do it is where I'm lost. How do I turn the execution count into the struct? Where does the ClickTrigger come from?

EDIT: Nevermind. I found another way. Update, can now support multiple events on the same trigger (The answer? More H2I!)
 
Well, I do what I understand. It's not like H2I is horribly unstable. Sure, after enough handles, trackables will no longer fit into the array. But these were not meant to be created dynamically. Even if you're paranoid, you can always increase the array size to something ungodly high.
 
I've worked on a real map that had 10,000 handles at map init. This code would blatantly not work. Besides, there's an alternative...
JASS:
library Trackable2

private keyword Data

globals
    private Data array Trackables
    private Data TriggeringTrackable
endglobals

private struct Data
    trackable array Trackers [12]
    trigger ClickFire
    trigger TrackFire
    trigger OnClick // change to arrays or w/e to support multi-trigs
    trigger OnTrack // change to arrays or w/e to support multi-trigs
    real X
    real Y
    real Z
    real Facing
    string Model
    player ForPlayer = null
endstruct

// Unreliable piece of junk... j/k
//private constant function H2I takes handle h returns integer
//    return h
//    return 0
//endfunction

// The old Key Triggers implementation. <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite1" alt=":)" title="Smile    :)" loading="lazy" data-shortname=":)" />
// Fount on <a href="http://www.thehelper.net/forums/showthread.php?t=78493" class="link link--internal">http://www.thehelper.net/forums/showthread.php?t=78493</a>
// Suitable only in very controlled circumstances, so it was never approved.
private function SetTriggerData takes trigger t, integer data returns nothing
    call ResetTrigger(t)
    loop
        exitwhen data==0
        call TriggerExecute(t)
        set data=data-1
    endloop
endfunction
private function GetTriggerData takes trigger t returns integer
    return GetTriggerExecCount(t)
endfunction
// End Key Triggers implementation.

function ClickFireCond takes nothing returns boolean
    set TriggeringTrackable=GetTriggerData(GetTriggeringTrigger())
    // The below can be done in a loop to support multi-trigger
    if TriggerEvaluate(TriggeringTrackable.OnClick) then
        call TriggerExecute(TriggeringTrackable.OnClick)
    endif
    return false // Must be false so attached data never changes. Do not use real actions.
endfunction
function TrackFireCond takes nothing returns boolean
    set TriggeringTrackable=GetTriggerData(GetTriggeringTrigger())
    // The below can be done in a loop to support multi-trigger
    if TriggerEvaluate(TriggeringTrackable.OnTrack) then
        call TriggerExecute(TriggeringTrackable.OnTrack)
    endif
    return false // Must be false so attached data never changes. Do not use real actions.
endfunction

function CreateTrackable2 takes string modelPath, real x, real y, real z, real facing returns Data
    local Data d = Data.create()
    local string s = &quot;&quot; // I honestly believe the alternative could desynch, as &quot;&quot; did not exist - Jesus4Lyf
    local destructable platform = CreateDestructableZ(&#039;OTip&#039;,x,y,z,0.00,1,0)
    local integer i = 11
    loop
        exitwhen i &lt; 0
        if GetLocalPlayer() == Player(i) then
            set s = modelPath
        else
            set s = &quot;&quot;
        endif
        set d.Trackers<i> = CreateTrackable(s, x, y, facing)
        //set Trackables[H2I(d.Trackers<i>) - 0x100000] = d
        set i = i - 1
    endloop
    set d.X = x
    set d.Y = y
    set d.Z = z
    set d.Facing = facing
    set d.Model = modelPath
    // Added by Jesus4Lyf
    set d.ClickFire=CreateTrigger()
    set d.TrackFire=CreateTrigger()
    call SetTriggerData(d.ClickFire,d)
    call SetTriggerData(d.TrackFire,d)
    call TriggerAddCondition(d.ClickFire,Condition(function ClickFireCond))
    call TriggerAddCondition(d.TrackFire,Condition(function TrackFireCond))
    set i = 11
    loop
        exitwhen i &lt; 0
        call TriggerRegisterTrackableHitEvent(d.ClickFire, d.Trackers<i>)
        call TriggerRegisterTrackableTrackEvent(d.TrackFire, d.Trackers<i>)
        set i = i - 1
    endloop
    // End addition
    call RemoveDestructable(platform)
    set platform = null
    return d
endfunction

function CreateTrackable2ForPlayer takes string modelPath, real x, real y, real z, real facing, player forPlayer returns Data
    local Data d = Data.create()
    local string s = modelPath
    local destructable platform = CreateDestructableZ(&#039;OTip&#039;,x,y,z,0.00,1,0)
    if GetLocalPlayer() != forPlayer then
        set s = &quot;&quot;
    endif
    set d.Trackers[1] = CreateTrackable(s, x, y, facing)
    //set Trackables[H2I(d.Trackers[1]) - 0x100000] = d
    set d.ForPlayer = forPlayer
    set d.X = x
    set d.Y = y
    set d.Z = z
    set d.Facing = facing
    set d.Model = modelPath
    // Added by Jesus4Lyf
    set d.ClickFire=CreateTrigger()
    set d.TrackFire=CreateTrigger()
    call SetTriggerData(d.ClickFire,d)
    call SetTriggerData(d.TrackFire,d)
    call TriggerAddCondition(d.ClickFire,Condition(function ClickFireCond))
    call TriggerAddCondition(d.TrackFire,Condition(function TrackFireCond))
    call TriggerRegisterTrackableHitEvent(d.ClickFire, d.Trackers[1])
    call TriggerRegisterTrackableTrackEvent(d.TrackFire, d.Trackers[1])
    // End addition
    call RemoveDestructable(platform)
    set platform = null
    return d
endfunction

function TriggerRegisterTrackable2HitEvent takes trigger whichTrigger, Data d returns nothing
    set d.OnClick=whichTrigger
endfunction

function TriggerRegisterTrackable2TrackEvent takes trigger whichTrigger, Data d returns nothing
    set d.OnTrack=whichTrigger
endfunction

// Noooiez. H2I is naughty like that. Unstable! <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite7" alt=":p" title="Stick Out Tongue    :p" loading="lazy" data-shortname=":p" />
//function GetTriggeringTrackable2 takes nothing returns Data
//    return Trackables[H2I(GetTriggeringTrackable()) - 0x100000]
//endfunction

function GetTrackedPlayer takes Data d returns player
    local integer i
    local trackable t
    if d.ForPlayer == null then
        set i = 11
        set t = GetTriggeringTrackable()
        loop
            exitwhen i &lt; 0
            if t == d.Trackers<i> then
                set t = null
                return Player(i)
            endif
            set i = i - 1
        endloop
    else
        return d.ForPlayer
    endif
    return null
endfunction
        

//! textmacro Trackable2_Macro takes NAME, TYPE
function GetTrackable2$NAME$ takes nothing returns $TYPE$
    return TriggeringTrackable.$NAME$
endfunction
//! endtextmacro

//! runtextmacro Trackable2_Macro (&quot;X&quot;, &quot;real&quot;)
//! runtextmacro Trackable2_Macro (&quot;Y&quot;, &quot;real&quot;)
//! runtextmacro Trackable2_Macro (&quot;Z&quot;, &quot;real&quot;)
//! runtextmacro Trackable2_Macro (&quot;Facing&quot;, &quot;real&quot;)
//! runtextmacro Trackable2_Macro (&quot;Model&quot;, &quot;string&quot;)
//! runtextmacro Trackable2_Macro (&quot;ForPlayer&quot;, &quot;player&quot;)

endlibrary</i></i></i></i></i>


That's your head start. Oh, this breaks your get tracking player thing. You can fix this by creating one trigger for each player in a wrapper struct, then have the current data in a substruct.

You'll figure it out. Go have some fun. :D
And master the TriggerExecCount princible. :cool:
While TriggerExecCount needs the author to be very cautious to work, it's great when encapsulated in a library like this, because the end user doesn't care what's in it, as long as it works. This will make your code much more stable. :D

PS. The code needs a lot of cleanup work and such, such as some of the funcs arent even private. But that's not my job. :p
 
Bah, it's just too complicated for what is meant to be an interface for what is already possible.

Are you really sure that you should create a trigger at creation instead of event registry? Seems like a waste of a trigger.

I'll try to throw something together. If all fails, I fall back on H2I. Possibly put in a MIN_HANDLE_ID constant in case your map has far too many preplaced handles.

EDIT: Nevermind. I can't figure out how to make it work for a single trigger using your deranged method.
 
>Are you really sure that you should create a trigger at creation instead of event registry? Seems like a waste of a trigger.

Why would you ever create a trackable without any events attached (I can actually think of only one reason; click blocking)? Besides, you can indeed create the trigger later if you like.

Sorry if you think I'm being overzealous, but this issue really means something to me. I believe nothing in WC3 needs to use H2I, and hence everything can be more stable (and often faster). Trackables, in my mind, struck me as the one thing that you couldn't get down to O(1) complexity without H2I. I thought of a way to get around that, and hence had to post that.

I have actually written two maps with trackables before, years ago. I used your methods, exactly (you probably saw the same tutorial on it). So I'm quite familiar with all the issues involved. No offense, but I personally would never use this while it still contains H2I or O(n) complexity (for loading data), knowing that it can be better. Other people have lesser requirements than me, however. So carry on... :D

PS. Going on your last edit time (6 minutes after original post), it seems you gave up after 6 minutes. That diagram took 15 minutes, and that code took 25. =/ But it's your snippet, not mine. :)
 
Are you talking about H2I or I2H?

IMO H2I is maybe the coolest single function wc3 modders have ever invented.

edit. Actually, have you done any testing about the speed of I2H ? Since, I2Trackable is safe, it could be the fastest way to get attached data from trackable.

edit2. And you can always calculate your ID_OFFSET before creating trackables, instead of using 0x100000 as an ID_OFFSET.
 
Excuse the off topic.

>IMO H2I is maybe the coolest single function wc3 modders have ever invented

IMO, H2I is fast food. It hits the spot, it's quick to implement, and it's unhealthy in the long run.

I earnestly believe that H2I is practically never necessary, and hence I don't use it, nor use anything that uses it. But most mappers are OK with it. :)

As for I2H, that's just ridiculous. An array call can handle that for you. And if not, an array call with hashing can. But I never need this either because I have no H2I in the first place.

Viikuna's edit --> I wouldn't even consider speed (within reason) in a system like this. As long as it's O(1) complexity to run, it's fine. But you may notice my code doesn't even attach to trackables. That's why it's clever. The reality is that after creating the trackable, you can drop it from memory completely and store no references to it, which is what I strongly suggest doing.

Furthermore, "Since, I2Trackable is safe, it could be the fastest way to get attached data from trackable" doesn't make sense as all it can do is get the trackable. Not data from it.
 
It depends how you use H2I.

Actually, I just realized that the only place where I use H2I in my map, is TimerStack. This is the fastest method, faster than hashing, and has only one downside: limited amount of timers. Luckily this is not a problem, because limit is till big enough for my needs.

I might also need Table too for something. Even if it is slow, it has no other downsides, so it works perfectly in situations where you dont need speed.

Furthermore, "Since, I2Trackable is safe, it could be the fastest way to get attached data from trackable" doesn't make sense as all it can do is get the trackable. Not data from it.
Makes sense. I dont know what Im writing anymore.
 
Yeah. Refer to KT2 as you know for no H2I timers (not that you're interested in that), and Table is why I said -nearly- no reason for H2I ever. Sometimes you need to attach wierd stuff. And Table is slow but reliable (I assume). No limits.

Let's leave the off-topic there. :thup:

PS.
>Bah, it's just too complicated for what is meant to be an interface for what is already possible.

When it comes to code, things usually grow. ;)
 
I still don't understand the trigger method, but I will look into Table. Seems to be good for those who don't want to just adjust the MIN_HANDLE_ID :p.
 
I can think of a way to do it, but it limits the amount of events to one trigger. I can't have that. Usability over speed, always.

EDIT: Wait, no! The entire reason I did this was to avoid lots of gamecache. Besides, I can't get Table with WC3C down. Increasing MIN_HANDLE_ID and/or extending the Trackables array some works just fine.

H2I is not unstable! Now I2H, that's a problem.

Besides, I need to attach data to strings in my map. I can't find a way to do that without H2I or an O(n) search. In fact, the only O(n) search in Trackable2 is through a stack of 12 trackables to find which one was triggered.
 
Ability data. I need to tie the name to a raw code. Use it to add an ability from a string to a unit in an RP map. I don't see any other method.
 
Why use gamecache when H2I works perfectly? Yes, this question may drive you insane.
 
... You are so confused! XD

You generally DO use H2I to use gamecache. I don't use either. BUT for people who do, I have a better idea! So pleaseeeee post Table here for a sec so I can grab it and make it way better, but use the same interface so you can replace it completely, directly. I'm really excited.

>Ability data. I need to tie the name to a raw code. Use it to add an ability from a string to a unit in an RP map. I don't see any other method.

You yourself just stated a reason for gamecache, without H2I.

Seriously, you need to understand this. This will implement right over gamecache without the efficiency loss. Sounds stupid, but IT'S ME. I break things properly! :D

EDIT: Nvm, got it.
 
The real reason for game cache is because there is no array limit, isn't it like that? I don't see how you can replace that without hax, <censored>, and bribes.

Let me restate my last post. Ahem
Why use game cache when I can use H2I alone without flaw?
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Varine Varine:
    Turns out it wasn't me and it wasn't E Coli, which I was sure it wasn't. But still very stressful. Do not recommend fucking with the CDC.
  • Varine Varine:
    I think the worst was the IRS. We got audited once and they show up with like guns and shit, because I guess the IRS is technically a police force?
  • Varine Varine:
    They had a gun and it was very unnerving.
  • Varine Varine:
    I looked up why and it does make sense though. I forget they are the ones that deal with like mafias and shit, and not everyone is going to be very considerate about being told they need to explain and prove where their money comes from. We'
  • Varine Varine:
    We are pretty good about it I think. Not my job, but the people that do it are pretty one top of it.
  • The Helper The Helper:
    yeah I dont like the government. I am a total libertarian and what you are describing is what I am totally against when it comes to governing
  • Varine Varine:
    I mean I don't really like the government. But I would also prefer to have one than... not have any government. Like we need to have police forces and national welfare systems, but I don't think the cop that is pulling you over for speeding is the same cop that should also be responding to active terror events.
  • The Helper The Helper:
    I am talking about federal.
  • The Helper The Helper:
    State and local elections I believe in when it comes to governing. Of course the military
  • The Helper The Helper:
    Federal should do military
  • The Helper The Helper:
    The federal government should do the military not the police. I hope Trump gets rid of the income tax
  • The Helper The Helper:
    I hold no hope of Trump getting rid of income tax though.
  • jonas jonas:
    Trump is a wildcard, but in the end, it's the republican party that makes the laws, Trump can only do exec orders
  • jonas jonas:
    I don't think the Republicans will get rid of income tax, at most lower it a little, mostly for people with 6 figures+. But that's just my opinion
  • The Helper The Helper:
    one can dream
  • Ghan Ghan:
    FairTax would be nice.
  • Ghan Ghan:
    But the electorate would have to demand it and vote people in to do it.
  • Ghan Ghan:
    Government spending, foreign policy, and the southern border are all bigger issues than the income tax right now I'd say.
  • The Helper The Helper:
    For you those are the bigger issues. Cannabis legalization and get rid of Income tax are mine.
  • Ghan Ghan:
    We have so much cannabis up here in Oklahoma. Can't go a block without running into 3 dispensaries. xD
  • The Helper The Helper:
    if the demand is there
  • jonas jonas:
    I think the biggest issue in USA is how divided the country has become
  • Ghan Ghan:
    There's a big split happening in fundamental values that is very worrisome.
  • jonas jonas:
    I think there's always been a split in values. But now there's a split in what reality is. No matter whom you ask, they think a third of the country is insane and wants to destroy the country
  • The Helper The Helper:
    pretty big split

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top