1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still haven't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. Lead your forces to battle in the 15th Techtree Contest. The call is yours, commander!
    Dismiss Notice
  4. The reforging of the races is complete. Come see the 14th Techtree Contest Results.
    Dismiss Notice
  5. It's time to choose your horse in the race - the 32nd Modeling Contest Poll is up!
    Dismiss Notice
  6. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[vJASS] Mpi trackables?

Discussion in 'Triggers & Scripts' started by dardas, May 17, 2011.

  1. dardas

    dardas

    Joined:
    Sep 12, 2008
    Messages:
    649
    Resources:
    0
    Resources:
    0
    Hey, i've made my first trackables code, and i tested it on 1 player, worked just fine, added another player (with a loop to re-create the trackables),
    and it seemed to fail, it only showed units to the first player, not the second.
    i need it to be a trackable per player, since i show messages to only 1 player.

    heres my entire code:
    Code (vJASS):

    library TTest initializer onInit
       
        globals
            private hashtable Track_Table = InitHashtable()
        endglobals
       
        private function CreateTrackableEx takes player p, string model, real x, real y, real z, real facing returns trackable
            local destructable dest
            local trackable tr
           
            if GetLocalPlayer() == p then
                set dest = CreateDestructableZ('OTip', x, y, z, 0, 1, 0)
                set tr = CreateTrackable(model, x, y, facing)
                call RemoveDestructable(dest)
            endif
           
            return tr
            endfunction
       
        private function OnEscape takes nothing returns boolean
            local integer trId = LoadInteger(Track_Table, GetHandleId(GetTriggerPlayer()), 0)
            if not (trId == null) then
                call CreateUnit(GetTriggerPlayer(), trId, 0, 0, 180)
            endif
            return false
        endfunction
       
        private function onTrackHit takes nothing returns boolean
            local integer id = GetHandleId(GetTriggeringTrackable())
            local integer lines = LoadInteger(Track_Table, id, 0)
            local integer count = 0
            local player p = LoadPlayerHandle(Track_Table, id, 1)
           
            loop
                exitwhen count >= lines
                if GetLocalPlayer() == p then
                    if count == 0 then
                        call ClearTextMessages()
                    endif
                    call BJDebugMsg(LoadStr(Track_Table, id, count + 3))
                endif
                set count = count + 1
            endloop
           
            call SaveInteger(Track_Table, GetHandleId(p), 0, LoadInteger(Track_Table, id, 2))
           
            return false
        endfunction
       
        private function onInit takes nothing returns nothing
            //Creating the trackables
            local trigger t = CreateTrigger()
            local trigger t2 = CreateTrigger()
            local trackable tr
            local integer id
            local integer i = 0
            call TriggerAddCondition(t, Filter(function onTrackHit))
           
            call TriggerAddCondition(t2, Filter(function OnEscape))
            loop
            exitwhen i >= 2
           
            call TriggerRegisterPlayerEventEndCinematic(t2, Player(i))
           
            set tr = /*
            */
    CreateTrackableEx(Player(i), "units\\human\\Footman\\Footman.mdl", GetRectCenterX(gg_rct_Item_0), GetRectCenterY(gg_rct_Item_0), 0, 180)
            set id = GetHandleId(tr)
           
            call TriggerRegisterTrackableHitEvent(t, tr) // Registering the event
            call SaveInteger(Track_Table, id, 0, 3) // Setting amount of text lines to apply
            call SavePlayerHandle(Track_Table, id, 1, Player(i)) // Saves the player who should see the trackable.
            call SaveInteger(Track_Table, id, 2, 'hfoo') //Saves the raw id of the unit.
            call SaveStr(Track_Table, id, 3, "|c00FF0000Footman: |r") // Line 1/3 of the text
            call SaveStr(Track_Table, id, 4, "|c0000FF00Versatile foot soldier. Can learn the Defend ability. |r") //Line 2/3 of the text
            call SaveStr(Track_Table, id, 5, "|cffffcc00Attacks land units. |r") // Line 3/3 of the text
           
            set tr = /*
            */
    CreateTrackableEx(Player(i), "units\\human\\Rifleman\\Rifleman.mdl", GetRectCenterX(gg_rct_Item_1), GetRectCenterY(gg_rct_Item_1), 0, 180)
            set id = GetHandleId(tr)
           
            call TriggerRegisterTrackableHitEvent(t, tr)
            call SaveInteger(Track_Table, id, 0, 3)
            call SavePlayerHandle(Track_Table, id, 1, Player(i))
            call SaveInteger(Track_Table, id, 2, 'hrif')
            call SaveStr(Track_Table, id, 3, "|c00FF0000Rifleman: |r")
            call SaveStr(Track_Table, id, 4, "|c0000FF00Highly skilled sharpshooter, effective against air units. Can gain the Long Rifles upgrade. |r")
            call SaveStr(Track_Table, id, 5, "|cffffcc00Attacks land and air units. |r")
           
            set tr = /*
            */
    CreateTrackableEx(Player(i), "units\\human\\Knight\\Knight.mdl", GetRectCenterX(gg_rct_Item_2), GetRectCenterY(gg_rct_Item_2), 0, 180)
            set id = GetHandleId(tr)
           
            call TriggerRegisterTrackableHitEvent(t, tr)
            call SaveInteger(Track_Table, id, 0, 3)
            call SavePlayerHandle(Track_Table, id, 1, Player(i))
            call SaveInteger(Track_Table, id, 2, 'hkni')
            call SaveStr(Track_Table, id, 3, "|c00FF0000Knight: |r")
            call SaveStr(Track_Table, id, 4, "|c0000FF00Powerful mounted warrior. Can learn Animal War Training. |r")
            call SaveStr(Track_Table, id, 5, "|cffffcc00Attacks land units. |r")
           
            set tr = /*
            */
    CreateTrackableEx(Player(i), "units\\human\\Priest\\Priest.mdl", GetRectCenterX(gg_rct_Item_3), GetRectCenterY(gg_rct_Item_3), 0, 180)
            set id = GetHandleId(tr)
           
            call TriggerRegisterTrackableHitEvent(t, tr)
            call SaveInteger(Track_Table, id, 0, 3)
            call SavePlayerHandle(Track_Table, id, 1, Player(i))
            call SaveInteger(Track_Table, id, 2, 'hmpr')
            call SaveStr(Track_Table, id, 3, "|c00FF0000Priest: |r")
            call SaveStr(Track_Table, id, 4, "|c0000FF00Supporting spellcaster. Can initially cast Heal, which increases the life of wounded units. Can also learn Dispel Magic and Inner Fire. |r")
            call SaveStr(Track_Table, id, 5, "|cffffcc00Attacks land and air units. |r")
           
            set i = i + 1
            endloop
           
        endfunction
       
    endlibrary
     


    Also, not about trackables, this seemed to also not show the image to the second player,
    using ImageUtils imagex struct:

    Code (vJASS):

    library TestingImages initializer onInit requires ImageUtils
       
        globals
            private imagex array Image
        endglobals
       
        private function LoopActions takes nothing returns nothing
            local real x = GetCameraEyePositionX() + 1500 * Cos(90 * bj_DEGTORAD)
            local real y = GetCameraEyePositionY() + 1500 * Sin(90 * bj_DEGTORAD)
            local integer i = 0
           
            loop
            exitwhen i >= 1
            if GetLocalPlayer() == Player(i) then
                set Image[i].x = x + 200 * Cos(0)
                set Image[i].y = y + 200 * Sin(0)
                set Image[i].show = true
            endif
            set i = i + 1
            endloop
        endfunction
       
        private function onInit takes nothing returns nothing
            set Image[0] = imagex.create("ReplaceableTextures\\CommandButtons\\BTNRifleman", 64, 64, 64, 64, 0, false)
            set Image[1] = imagex.create("ReplaceableTextures\\CommandButtons\\BTNFootman", 64, 64, 64, 64, 0, false)
            call TimerStart(CreateTimer(), 0., true, function LoopActions)
        endfunction
       
    endlibrary
     


    Thanks in advance to all helpers.

    Edit: found the problem with the images, i made it loop untill "i" is greater or equal to 1, so it passed 0, then stopped, and didnt reach player 2.
    Anyhow, still having problems with trackables.

    Edit2: found the problem with trackables, you can lock this. the solution:
    i've forgot wc has stupid try catches to prevent people from bugging,
    so it crushed when it tried getting local player of a player that is not in game..
     
  2. Pharaoh_

    Pharaoh_

    Joined:
    Nov 6, 2008
    Messages:
    8,128
    Resources:
    11
    Icons:
    3
    Skins:
    1
    Spells:
    6
    Tutorials:
    1
    Resources:
    11
  3. dardas

    dardas

    Joined:
    Sep 12, 2008
    Messages:
    649
    Resources:
    0
    Resources:
    0
    Oh thanks, i didnt see that code ^^ guess its much easier for me now,
    since re-creating each trackable is seriusly annoying, thanks again pharoh. +rep

    edit: is there any way to detect double click using an external library? i dont wanna create timer every time now..
    Thanks in advance.

    edit: got bored and decided to create my own library.
    heres the code:
    Code (vJASS):

    library ODC requires Trackable2
       
        public struct OnDoubleClick
            public static integer InstanceCount = 0
            public static hashtable TimerHash = InitHashtable()
            public Trackable2 track
            private Event onDoubleClick
            public real MaxDelay
            public boolean TwoClicks
           
            public static method create takes Trackable2 track, trigger t, real MaxDelay returns thistype
                local thistype this = thistype.allocate()
                local trigger tri = CreateTrigger()
                call TriggerAddCondition(tri, Filter(function thistype.onClick))
                set .onDoubleClick = Event.create()
                call track.registerClick(tri)
                set .MaxDelay = MaxDelay
                set .track = track
               
                set .InstanceCount = this + 1
                return this
            endmethod
           
            public method registerOnDoubleClick takes trigger t returns EventReg
                local EventReg reg = onDoubleClick.register(t)
                set reg.data = this
                return reg
            endmethod
           
            private static method DestroyDoubleClick takes nothing returns nothing
                local timer tim = GetExpiredTimer()
                local thistype t = LoadInteger(TimerHash, GetHandleId(tim), 0)
               
                set t.TwoClicks = false
               
                call FlushChildHashtable(TimerHash, GetHandleId(tim))
                call DestroyTimer(tim)
            endmethod
           
            private static method onClick takes nothing returns boolean
                local Trackable2 t = GetTriggeringTrackable2()
                local timer tim
                local integer i = integer(t)
                local integer c = 1
                local thistype this = 0
               
                loop
                exitwhen c>=InstanceCount
                set this = thistype(c)
                if .track == t then
                    set c = InstanceCount - 1
                endif
                set c=c+1
                endloop
               
                if .TwoClicks then
                    call .onDoubleClick.fire()
                endif
               
                set .TwoClicks = true
               
                set tim = CreateTimer()
                call TimerStart(tim, .MaxDelay, false, function thistype.DestroyDoubleClick)
                call SaveInteger(TimerHash, GetHandleId(tim), 0, this)
                call SavePlayerHandle(TimerHash, GetHandleId(tim), 1, GetTrackedPlayer())
                set tim = null
               
                return false
            endmethod
        endstruct
       
    endlibrary
     

    just use GetTriggeringTrackable2() and GetTrackedPlayer() as if its the "onClick" event of Trackable2.

    You can close this i supose..
     
    Last edited: May 19, 2011