System TrackMapSystem

Executor

I see you
Reaction score
57
TrackMapSystem

  • Language = vJass
  • System Requirements = Event;
  • Usage Requirements = jass abilities

Description:

This System allows the fast creation of rects filled with trackables or as I call them "TrackMaps". The object trackable is able to react to mouse movements aswell as to mouse clicks.
I simply use the model of a transparent square for the trackable to fill a rect without modifying map appearance.
In TrackMaps you will be able to access the cursor position, cursor clicks on the ground and cursor movements over the ground.

Screenshot:

You won't really see the point of my system by looking at this screenshot.
040909211058_TrackMapSysScreen.jpg

Instruction:

Just insert the whole system code into an empty trigger.
If you have problems look at the Demo Map.

Problems:

TrackMaps cannot be destroyed, as trackables aren't removable. Destroying a TrackMap will lead to the removal of the triggers but nothing more.
Normal clicks on the ground will malfunction because the ground cannot be directly acessed anymore.
You should try it out!

Interface:

JASS:
function SetUpTrackMap takes rect area, player p, boolean veryprecise returns TrackMap
// boolean veryprecise => My system grants the possibilty to use a smaller or a bigger quadrat as a model for the TrackMap
// true means you want the small model and more trackables while false means that the big model will be used aswell as less trackables
// In general : more trackables => more lag, more precision.. less trackables => less lag, less precision

function SetUpTrackMapEx takes rect area, player p, real precision, boolean timed returns TrackMap
// real precision means you can choose the distance between the trackables.. but I would say you should use one of the two constants
// given in the globals section.. you also can see how they are used in the system code on the bottom.
// boolean timed => generates TrackMap dynamically while the game is running.. means that the TrackMap will take a few moments to initialize but it 
// shouldn't lag

// Any TrackMap reacts:
function TriggerRegisterAnyMouseEvent takes trigger t returns nothing
            // Any TrackMap reacts to a Click or a Track Event
function TriggerRegisterAnyClickEvent takes trigger t returns nothing
            // Any TrackMap reacts to a Click Event
function TriggerRegisterAnyTrackEvent takes trigger t returns nothing
            // Any TrackMap reacts to a Track Event

// A specific TrackMap reacts
function TriggerRegisterMouseEvent takes trigger t, TrackMap tm returns nothing
            // A specific TrackMap reacts to a Click or a Track Event
function TriggerRegisterClickEvent takes trigger t, TrackMap tm returns nothing
            // A specific TrackMap reacts to a ClickEvent
function TriggerRegisterTrackEvent takes trigger t, TrackMap tm returns nothing
           // A specific TrackMap reacts to a Track Event

// Track = Cursor touches a trackable
// Click  =  User clicked on a trackable
// Mouse = Track or Click

function Clicked takes nothing returns boolean  
function Tracked takes nothing returns boolean
function GetMousePosX takes integer p returns real
function GetMousePosY takes integer p returns real
function GetTriggerMousePosX takes nothing returns real
function GetTriggerMousePosY takes nothing returns real
function GetTriggerTrackMap takes nothing returns TrackMap
function GetMouseUsingPlayer takes nothing returns player
function GetMouseUsingPlayerId takes nothing returns integer


Code:

Requirement Event
JASS:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  ~~    Event     ~~    By Jesus4Lyf    ~~    Version 1.03    ~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//  What is Event?
//         - Event simulates Warcraft III events. They can be created,
//           registered for, fired and also destroyed.
//         - Event, therefore, can also be used like a trigger "group".
//         - This was created when there was an influx of event style systems 
//           emerging that could really benefit from a standardised custom
//           events snippet. Many users were trying to achieve the same thing
//           and making the same kind of errors. This snippet aims to solve that.
//
//  Functions:
//         - Event.create()     --> Creates a new Event.
//         - .chainDestroy()    --> Destroys an Event.
//                                  DO NOT use .destroy().
//         - .fire()            --> Fires all triggers which have been
//                                  registered on this Event.
//         - .register(trigger) --> Registers another trigger on this Event.
//
//  Details:
//         - Event is extremely efficient and lightweight.
//         - It is safe to use with dynamic triggers.
//         - Internally, it is just a singularly linked list. Very simple.
//
//  How to import:
//         - Create a trigger named Event.
//         - Convert it to custom text and replace the whole trigger text with this.
//
//  Thanks:
//         - Builder Bob for the trigger destroy detection method.
//         - Azlier for inspiring this by ripping off my dodgier code.
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
library Event
    ///////////////
    // EventRegs //
    ////////////////////////////////////////////////////////////////////////////
    // For reading this far, you can learn one thing more.
    // Unlike normal Warcraft III events, you can attach to Event registries.
    // 
    // Event Registries are registrations of one trigger on one event.
    // These cannot be created or destroyed, just attached to.
    //
    // It is VERY efficient for loading and saving data.
    // 
    //  Functions:
    //         - set eventReg.data = someStruct --> Store data.
    //         - eventReg.data                  --> Retreive data.
    //         - Event.getTriggeringEventReg()  --> Get the triggering EventReg.
    // 
    struct EventReg
        integer data
        method clear takes nothing returns nothing
            set this.data=0
        endmethod
    endstruct
    
    struct Event
        private trigger trig
        private Event next
        static method create takes nothing returns Event
            local Event this=Event.allocate()
            set this.next=0
            return this
        endmethod
        private static Event current
        static method getTriggeringEventReg takes nothing returns EventReg
            return .current
        endmethod
        private static trigger t
        method fire takes nothing returns nothing
            local Event curr
            // this = last.
            loop
                set curr=this.next
                exitwhen curr==0
                set .t=curr.trig
                if IsTriggerEnabled(.t) then
                    set .current=curr
                    if TriggerEvaluate(.t) then
                        call TriggerExecute(.t)
                    endif
                    set this=curr
                else
                    call EnableTrigger(.t) // Was trigger destroyed?
                    if IsTriggerEnabled(.t) then
                        call DisableTrigger(.t)
                        set this=curr
                    else // If trigger destroyed...
                        set .current.trig=null
                        set this.next=curr.next
                        call curr.destroy()
                    endif
                endif
            endloop
        endmethod
        method register takes trigger t returns EventReg
            local Event new=Event.allocate()
            set new.next=this.next
            set new.trig=t
            set this.next=new
            call EventReg(new).clear()
            return new
        endmethod
        method chainDestroy takes nothing returns nothing
            loop
                call this.destroy()
                set this=this.next
                exitwhen this==0
                set this.trig=null
            endloop
        endmethod
    endstruct
    
    /////////////////////////////////////////////////////
    // Demonstration Functions & Alternative Interface //
    ////////////////////////////////////////////////////////////////////////////
    // What this would look like in normal WC3 style JASS (should all inline).
    // 
    function CreateEvent takes nothing returns Event
        return Event.create()
    endfunction
    function DestroyEvent takes Event whichEvent returns nothing
        call whichEvent.chainDestroy()
    endfunction
    function FireEvent takes Event whichEvent returns nothing
        call whichEvent.fire()
    endfunction
    function TriggerRegisterEvent takes trigger whichTrigger, Event whichEvent returns EventReg
        return whichEvent.register(whichTrigger)
    endfunction
    
    // And for EventRegs...
    function SetEventRegData takes EventReg whichEventReg, integer data returns nothing
        set whichEventReg.data=data
    endfunction
    function GetEventRegData takes EventReg whichEventReg returns integer
        return whichEventReg.data
    endfunction
    function GetTriggeringEventReg takes nothing returns integer
        return Event.getTriggeringEventReg()
    endfunction
endlibrary


System Code:

JASS:
library TrackMapSystem initializer InitSystem uses Event

//=====================================================================================
//                                                                                   ||
//    TrackMapSystem                                                                 ||
//                                                                                   ||
//                   created by Lord_Executor alias Executor alias Executor1         ||
//                                                                                   ||
//    Credits                                                                        ||
//                                                                                   ||
//      Vexorian  [JNGP,Dummy.mdx]                                                   ||
//      tamisrah  [Advice]                                                           ||
//      Azelier   [Ideas]                                                            ||
//      Jesus4Lyf [Event]                                                            ||
//                                                                                   ||
//=====================================================================================

//=====================================================================================
//                                                                                   ||
//  This system allows you the fast and effective set up of TrackMaps which means    ||
//  filling an area with trackable objects which will callback to cursor actions.    ||
//                                                                                   ||
//  I create those trackables without a visible model, which allows them to be       ||
//  invisible ingame but still able to determine move and click of the cursor.       ||
//                                                                                   ||
//  There are several problems with this system because normal orders on TrackMapped ||
//  ground won't be handled normal anymore. But you should try for yourself.         ||
//                                                                                   ||
//=====================================================================================

globals
    //May be modified:
    private constant    real        TIMER_INTERVAL               = 0.05
    private constant    integer     LOOP_BREAK_VALUE             = 2500
    
    // You should know what you do if you want to modify these:
    private constant    string      MODEL_SMALL                      = "Doodads\\Terrain\\InvisiblePlatformSmall\\InvisiblePlatformSmall.mdl"
    private constant    string      MODEL_NORMAL                     = "Doodads\\Terrain\\InvisiblePlatform\\InvisiblePlatform.mdl"
    private constant    real        RADIUS_NORMAL                    = 73.59
    
    // Usuable Constants                                        
            constant    real        MOUSEPOSITION_HIGH_PRECISION = RADIUS_NORMAL
            constant    real        MOUSEPOSITION_LESS_PRECISION = RADIUS_NORMAL * 2
    
    //System Vars (do not modify)
    private             hashtable   Hash                           = null
    private constant    key         SLOT_TRACKDATA               
    private constant    key         SLOT_STRUCT                  
    private             real array  TMpx
    private             real array  TMpy
    
    private             boolean     clicked                      = false
    private             integer     TMlasttm                     =  0
    private             integer     TMlastplayer                 = -1
endglobals

private function InitSystem takes nothing returns nothing
    set Hash = InitHashtable()
endfunction

private function SetTriggerData takes trigger t, integer i returns nothing
    loop
        exitwhen i <= 0
        call TriggerExecute(t)
        set i = i - 1
    endloop
endfunction

private function DestroyTriggerDelayed takes trigger t returns nothing
    call TriggerSleepAction(3.0)
    call DestroyTrigger(t)
endfunction

private struct trackdata
    readonly real x
    readonly real y
    static method create takes real x, real y returns thistype
        local thistype this = thistype.allocate()
        set .x = x
        set .y = y
        return this    
    endmethod
endstruct

private struct cache
    public real    res
    public string  mod
    public boolean timed
    public real    x_MIN
    public real    y_MIN
    public real    x_MAX
    public real    y_MAX
    static method create takes nothing returns thistype
        return thistype.allocate()
    endmethod
endstruct

struct TrackMap
    readonly        trigger     TrigTrack
    readonly        trigger     TrigClick
    readonly        integer     p
    readonly        rect        r
    readonly        boolean     active
    
    private static  boolexpr    TrackHandle
    private static  boolexpr    ClickHandle
    
    private static  Event       anyClick
    private static  Event       anyTrack
    
    private         Event       onClick
    private         Event       onTrack
    
    static method registerAnyClick takes trigger t returns nothing
        call .anyClick.register(t)
    endmethod
    
    static method registerAnyTrack takes trigger t returns nothing
        call .anyTrack.register(t)
    endmethod
    
    static method registerAnyChange takes trigger t returns nothing
        call .anyClick.register(t)
        call .anyTrack.register(t)
    endmethod
    
    method registerClick takes trigger t returns nothing
        call .onClick.register(t)
    endmethod
    
    method registerTrack takes trigger t returns nothing
        call .onTrack.register(t)
    endmethod
    
    method registerChange takes trigger t returns nothing
        call .onClick.register(t)
        call .onTrack.register(t)
    endmethod
    
    private static method TrackHandleEx takes nothing returns boolean
        local thistype map  = GetTriggerExecCount(GetTriggeringTrigger())
        local trackdata d   = LoadInteger(Hash,GetHandleId(GetTriggeringTrackable()),SLOT_TRACKDATA)
        
        set TMlasttm        = map
        set TMpx[map.p]     = d.x
        set TMpy[map.p]     = d.y
        set TMlastplayer    = map.p
        set clicked         = false
        
        call map.onTrack.fire()
        call .anyTrack.fire()
        
        return false
    endmethod
    private static method ClickHandleEx takes nothing returns boolean
        local thistype map  = GetTriggerExecCount(GetTriggeringTrigger())
        local trackdata d   = LoadInteger(Hash,GetHandleId(GetTriggeringTrackable()),SLOT_TRACKDATA)
        
        set TMlasttm        = map
        set TMpx[map.p]     = d.x
        set TMpy[map.p]     = d.y
        set TMlastplayer    = map.p
        set clicked         = true
    
        call map.onClick.fire()
        call .anyClick.fire()
        
        return false
    endmethod
    
    static method create takes rect r,integer p, real resolution, boolean timed returns thistype
        local thistype  this = thistype.allocate()
        local string    mod  = ""
        local cache     c    = cache.create()
        
        if resolution <= RADIUS_NORMAL then
            set mod          = MODEL_SMALL
        else 
            set mod          = MODEL_NORMAL
        endif
        
        set .p      = p
        set .r      = r
        set c.res   = resolution
        set c.mod   = mod
        set c.x_MIN = GetRectMinX(.r)
        set c.y_MIN = GetRectMinY(.r)
        set c.x_MAX = GetRectMaxX(.r)
        set c.y_MAX = GetRectMaxY(.r)
        set c.timed = timed
        
        set .onClick = Event.create()
        set .onTrack = Event.create()
        
        set .TrigTrack = CreateTrigger()
        set .TrigClick = CreateTrigger()
        call SetTriggerData.execute(.TrigTrack,this)
        call SetTriggerData.execute(.TrigClick,this)
        call TriggerAddCondition(.TrigTrack,thistype.TrackHandle)
        call TriggerAddCondition(.TrigClick,thistype.ClickHandle)
        
        if timed then
            call DynamicTrackMapGenerator.create(this,c)
        else        
            call .generatefield(c,0)
        endif
        return this
    endmethod
    method generatefield takes cache c, integer i returns boolean
        local integer j         = 0
        local trackable track   = null
        local real x            = 0.
        local real y            = 0.
        local string mod        = c.mod
        
        if GetPlayerId(GetLocalPlayer()) != .p then
            set mod             = ""
        endif  
        
        loop
            set j   = 0
            set x   = c.x_MIN + i * c.res
            loop
                set y   = c.y_MIN + j * c.res
          
                set track = CreateTrackable(mod,x,y,0.) 
                call SaveInteger(Hash,GetHandleId(track),SLOT_TRACKDATA,trackdata.create(x,y))
            
                call TriggerRegisterTrackableTrackEvent(.TrigTrack, track)
                call TriggerRegisterTrackableHitEvent(.TrigClick, track)
            
                set j   = j + 1
                exitwhen y >= c.y_MAX
            endloop
            
            set i   = i + 1
            
            if x >= c.x_MAX then
                // completely done.
                call c.destroy()
                return true
            endif
            
                // wait for next interval to proceed
            exitwhen c.timed
            
            if (i * j >= LOOP_BREAK_VALUE) then
                // recall the function in another thread to avoid a loop break.
                call .generatefield.execute(c,i)
                return false
            endif
            
        endloop  
        
        return false
    endmethod
    
    method onDestroy takes nothing returns nothing
        call TriggerClearActions(.TrigTrack)
        call TriggerClearActions(.TrigClick)
        call DisableTrigger(.TrigTrack)
        call DisableTrigger(.TrigClick)
        call DestroyTriggerDelayed.execute(.TrigTrack)
        call DestroyTriggerDelayed.execute(.TrigClick)
        set .TrigTrack = null
        set .TrigClick = null
    endmethod
    
    private static method onInit takes nothing returns nothing
        set .anyClick       = Event.create()
        set .anyTrack       = Event.create()
        set .ClickHandle    = Condition( function thistype.ClickHandleEx)
        set .TrackHandle    = Condition( function thistype.TrackHandleEx)
    endmethod
    
    method stop takes nothing returns nothing
        if not .active then
            return
        endif
        set .active    = false
        if .TrigTrack != null then
            call DisableTrigger(.TrigTrack)
        endif
        if .TrigClick != null then
            call DisableTrigger(.TrigClick)
        endif
    endmethod
    method resume takes nothing returns nothing
        if .active then
            return
        endif
        set .active    = true
        if .TrigTrack != null then
            call EnableTrigger(.TrigTrack)
        endif
        if .TrigClick != null then
            call EnableTrigger(.TrigClick)
        endif
    endmethod
endstruct

struct DynamicTrackMapGenerator
    private integer     i = -1
    private TrackMap    m
    private cache       c
    static method create takes TrackMap m, cache c returns thistype
        local thistype this = thistype.allocate()
        local timer t = CreateTimer()
        
        set .m              = m
        set .c              = c
        call SaveInteger(Hash, GetHandleId(t),SLOT_STRUCT,this)
        call TimerStart(t,TIMER_INTERVAL,true, function thistype.callback)
        
        return this
    endmethod
    static method callback takes nothing returns nothing 
        local timer t = GetExpiredTimer()
        local thistype this = LoadInteger(Hash,GetHandleId(t),SLOT_STRUCT)
        set .i = .i + 1
        if  .m.generatefield(.c,.i) then
            call RemoveSavedInteger(Hash,GetHandleId(t),SLOT_STRUCT)
            call DestroyTimer(t)
            call .destroy()
        endif
    endmethod
endstruct


// Usuable Functions

function SetUpTrackMap takes rect area, player p, boolean veryprecise returns TrackMap
    if veryprecise then
        return TrackMap.create(area ,GetPlayerId(p),MOUSEPOSITION_HIGH_PRECISION,true)
    else
        return TrackMap.create(area ,GetPlayerId(p),MOUSEPOSITION_LESS_PRECISION,true)
    endif
endfunction

function SetUpTrackMapEx takes rect area, player p, real precision, boolean timed returns TrackMap
    return TrackMap.create(area,GetPlayerId(p),precision,timed)
endfunction

function TriggerRegisterAnyMouseEvent takes trigger t returns nothing
    call TrackMap.registerAnyChange(t)
endfunction

function TriggerRegisterAnyClickEvent takes trigger t returns nothing
    call TrackMap.registerAnyClick(t)
endfunction

function TriggerRegisterAnyTrackEvent takes trigger t returns nothing
    call TrackMap.registerAnyTrack(t)
endfunction

function TriggerRegisterMouseEvent takes trigger t, TrackMap tm returns nothing
    call tm.registerChange(t)
endfunction

function TriggerRegisterClickEvent takes trigger t, TrackMap tm returns nothing
    call tm.registerClick(t)
endfunction

function TriggerRegisterTrackEvent takes trigger t, TrackMap tm returns nothing
    call tm.registerTrack(t)
endfunction

function Clicked takes nothing returns boolean  
    return clicked
endfunction

function Tracked takes nothing returns boolean
    return not clicked
endfunction

function GetMousePosX takes integer p returns real
    return TMpx[p]
endfunction

function GetMousePosY takes integer p returns real
    return TMpy[p]
endfunction

function GetTriggerMousePosX takes nothing returns real
    return TMpx[TMlastplayer]
endfunction

function GetTriggerMousePosY takes nothing returns real
    return TMpy[TMlastplayer]
endfunction

function GetTriggerTrackMap takes nothing returns TrackMap
    return TMlasttm
endfunction

function GetMouseUsingPlayer takes nothing returns player
    return Player(TMlastplayer)
endfunction

function GetMouseUsingPlayerId takes nothing returns integer
    return TMlastplayer
endfunction

endlibrary

Changelog:
v1.1a:
Fixed 2 Problems

v1.1:
Added Event
Code Optimization

v1.0:
first Release

Credits:

- Vexorian [JNGP]
- tamisrah [Advice]
- Azlier [Ideas]
- Jesus4Lyf [Event]

Hint:

The code in this post is more actual then the map.

Greetings.
 

Attachments

  • TrackMapSys.w3x
    33.9 KB · Views: 546

Azlier

Old World Ghost
Reaction score
461
You see, I made this cool thing called Trackable2 which [del]should be[/del] is more efficient than your current trackable setup.

You should also use a timer system like KT2 instead of dynamic timers.

You could even find a place for rectwraps to neaten things up in there with the aweslawsome .iterateThrough method. Though, I'm not totally sure.

Event would also be an excellent addition.

Dear God, did I just recommend 4 systems for one script?
 

Executor

I see you
Reaction score
57
Thank you for your feedback.

I believe you Trackable2 is a cool thing but I don't see why it [del]is[/del] should be more efficient in this situation. If you could explain this point to me maybe I'll modify my code.

Using KT2 won't be worth it because:
1. I want to have my library independent from other libraries (aslong as it isn't necessary)
2. How much TrackMap's do you think will a Map contain?
I need Timers only for the generation of the TrackMap in dynamic mode this means only once per struct and I think a maximum of 5 times per whole game^^ so..

rectwraps .. I'll check tomorrow if this library could enhance my speed drastically, but may be a good idea!
Same to event.
 

Azlier

Old World Ghost
Reaction score
461
>I believe you Trackable2 is a cool thing but I don't see why it is should be more efficient in this situation.

Well, you use hashtable for attachment. Hashtable is about twice the speed of game cache. Trackable2's attachment is faster than even H2I() - 0x100000 attachment. It's also incredibly stable. Oh, and the code simplification is nice, too.

>I'll check tomorrow if this library could enhance my speed drastically

Not drastically. Maybe just a tiny, tiny speed increase, if one at all. It will simplify your code, however.
 

Executor

I see you
Reaction score
57
Ah k I see the point with your Trackable2 library.
I thought you also somewhere used the "connection hashtable". But I think it would be enough to just modify the way of attachement to yours.
~ Tomorrow ~
Gn8
 

Azlier

Old World Ghost
Reaction score
461
I would just use Trackable2. Your code is all unorganized, so it'll become a pile of .evaluates and lots other unnecessary (and inefficient) stuff.

Trackable2 is about the best you get.
 

Executor

I see you
Reaction score
57
I don't think that thousands of triggers would be very effective.
Because a TrackMap over a whole Map can easily generate over 6000 trackables.
 

Jesus4Lyf

Good Idea™
Reaction score
397
I agree with Event - generally awesome to use.
I don't see why this uses timers at all?
Rectwraps seems a strange thing to use because I thought that was mostly for attaching to rects...

Trackable2. I love that system. I'm awfully fond of it. I'm not sure how it would fare with creating 6000 trackables for 12 different players on init.
JASS:
call PolledWait(3.)

Leaks.

I think Trackable2 even has a track any trackable Event... Hmm.
 

Azlier

Old World Ghost
Reaction score
461
>I think Trackable2 even has a track any trackable Event... Hmm.

Sevion suggested that, and it has been added.

>Rectwraps seems a strange thing to use because I thought that was mostly for attaching to rects...

Well, the code shortening is nice. So is the .iterateThrough method.

Strange? Indeed. Attaching to rects is useless since there's no such event response to get the rect. Rectwraps are magical like that.

>I don't see why this uses timers at all?

Me neither.
 

Executor

I see you
Reaction score
57
Isn't it obvius that the [creation of >6000 trackables + registering to the triggers] in one instant could lag?

So i created an option for the creation over time if the user wants a TrackMap to be generated while the game's running.

Okey rectwrap might clean my code up, but I don't think that it would be more efficient. And imo adding another system to "clean the code up" is senseless.

I will implement Event to connect the the 2 handle triggers to the TrackMap struct and will offer the option to register other triggers to my TrackMap as events are intended to.
 

Executor

I see you
Reaction score
57
>Isn't it obvius that the [creation of >6000 trackables + registering to the triggers] in one instant could lag?
Yes, that's why you shouldn't use timers to do it over time. It can be done on the map's loading screen. :D

So i created an option for the creation over time if the user wants a TrackMap to be generated while the game's running.

If you read the code you would have recognized that the creation over time is OPTIONAL.
 

Jesus4Lyf

Good Idea™
Reaction score
397
>Isn't it obvius that the [creation of >6000 trackables + registering to the triggers] in one instant could lag?
Yes, that's why you shouldn't OPTIONALLY use timers to do it over time. It can be done on the map's loading screen. :D
Better?

Anyway, why does this require dummy.mdx?
And because this uses those doodad platform things, this actually looks kinda cool. :)
 

Executor

I see you
Reaction score
57
Anyway, why does this require dummy.mdx?

Because I'm stupid and forgot that i only used this dummy for test purposes. :D


Hm, it seems like I'm not getting your point. You have 2 possibilites to create a TrackMap:

1. [Timed = false] => one fat loop that generates the whole TrackMap as fast as possible, to use in LoadingScreen because of the lag which would occure while the game's running.

2. [Timed = true] => the TrackMap creates itself slowly in a few seconds without any lag, allowing TrackMap's to be created ingame without any lag.

That's why I use a timer.
 

Jesus4Lyf

Good Idea™
Reaction score
397
Your current justification for having a timer is lag. But doing it in the loading screen is a far better option if you don't want lag. Therefore there is no justification for an optional timed method? Please inform me if there is.
JASS:
        local thistype map = GetTriggerExecCount(GetTriggeringTrigger())
        local trackdata d = LoadInteger(ht,GetHandleId(GetTriggeringTrackable()),SLOT_TRACKDATA)

What's the point of using TriggerExecCount if you're using GetHandleId as well? The only (practical) reason to use TriggerExecCount is 1.23 compatability, which you have broken otherwise anyway. :banghead: (Edit: Actually, in this case, since it is for a struct with a low number of instances, it may be ok anyway.)

Don't get me wrong, I like the method. But if you want to make 1.23 compatability a feature, do so, and if you don't, then I don't recommend you use ExecCount attachment. (And I'll go use Trackable2 probably. XD)

I really like that you don't use a custom model for your trackables. :)
 

Executor

I see you
Reaction score
57
Your current justification for having a timer is lag. But doing it in the loading screen is a far better option if you don't want lag. Therefore there is no justification for an optional timed method? Please inform me if there is.

Of course you're right. TrackMap's should be created in the LoadingScreen, due to their immobility and their indestructibility, but sometimes for example if you can choose whether you are a ingame mapper or a "runner", it is important to have the possibility to generate them while the game's running.

JASS:
        local thistype map = GetTriggerExecCount(GetTriggeringTrigger())
        local trackdata d = LoadInteger(ht,GetHandleId(GetTriggeringTrackable()),SLOT_TRACKDATA)

What's the point of using TriggerExecCount if you're using GetHandleId as well? The only (practical) reason to use TriggerExecCount is 1.23 compatability, which you have broken otherwise anyway. :banghead: (Edit: Actually, in this case, since it is for a struct with a low number of instances, it may be ok anyway.)

As you said, in this case it is not as computation-intensive as in other situation.
Furthermore this triggers will remain the whole game over and due to the GetTriggerEvalCount this connection is faster than LoadInteger which is important for Triggers (like this) which fire this often.

Don't get me wrong, I like the method. But if you want to make 1.23 compatability a feature, do so, and if you don't, then I don't recommend you use ExecCount attachment. (And I'll go use Trackable2 probably. XD)

I don't want to make a 1.23 compatability feature.. it's all about the speed ;)

I really like that you don't use a custom model for your trackables. :)

Thank you! It is important to me that my libraries doesn't require to much extra material.
 

Azlier

Old World Ghost
Reaction score
461
If I were to base a map on this track map thingy, wouldn't it be laggier and inaccurate compared to this solution?

It detects the X/Y of left clicks and can detect right clicks with ease.
 

Executor

I see you
Reaction score
57
Yes, this solution is even better than mine.. EXCEPT that you cannot access the onTrack Event. Otherwise it got the advantage of not being buggy and of being deactivatable completely.
Well ...
 

Azlier

Old World Ghost
Reaction score
461
Mine could probably be improved to not replace the icons of the basic commands (move, attack, etc.). That would make it rather perfect, overall.

Oh, and I could probably replace the timer that presses the T key every 0.005 seconds. I had to replace the basic 'click' sound when an order is issued for that. No timer would make it fail more often on multiplayer, but it would reduce the amount of those annoying clicks.

Meh.
 
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