• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[vJASS] Mpi trackables?

Status
Not open for further replies.
Level 11
Joined
Sep 12, 2008
Messages
657
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:
JASS:
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:

JASS:
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..
 
Level 11
Joined
Sep 12, 2008
Messages
657
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:
JASS:
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:
Status
Not open for further replies.
Top