| 09-07-2009, 03:45 PM | #1 |
Hi people. I wanted to use trackables for one of my projects, however now I see it is not the good solution. However I made this library and I think it can help other people in a nice way, so now I am transforming it into a resource and I intend to upload it. I also took the liberty of adding some extra components to the basic stuff such as filling a region or area with trackables. So far it needs Table, but I would like to make this resource auto-sufficient, I would like to know how to use hastables on my own. I am open to suggestions, maybe I will create something like a "trackable group" later using a list, but I still don't know it can be of any use. JASS://=========================================================================== //This simple library defines a trackable. It allows to store information //about a trackable such as it's position, owner, facing angle, etc and it //also allows for the user to attach a structure to the trackable. //This library also allows to create trackables over a region. // //Version 1.2.0 // //Author: // - Flame_Phoenix // //Requirements: // - Table from Vexorian // //Credits: // - Kattana, for his tutorial // - Hans_Maulwurf, for code inspiration, ideas and typo reports // //Methods: //static method advancedCreate takes real x, real y, real facing, string path, player owner, //code onTrack, code onClick returns Trackable // - Create a Trackable object with the given data // ////static method create takes real x, real y, player owner, //code onTrack, code onClick returns Trackable // - Create a Trackable object with the given data. In this case the default the script will //use DEFAULT_ANGLE and DEFAULT_PATH to create the trackable. // //method onDestroy takes nothing returns nothing // - trackables cannot be destroyed. However we can disable and destroy the triggers that //run them, and we can remove the Trackable object from table. This is what this method does. // //Members you can use: //this.x - the X coordinate of the trackable. Has read permissions. //this.y - the Y coordinate of the trackable. Has read permissions. //this.facing - the facing angle of the trackable. Has read permissions. //this.path - the path (model being used) of the tracable. Has read permissions. //this.tracker - the trackable itself. Has read permissions. //this.owner - the owner of the trackable. Has read permissions. //this.data - it can be a structure attached to the Trackable object. Has write and read permissions. //this.onClickTrgAction - this is the function that runs when you click the trackable. Has write permissions. //this.onTrackTrgAction - this is the function that runs when you over the trackable. Has write permissions. // //Note: to change a member just do "myTrack.data = blablabal" //Note: to access a member just do "local real myX = myTrack.x" // //Functions: //function CreateTrackedRegion takes rect where, real trackSize, string path, real facing, player owner, //code onTrack, code onClick returns nothing // - This function fills a region with trackables. There is little to say. // //function CreateTrackedArea takes real topLeftX, real topLeftY, real width, real height, real trackSize, //string path, real facing, player owner, code onTrack, code onClick returns nothing // - This function does the same thing the previous function does, but it doesn't require a rect. Instead it //takes the top left corner of the area and then it lets the magic happen. // //NOTE: you must be carefull when using functions CreateTrackedRegion and CreatedTrackedArea. If the area or //the region to fill is too big, you will hit the oplimit of the thread and the region will be 100% filled //with trackables. // //function GetTrackableData takes trackable whichTrackable returns Trackable // - this is used to get the information from a trackable. See the example: // private function TrackableHit takes nothing returns nothing // local Trackable tracker = GetTrackableData(GetTriggeringTrackable()) // call BJDebugMsg("cliked!") // call BJDebugMsg("x = " + R2S(tracker.x)) // call BJDebugMsg("y = " + R2S(tracker.y)) // endfunction // //=========================================================================== library Trackable initializer Init requires Table //=========================================================================== //=============================SETUP START=================================== //=========================================================================== globals //destroying triggers has some obscure effects. In this case I allow it, //but if you think this is causing porblems, just set the boolean valu to false. //Know that no matter the value this boolean flag holds, the triggers of a trackable //are always disabled when you call onDestroy. public constant boolean DESTROY_TRIGGERS = true public constant string DEFAULT_PATH = "units\\human\\Peasant\\Peasant.mdl" public constant real DEFAULT_ANGLE = 0. endglobals //=========================================================================== //=============================SETUP END===================================== //=========================================================================== globals private HandleTable activeTable //your private Table's global variable endglobals struct Trackable private real tcX private real tcY private real tcFacing private string tcPath = "" private trackable track private player tcOwner private integer tcData private trigger onTrackTrg = null private trigger onClickTrg = null static method advancedCreate takes real x, real y, real facing, string path, player owner, code onTrack, code onClick returns Trackable local Trackable this = Trackable.allocate() if GetLocalPlayer() == owner then set .tcPath = path endif set .tcX = x set .tcY = y set .tcFacing = facing set .tcOwner = owner set .track = CreateTrackable(.tcPath, .tcX, .tcY, .tcFacing) if onClick != null then set .onClickTrg = CreateTrigger() call TriggerRegisterTrackableHitEvent(.onClickTrg, .track) call TriggerAddAction(.onClickTrg, onClick) endif if onTrack != null then set .onTrackTrg = CreateTrigger() call TriggerRegisterTrackableTrackEvent(.onTrackTrg, .track) call TriggerAddAction(.onTrackTrg, onTrack) endif //save this struct into Table set activeTable[.track] = this return this endmethod static method create takes real x, real y, player owner, code onTrack, code onClick returns Trackable local Trackable this = Trackable.allocate() if GetLocalPlayer() == owner then set .tcPath = DEFAULT_PATH endif set .tcX = x set .tcY = y set .tcFacing = DEFAULT_ANGLE set .tcOwner = owner set .track = CreateTrackable(.tcPath, .tcX, .tcY, DEFAULT_ANGLE) if onClick != null then set .onClickTrg = CreateTrigger() call TriggerRegisterTrackableHitEvent(.onClickTrg, .track) call TriggerAddAction(.onClickTrg, onClick) endif if onTrack != null then set .onTrackTrg = CreateTrigger() call TriggerRegisterTrackableTrackEvent(.onTrackTrg, .track) call TriggerAddAction(.onTrackTrg, onTrack) endif //save this struct into Table set activeTable[.track] = this return this endmethod method onDestroy takes nothing returns nothing //disable the triggers if .onTrackTrg != null then call DisableTrigger(.onTrackTrg) endif if .onClickTrg!= null then call DisableTrigger(.onClickTrg) endif //the user may not want to destroy the triggers if DESTROY_TRIGGERS then if .onTrackTrg != null then call DestroyTrigger(.onTrackTrg) endif if .onClickTrg!= null then call DestroyTrigger(.onClickTrg) endif endif //remove trackable from Table call activeTable.flush(.track) endmethod //getters method operator x takes nothing returns real return .tcX endmethod method operator y takes nothing returns real return .tcY endmethod method operator facing takes nothing returns real return .tcFacing endmethod method operator path takes nothing returns string return .tcPath endmethod method operator tracker takes nothing returns trackable return .track endmethod method operator owner takes nothing returns player return .tcOwner endmethod method operator data takes nothing returns integer return .tcData endmethod //setters method operator data= takes integer newData returns nothing set .tcData = newData endmethod method operator onClickTrgAction= takes code newFunction returns nothing //we get rid of the old trigger if .onClickTrg != null then call DisableTrigger(.onClickTrg) if DESTROY_TRIGGERS then call DestroyTrigger(.onClickTrg) endif endif //create a new one set .onClickTrg = CreateTrigger() call TriggerRegisterTrackableHitEvent(.onClickTrg, .track) //register actions call TriggerAddAction(.onClickTrg, newFunction) endmethod method operator onTrackTrgAction= takes code newFunction returns nothing //we get rid of the old trigger if .onTrackTrg != null then call DisableTrigger(.onTrackTrg) if DESTROY_TRIGGERS then call DestroyTrigger(.onTrackTrg) endif endif //create a new one set .onTrackTrg = CreateTrigger() call TriggerRegisterTrackableHitEvent(.onTrackTrg, .track) //register actions call TriggerAddAction(.onTrackTrg, newFunction) endmethod endstruct //=========================================================================== function GetTrackableData takes trackable whichTrackable returns Trackable return activeTable[whichTrackable] endfunction //=========================================================================== private function PlaceTrackables takes real maxX, real minX, real maxY, real minY, real trackSize, string path, real facing, player owner, code onTrack, code onClick returns nothing local real currentX = minX local real currentY = minY local integer i = 0 loop exitwhen currentY >= maxY loop exitwhen currentX >= maxX call Trackable.advancedCreate(currentX, currentY, 0., path, owner, onTrack, onClick) set currentX = currentX + trackSize endloop set currentX = minX set currentY = currentY + trackSize endloop endfunction //=========================================================================== function CreateTrackedArea takes real topLeftX, real topLeftY, real width, real height, real trackSize, string path, real facing, player owner, code onTrack, code onClick returns nothing local real maxX = topLeftX + width local real maxY = topLeftY local real minX = topLeftX local real minY = topLeftY - height call PlaceTrackables(maxX, minX, maxY, minY, trackSize, path, facing, owner, onTrack, onClick) endfunction //=========================================================================== function CreateTrackedRegion takes rect where, real trackSize, string path, real facing, player owner, code onTrack, code onClick returns nothing local real maxX = GetRectMaxX(where) local real maxY = GetRectMaxY(where) local real minX = GetRectMinX(where) local real minY = GetRectMinY(where) call PlaceTrackables(maxX, minX, maxY, minY, trackSize, path, facing, owner, onTrack, onClick) endfunction //=========================================================================== private function Init takes nothing returns nothing //setting our globals set activeTable = HandleTable.create() //Create our spell's private Table for casters endfunction endlibrary |
| 09-07-2009, 04:59 PM | #2 |
I bet it DC's. |
| 09-07-2009, 05:05 PM | #3 |
Ok, I just read it and here are my 2 cent: It's basicly (or even exactly?) the same as mine. I don't see what you mean with "different approach". Please explain :) The only real difference is, that you let the user choose the facing and the path. You said it's "easier for the user", but i think you got the exectly opposite effect. Let me explain: imo the only use of such a lib is, to create invis tracks across an area, to catch mouseaction there. You don't need a lib to create a single track with the model of a unit or sth. Whats the sense of having a region covered with peasants in a 45° facing every 50 units? In 99+% the user will have to enter 0 and the path of a transparent dummytrackmodel. I tryed to make it userfriendly, by reducing the amount of arguments the functions take to a minimum. So much for the only real difference i saw. However - to finish with sth positive - the coding is nice and clean. It reads like you thought about what you want to do, before you started typing (or cleaned it up carefully before posting). I allways have to add a new variable here or add sth i forget there, etc or even have to completly change it while developing..... PS: I think you got a typo with CreatedTrackArea |
| 09-07-2009, 05:17 PM | #4 | ||||
Quote:
Quote:
Quote:
Using rects is something it's really handy, to be honest I wanted to do the same with your CreateButton lib, but that would be stealing. I may also add groups of trackables, but has I said before, I will give me a lot of work. In a future version I will also allow the user to change the actions and the triggers, thus making trackable re-use easier (or so I hope). However I am not sure is destroying actions from triggers works properly. Quote:
As for the typo, I will fix it soon! |
| 09-07-2009, 05:44 PM | #5 |
Consider that structs are made of global variables, and that assigning different local values to a global variable causes a DC. |
| 09-07-2009, 05:58 PM | #6 |
I still don't know what a DC is ... The code works fine as far as I know, I don't see where the problem could be. |
| 09-07-2009, 06:04 PM | #7 |
DC is short for disconnect. |
| 09-07-2009, 06:24 PM | #8 |
Right .... I seriously don't see how my code can cause a disconnect ... is it because of these lines?: JASS:
private trigger onTrackTrg = CreateTrigger()
private trigger onClickTrg = CreateTrigger()
|
| 09-07-2009, 06:27 PM | #9 |
I believe Here-b-Trollz is referring to this set of lines in struct Trackable create method: JASS:if GetLocalPlayer() == owner then set .tcPath = path endif |
| 09-07-2009, 06:37 PM | #10 |
Man ... that is what makes trackables work in multiplayer ... Kattana used it and he had no problems, I don't see why I would have ... This problem is something I was not expecting ... if this is true, how can I fix it? |
| 09-07-2009, 06:44 PM | #11 |
Assigning different values to globals doesn't cause desyncs (by itself). I'm sure I've tested it before. |
| 09-07-2009, 06:53 PM | #12 |
That doesn't DC |
| 09-07-2009, 07:37 PM | #13 |
Yeee !!!! So guys, any suggestions on how I can get rid of Table? I want to learn how to use hastables, if anyone is kind enough I would appreciate. I am also open to other suggestions. |
| 09-07-2009, 07:50 PM | #14 |
Table is just like interface for hashtable & inlined, so same speed pretty much .. |
| 09-07-2009, 07:54 PM | #15 | |
Quote:
|
