WC3Jass.com Forum Index WC3Jass.com
"The Jass Vault"
 
 FAQ   Search   Memberlist   Usergroups   Register 
 Profile   Log in to check your private messages   Log in  
 Forum   Scripts   Files   Chat   Pastebin   Function finder  
Affiliates
The HIVE Workshop Games Modding
The Hubb Wc3Campaigns
WC3-Mapping.net

Trackables (Mouse detection)
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    WC3Jass.com Forum Index -> Tutorials
View previous script :: View next script  

Author
KaTTaNa
Site Admin

Joined: 04 Apr 2005
Posts: 655
Back to top
Message
PostPosted: Mon Apr 18, 2005 9:23 pm    Post subject: Trackables (Mouse detection) Reply with quote

Here is a quick right-to-the-point tutorial for people already familiar with Jass.
You should be able to start experimenting with Trackables immediately after reading through this.

What is a trackable?
A trackable is a model displayed in the game, similiar to a special effect.
It stands out by being able to detect whenever the mouse moves over this model, and when the mouse clicks it.
Problems are that we cannot delete, move or hide a trackable again.
Update: Trackable do work in multiplayer.

Creating a trackable
Code:
native CreateTrackable takes string trackableModelPath, real x, real y, real facing returns trackable

Example:
Code:
local trackable tr = CreateTrackable("Buildings\\Human\\HumanTower\\HumanTower.mdl", -1024, 512, 90)



Detecting mouse events
Code:
native TriggerRegisterTrackableHitEvent takes trigger whichTrigger, trackable t returns event
native TriggerRegisterTrackableTrackEvent takes trigger whichTrigger, trackable t returns event

TrackableHitEvent fires when mouse clicks the trackable.
TrackableTrackEvent fires when mouse moves over the trackable.

Using trackables
There is one last native related to trackables...
Code:
native GetTriggeringTrackable takes nothing returns trackable

This refers to the trackable that fired the mouse event.
We don't have any natives for getting the (x,y) coordinates of a trackable, but we can handle that ourselves with the Local Handle Variables.
Here is a custom API for extended use of trackables.
Code:

// ===========================
//   Trackable API

function GetTrackableX takes trackable tc returns real
    return GetHandleReal(tc, "x")
endfunction
function GetTrackableY takes trackable tc returns real
    return GetHandleReal(tc, "y")
endfunction
function GetTrackableFacing takes trackable tc returns real
    return GetHandleReal(tc, "facing")
endfunction
function GetTrackablePath takes trackable tc returns string
    return GetHandleString(tc, "path")
endfunction

function NewTrackable takes string path, real x, real y, real facing returns trackable
    local trackable tc = CreateTrackable(path, x, y, facing)
    call SetHandleReal(tc, "x", x)
    call SetHandleReal(tc, "y", y)
    call SetHandleReal(tc, "facing", facing)
    call SetHandleString(tc, "path", path)
    return tc
endfunction



Example map
I made a remake of an old classic game where countless rockets are falling from the sky threatening to waste your precious farms.
You have to shoot the rockets by clicking near them on the ground.
Download here.

Trackables in Multiplayer
Previously, the tutorial stated that trackables didn't work in multiplayer, but that was wrong. They work fine, and they don't desynchronize the game.
However, there is no way to determine which player triggered the event on a trackable. We can work around this by creating a trackable for each player - each can only be triggered by one player.
Code:
    // t1 and t2 are visually the same trackable, but in fact they only work for one player each
    local trackable t1 // Player 1's trackable
    local trackable t2 // Player 2's trackable
    local string peasant = "units\\human\\Peasant\\Peasant.mdl"
    local string invisible = ""
    local string path = invisible

    if ( GetLocalPlayer() == Player(0) ) then
        set path = peasant
    endif
    set t1 = CreateTrackable(path, -500, 0, 0)

    set path = invisible
    if ( GetLocalPlayer() == Player(1) ) then
        set path = peasant
    endif
    set t2 = CreateTrackable(path, -500, 0, 0)

    call SetHandleInt(t1, "player", 0) // Store which player "owns" this trackable
    call SetHandleInt(t2, "player", 1) // Same for player 2

    // Add events to register track/hit on t1 and t2...


After this, you can determine the player triggering a trackable by reading the local integer named "player" on the triggering trackable.

We can extend to NewTrackable if you like:
Code:

function GetTrackableOwner takes trackable t returns player
    return Player(GetHandleInt(t, "player"))
endfunction

function NewTrackable takes string path, real x, real y, real facing, player owner returns trackable
    local trackable tc
    local string invisible = ""
    if GetLocalPlayer() != owner then
        set path = invisible
    endif
    set tc = CreateTrackable(path, x, y, facing)
    call SetHandleReal(tc, "x", x)
    call SetHandleReal(tc, "y", y)
    call SetHandleReal(tc, "facing", facing)
    call SetHandleString(tc, "path", path)
    call SetHandleInt(tc, "player", GetPlayerId(owner))
    return tc
endfunction



Giving height to Trackables
Although the natives do not allow it, a simple workaround enables us to create trackables at a given height above ground.
Code:
function CreateTrackableZ takes string path, real x, real y, real z, real face returns trackable
    local destructable d = CreateDestructableZ( 'OTip', x, y, z, 0.00, 1, 0 )
    local trackable tr = CreateTrackable( path, x, y, face )
    call RemoveDestructable( d )
    set d = null
    return tr
endfunction

It works by creating an Invisible Platform at the given height, and then creating the trackable on top of that. After removing the platform, the trackable stays in place.

Building on top of our previous code:
Code:

function NewTrackable takes string path, real x, real y, real z, real facing, player owner returns trackable
    local trackable tc
    local string invisible = ""
    local destructable d = CreateDestructableZ( 'OTip', x, y, z, 0.00, 1.00, 0 )
    if GetLocalPlayer() != owner then
        set path = invisible
    endif
    set tc = CreateTrackable(path, x, y, facing)
    call RemoveDestructable( d )
    set d = null
    call SetHandleReal(tc, "x", x)
    call SetHandleReal(tc, "y", y)
    call SetHandleReal(tc, "z", z)
    call SetHandleReal(tc, "facing", facing)
    call SetHandleString(tc, "path", path)
    call SetHandleInt(tc, "player", GetPlayerId(owner))
    return tc
endfunction



Historical reading
If you are interested, you can read a bit more about trackables in this thread.


Last edited by KaTTaNa on Sun Nov 20, 2005 1:57 pm; edited 9 times in total
View user's profile Send private message Send e-mail Visit poster's website

Author
Agaricus


Joined: 07 Apr 2005
Posts: 72
Back to top
Message
PostPosted: Thu May 12, 2005 12:15 am    Post subject: Reply with quote

I'm not that good at reading JASS I don't write so, I would like to ask you how your demo map works? To me it looks like you create trackables when they player clicks. Fun game.

EDIT:
Anyone know why Blizzard doesn't finish trackables? Make player specific and removable.
View user's profile Send private message

Author
KaTTaNa
Site Admin

Joined: 04 Apr 2005
Posts: 655
Back to top
Message
PostPosted: Thu May 12, 2005 11:06 am    Post subject: Reply with quote

My code in the example map isn't that good actually, but what I do is like this:

  • Initialization
  • Create a trackable (invisble) at each grid-point in the game area (one grid cell is like 128.0 wide and high)
  • For each of these trackables, store their X,Y coordinates and add their hit event to the fire trigger, so it shoots when one of the trackables are clicked.

  • The fire trigger
  • In the shoot trigger, get the X,Y coordinates of the trackable.
  • Play the explosion effect at X,Y (...and destroy again)
  • Find all rockets near X,Y and kill them.

  • Rocket spawning
  • Choose random point in top region and another random point in bottom region.
  • Create a rocket at first point and order it to move to the second point.

I'm not sure if that was of any help, but I don't create any trackables after map initialization.

I assume that Blizzard didn't see trackables needed after all so they quit working on them. It would hardly be too much work making them, since units (and some doodads) also need mouse detection.
View user's profile Send private message Send e-mail Visit poster's website

Author
Agaricus


Joined: 07 Apr 2005
Posts: 72
Back to top
Message
PostPosted: Thu May 12, 2005 8:30 pm    Post subject: Reply with quote

Could a player specific trackable be made in the same way that a local multiboard is made? Trackables are something I think Blizzard should complete because it could be used for things like extra buttons and UI, like a clickable multiboard inventory.
View user's profile Send private message

Author
KaTTaNa
Site Admin

Joined: 04 Apr 2005
Posts: 655
Back to top
Message
PostPosted: Thu May 12, 2005 8:32 pm    Post subject: Reply with quote

I once thought so, but someone tested it and it seems that trackables don't work in multiplayer at all.

And I actually said this in my first post...
KaTTaNa wrote:
It appears that trackables don't work in multiplayer.
View user's profile Send private message Send e-mail Visit poster's website

Author
Citizen_Snips


Joined: 28 Jul 2005
Posts: 4
Back to top
Message
PostPosted: Fri Jul 29, 2005 7:29 pm    Post subject: Reply with quote

Is it possible to use a rifleman instead of a mortar team and how do you chnage the "blast" that appears to hit the ground when an area is selected?
View user's profile Send private message

Author
KaTTaNa
Site Admin

Joined: 04 Apr 2005
Posts: 655
Back to top
Message
PostPosted: Sat Jul 30, 2005 9:24 am    Post subject: Reply with quote

Of course you can use a rifleman instead.
The mortar team is just a normal unit with the locust ability (Aloc) so you can't select it.
The "blast" is a special effect I play. Just find the model somewhere in the code and change it.
View user's profile Send private message Send e-mail Visit poster's website

Author
Linera


Joined: 30 Aug 2005
Posts: 3
Back to top
Message
PostPosted: Mon Oct 03, 2005 6:16 am    Post subject: Reply with quote

Trackables do work in multiplayer
_________________
Linera
-Queen of Darkness-
View user's profile Send private message

Author
KaTTaNa
Site Admin

Joined: 04 Apr 2005
Posts: 655
Back to top
Message
PostPosted: Sat Oct 08, 2005 8:59 am    Post subject: Reply with quote

Linera wrote:
Trackables do work in multiplayer

I see - have you tested it? Do the events work without desyncs?
If yes, please post your tests and results so we can settle it.
View user's profile Send private message Send e-mail Visit poster's website

Author
KaTTaNa
Site Admin

Joined: 04 Apr 2005
Posts: 655
Back to top
Message
PostPosted: Tue Oct 11, 2005 2:12 pm    Post subject: Reply with quote

You are right. They do indeed work in multiplayer. I have expanded the tutorial with another section regarding trackables in multiplayer.
View user's profile Send private message Send e-mail Visit poster's website

Author
Blackroot
Guest



Back to top
Message
PostPosted: Thu Oct 13, 2005 9:50 am    Post subject: Reply with quote

Wow, very nice game! Just one question:

To use trackable detection, do you need to have your camera directly over the trackable?

-Also i tried dis-assembling your jass, but i cant get it to work, i get tons of errors. (Also when i change the model file of the trackable, wc3 crashs.)

Heres my jass if it helps any:
Code:

function TrackableTrack takes nothing returns nothing
    local real x = GetTrackableX(GetTriggeringTrackable())
    local real y = GetTrackableY(GetTriggeringTrackable())
    local location loc = Location(x,y)
endfunction

function TrackableHit takes nothing returns nothing
    local real x = GetTrackableX(GetTriggeringTrackable())
    local real y = GetTrackableY(GetTriggeringTrackable())
endfunction

function Trig_Init_Trackables_Actions takes nothing returns nothing
    local trigger hit = CreateTrigger()
    local trigger track = CreateTrigger()
    local real x = GetLocationX(GetRectCenter(gg_rct_SlotTrackables))
    local real y = GetLocationX(GetRectCenter(gg_rct_SlotTrackables))
    call NewTrackable("war3mapImported\\4x4Trackable.mdl", x, y, GetPlayersAll(), track, hit)
    call TriggerAddAction(hit, function TrackableHit)
    call TriggerAddAction(track, function TrackableTrack)
endfunction

//===========================================================================
function InitTrig_Init_Trackables takes nothing returns nothing
    set gg_trg_Init_Trackables = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Init_Trackables, function Trig_Init_Trackables_Actions )
endfunction



Im a noob to jass, so i dont really know how to fix anything. But i plugged this into your compiler kat, and it said no errors were detected... So im totaly confused -,-.

Author
KaTTaNa
Site Admin

Joined: 04 Apr 2005
Posts: 655
Back to top
Message
PostPosted: Thu Oct 13, 2005 10:06 am    Post subject: Reply with quote

The syntax checker in my Jass Editor is rubbish - do NOT use it.

Quote:
To use trackable detection, do you need to have your camera directly over the trackable?

No, the trackable is in fact a visible object that detects mouse just like units do. The reason you can't see them in my map is that the 4x4Trackable.mdl model is transparent.

And the code in my map is very old and very poor. Use the code from this tutorial instead.

And for your code to work, make sure you have the Local Handle Variables in your map header, above the trackable API from the tutorial.

Oh and this line is obviously wrong (the bane of copy/pasting)
Code:
local real y = GetLocationX(GetRectCenter(gg_rct_SlotTrackables))
// Use GetLocationY instead

View user's profile Send private message Send e-mail Visit poster's website

Author
Blackroot
Guest



Back to top
Message
PostPosted: Fri Oct 14, 2005 12:00 am    Post subject: ROFL Reply with quote

Yeah my jass was your jass cnped and attempted to edit. Razz. Anyways, i found the problem with your code was that i had no variable handlers. Its a total pain to cnp it, seeing as text editors see it as a block of text with no spaces >.>.

Good thing your map has it ^,^. Go cnp!

Author
Blackroot
Guest



Back to top
Message
PostPosted: Mon Oct 31, 2005 9:34 am    Post subject: Reply with quote

Is there any way to float a trackable? Or give it a Z value? Or is a trackable seen at any height?
-And if it is, can it return a Z value "on hit"?

Just wondering if its possible, would make for an awesome shooter O_o.

Author
KaTTaNa
Site Admin

Joined: 04 Apr 2005
Posts: 655
Back to top
Message
PostPosted: Mon Oct 31, 2005 1:41 pm    Post subject: Reply with quote

Here, I found a way to give it a Z height. See CreateTrackableZ.

You cannot know where on the trackable the mouse hit it, but you can store the Z coordinate on the trackable using your preferred gamecache method (Handle Vars is one example).

Gonna update the tutorial to include the Z coordinate thing.
View user's profile Send private message Send e-mail Visit poster's website

Display posts from previous:   
Post new topic   Reply to topic    WC3Jass.com Forum Index -> Tutorials All times are GMT
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


FSDark by SkaidonDesigns
Powered by phpBB © 2001, 2002 phpBB Group