| 12-16-2006, 05:56 AM | #1 |
I'm finished making the algorithm, but I'm having problems turning the out-put into a unit moving. The algorithm takes 2 nodes and finds the best path between the 2, through a series of other nodes. An example would be: Input: Node 01 to 08 Output: 0102050608 this means the unit needs to go to node 01, 02, 05, 06, 08 (in that order) to reach 08 the fastest. The nodes are both locations, and units. I was thinking of doing "A unit comes within range" or "A unit enters region" but I can't think of a dynamic way of doing this. All the help is appreciated! |
| 12-16-2006, 11:18 AM | #2 |
I think that moving to JASS is the best think you can do, I can't believe you made a pathing algorithm in GUI, I imagine some awful code that looks like an squid kissing the flying spaghetti monster. But that's it if you make the nodes regions (JASS regions, not GUI's) you can actually do this, if you want to use the unit in range event you would have to attach information to a trigger and actually you'll need to create a lot of triggers, which is not the most practical way to do it. The range event is awesome when you want the enter area to move but in this case that seems unlikely. |
| 12-16-2006, 01:32 PM | #3 |
Turn the nodes into rectangles and assign them into an array. Now make a Trigger with all nodes in a "Unit enters Region" Event. Then check which node the unit is in, where it has to go next, and make it go there. Each unit needs an unique ID in order to identify this. So for example make a trigger "unit enters playable map area: set custom value of entering unit = custom value of last unit + 1" or something. Also you would need a String Array in which you save the order of the nodes (in your case 0102050608). Now when the trigger fires it first checks which region triggered it (For each Integer A, if Unit is in Region[Integer A] then...) then compare that region to the string (for each integer b, if Integer a equal to substring(StringArray[custom value of unit], 2xInteger B - 1, 2x Integer B), then...) and order the unit to go to the next region. (order unit to go to substring(StringArray[custom value of unit], 2xInteger B - 1+2, 2xInteger B + 2) I don't have the world editor here right now, but I can write it better later if you want to. |
| 12-16-2006, 03:10 PM | #4 | ||
Quote:
I know both JASS and GUI, but because of very strange loop and return problems iv had in the past, I decided to stick with GUI for this project. The algorithm is pretty streamline. Testing it with 41 nodes and there is no noticeable lag when it runs. Although that is the case, my final version will be JASS (allows for ease of use for other players to copy). Quote:
The regions are already in an array. Your idea was my first idea, but there's a slight problem. The event "A unit enters region" fires before the unit is actually in the region, so a "point is in region" boolean check will always return false. A simple way is to make another region slightly larger than the other, and check in that one. Only problem is that it's harder to set-up the system, and I have to worry about over-lapping nodes. I was planning to save the strings in a game-cache using the H2I method. It's just more of detecting when the unit gets to the required node. Vexorian, the Regions are GUI, because it's easy for a player to set them up. I'm a curious though, what method would you use with JASS locations? |
| 12-16-2006, 03:20 PM | #5 | |
Quote:
In that case just make an Integer Array that counts, how often the trigger has fired for the unit with that ID. That should allow you to always know the next node. |
| 12-16-2006, 03:26 PM | #6 | |
Quote:
Sorry, you lost me there... An integer array that counts how many times the unit enters the region? How would I use this? |
| 12-16-2006, 03:29 PM | #7 |
Count the amount of "regions" that are in the string, so that something such as 020403 would have 3 regions. Now you know there are 3 regions, and with an integer you can count how many regions he's "been to". No idea what the array is for unless you're not using locals. |
| 12-16-2006, 07:12 PM | #8 |
Quick question. Does using "call ForGroup" allow locals to be referenced in the loop from the calling function? Thanks! (Yes, I am converting to JASS) |
| 12-16-2006, 07:18 PM | #9 |
Is it just me, or is this the same thing as the system Dalten posted here on node movement? His system is in GUI, which is what you're looking for, and it works perfectly for multiple units at a time. Maybe you should look into his system and see if it can help you? |
| 12-16-2006, 07:28 PM | #10 |
I know of Dalten's system and that is the main reason why I am making this one. The one downside to his system is that it lacks the ability to create intersecting nodes. This system will give credit to Dalten since I am using a few of his methods for management, but changing the overall procedure. |
| 12-16-2006, 07:46 PM | #11 |
Ammorth, all the movement functions i used are in the heartbeat trigger. It's a fairly simple but effective approach if you ask me, every 0.10 seconds or whatever you want it to be, it polls every unit's distance from where they are, to where they're going. If they're 'close enough' to the next node they're going to, then the trigger sends them on to the next node in the chain. Good luck. |
| 12-16-2006, 07:57 PM | #12 |
Okay, worldeditor is giving me errors from trying to reference a local in a function that called the ForUnitGroup I'm referencing from. Is there any way I can transfer the values without using globals? If not, I'll have to use globals (which sort-of defeats the purpose of the JASS version). |
| 12-16-2006, 08:12 PM | #13 |
The return bug i what you want for that. Check for anything related to "Local Handle Vars" |
| 12-17-2006, 01:15 PM | #14 |
Instead of using return bug + gamecache, just install Vexorian's JASSHelper. Yes, your system will require it, but it will be a lot faster. JASSHelper allows you to make the system in one single trigger, and assign private globals for it. It looks like this (check the caster system for reference; I'm not sure if I've got a 100% correct syntax ): (inside a trigger) JASS://! library NodeMovementThingy globals private integer anInteger endglobals function GroupFunc takes nothing returns nothing if(GetUnitCustomValue(GetEnumUnit())==anInteger) then call DoSomethingWithUnit(GetEnumUnit()) endif endfunction function Hello_World takes group g, integer i returns nothing set anInteger=i call ForGroup(g,function GroupFunc) endfunction //! endlibrary Alternatively, you can use another local group for the looping. This is a considered as slower, but it doesn't require JASSHelper. JASS:function Hello_World takes group g, integer i returns nothing local group g2=CreateGroup() local unit u // Make g2 a copy of g call GroupAddGroup(g,g2) loop set u=FirstOfGroup(g2) exitwhen u==null call DoSomethingWithUnit(u) call GroupRemoveUnit(g2,u) endloop call DestroyGroup(g2) set g2=null set u=null endfunction |
| 12-17-2006, 02:55 PM | #15 |
Thanks for the info! I don't really want to make a system that relies on another (no offense to vexorian, but I find it hard to have to install 3-4 systems just to get one thing to work). I did look into the second method before you posted, and couldn't implement it entirely to my liking. I did solve my problem though. I used an integer array that stores a "unit group" (either 0, 1, or 2) and then loop through the array, only doing actions to each node that has the required "integer group". |
