• 🏆 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!

Help with Coordinates, please.

Status
Not open for further replies.
Level 5
Joined
Dec 31, 2013
Messages
121
Hello, I kinda don't have idea how guy in the video made this. So what's the idea. I want to move special unit to any location on the map by command in chat. I can use trigger
"Conversion - Convert String to Real" to set varibales for X and Y coordinates.

b828eb6dbd.png


So for "X" coordinates I use "6,8" Integer and for "Y" I use "10, 12". So I can type only three-digit number for them, but what if I need four-digit or five-digit? Sure I can make "6,10" for "X" and "12,16" for "Y" but if I want to type small coordinates my command will something like "sloc 32 45" It has a lot of spaces and difficult to to find where I should type Y coordinates.
But in the video, there is another system, all numbers after "sloc" command and before comma "," is "X" coordinates and all number after comma "," is "Y". This system more easy to use and it flexible.

Does anyone have idea how to do that? I'm not sure is it made with GUi or Jass. I have simple skills in Gui and totally don't know Jass.



And one more question, is it possible to make command that will show on screen in game the exact location coordinates of the unit?

Sorry, If my english was hard for you, i hope I made it clear.

 
Last edited:
Level 24
Joined
Aug 1, 2013
Messages
4,657
In your case, you most probably want to have a string split function.
A function that takes a string and splits it up with a separator character.
So for example: "/move 123 321"

If we split that on the spaces, we get an array of strings as the following:
[ "/move" , "123" , "321" ]
Now, the first one is simply a check to see what command you used.
The code will then read the other two, convert them to reals and uses them as coordinates to move a pre-specified unit.

The splitter function however, is not so nice to make in GUI... in JASS neither though.
I thought Bannar's String stuff had it but it seems it doesn't.
There was a good one here though, but I cant find it at the moment.

In any case, you are probably going to have it in (v)JASS so you will need custom scripts to split it up.
 
Level 5
Joined
Dec 31, 2013
Messages
121
I am bad in JASS, so probably I will make 2 different commands for X and Y coordinates and 1 more commands to move, it's complicated, but easy to do in my way.
 
Level 5
Joined
Dec 31, 2013
Messages
121
Sorry, I still don't get how to split them. Can you tell me step by step, please? It something to do with custom script? Don't know how to use it too.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
You iterate through the string 1 character at a time (using substring to get 1 character wide strings) and then test if that digit is equal to your separator. If it is, or end of string is encountered, then everything left of that digit back to the previous separator (or beginning of string) is a single argument which can be extracted as a string. You can either process these arguments 1 by 1 as required during parsing the command (could be tricky and maybe have a strange looking API) or you can extract all arguments from the string and put them into an array which you can then process as required (looks neater and makes more sense but might be slower and more leaky as it parses more arguments than a command requires).

Unfortunately WC3 lacks proper string manipulation natives. SC2 has such natives which makes parsing strings with them a dream.

Do note that JASS strings are converted using independent of localization. This means that '.' is always the decimal delimiter.
 
Level 5
Joined
Dec 31, 2013
Messages
121
I don't understand what you telling me. Maybe because my knowledge of world editor is poor and I know only basics or/and it also difficult to translate your message and make your meaning together for me and because of that I really can't see how to make this splitter function.

The easy way I see it, is to make two commands for X and for Y, but now I really want to find how to make this function for one command only. Even not because I need it, but because this is just interesting, but lack of needed knowledge ruins it. Would be really nice if you could tell me what I need in more simple way, with which function I should work and etc.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
For each character of a string you test if it is the character used to separate the various pieces of the string. This is done by using substring to select a string with 1 character length and then testing it against a constant string of your separator character. If the character is the separator character then the string to left between either the start of the string, or the last separator, is one of your arguments (things you do stuff with). You can use a loop from the first character to the last character (for each integer from 1 to entered chat string length) to process the entire string this way. For every argument string you find, you can place it sequentially (0, 1, 2, etc...) into a string array.

After that you are free to refer to each argument as an index in the array and run actions by converting them to strings or logic etc.
 
Here you are:

  • Init
    • Ereignisse
      • Map initialization
    • Bedingungen
    • Aktionen
      • -------- ------Just a unit ------ --------
      • -------- -------------------------------------- --------
      • Set Hero = Erzmagier 0004 <gen>
      • Camera - Lock camera target for Spieler 1 (Rot) to Hero, offset by (0.00, 0.00) using Vorgabe-Drehung
      • -------- -------------------------------------- --------
      • -------- Which command for move --------
      • -------- -------------------------------------- --------
      • Set MoveCommand = -m
      • -------- -------------------------------------- --------
      • -------- Add event for CommandTrigger for needed players --------
      • -------- -------------------------------------- --------
      • Trigger - Add to Command Move <gen> the event (Spieler - Spieler 1 (Rot) types a chat message containing MoveCommand as Ein Teil-String)
      • -------- -------------------------------------- --------
      • -------- Don't touch --------
      • -------- -------------------------------------- --------
      • Set MoveCommandLength = (Length of MoveCommand)
  • Command Move
    • Ereignisse
    • Bedingungen
    • Aktionen
      • Set ChatString = (Entered chat string)
      • Set StringLength = (Length of ChatString)
      • Set TempX = 0.00
      • Set TempY = 0.00
      • For each (Integer TempInt) from (MoveCommandLength + 1) to StringLength, do (Actions)
        • Schleifen - Aktionen
          • -------- -------------------------------------- --------
          • -------- Find the first space --------
          • -------- -------------------------------------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Substring(ChatString, TempInt, TempInt)) Gleich
            • Then - Actions
              • -------- -------------------------------------- --------
              • -------- From our space, we go to the next space again and convert the substring in between to X ..... --------
              • -------- .....we take all the rest after the 2nd space and convert it to Y. --------
              • -------- -------------------------------------- --------
              • For each (Integer TempInt2) from (TempInt + 1) to StringLength, do (Actions)
                • Schleifen - Aktionen
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Substring(ChatString, TempInt2, TempInt2)) Gleich
                    • Then - Actions
                      • Set TempX = (Real((Substring(ChatString, (TempInt + 1), (TempInt2 - 1)))))
                      • Set TempY = (Real((Substring(ChatString, (TempInt2 + 1), StringLength))))
                    • Else - Actions
            • Else - Actions
      • Game - Display to (All players) the text: (X value: + (String(TempX)))
      • Game - Display to (All players) the text: (Y value: + (String(TempY)))
      • Custom script: call SetUnitX(udg_Hero, udg_TempX)
      • Custom script: call SetUnitY(udg_Hero, udg_TempY)
 

Attachments

  • test.w3x
    18.1 KB · Views: 58
Level 5
Joined
Dec 31, 2013
Messages
121
Thank you! I could never done this by myself, so much variables. And it even not uses event function, which really strange for me. Now I just need to think how to adapt this system for 12 players and for 12 units.
 
As the command string "-m" is modifyable in the init trigger, I thought it was better to add events at config, so after the command word was defined.
If you have a look at init there is an action which adds an event for Player1 to the command trigger. You may add events for other players there, too, also with a loop if needed.

You can use a unit[] array variable to store units for each player. The index inside the [] must be the PlayerNumber of each player.
So if you make actions with Hero[1] it is the hero for player 1, and so on. Inside the "Command Move" trigger where the event is "Player X types ... as string", you can use
PlayerNumber of TriggeringPlayer to refer to correct hero, so Hero[PlayerNumberOfTriggerIngPlayer].
 
Level 5
Joined
Dec 31, 2013
Messages
121
Yes, thank you, Dunno why you used custom script and how to me make index in Hero[PlayerNumberOfTriggerIngPlayer] in custom script, but I did it other way, seems to be working fine.

0689f4de82.png
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
But how I did is okay too, right?
Your way leaks and has a different logical meaning.
All GUI global variables need to be prefixed with "udg_" when referenced in custom script. Try...
JASS:
call SetUnitX(udg_Hero[GetPlayerId(GetTriggerPlayer())], udg_TempX)
call SetUnitY(udg_Hero[GetPlayerId(GetTriggerPlayer())], udg_TempY)
 
Level 5
Joined
Dec 31, 2013
Messages
121
Your way leaks and has a different logical meaning.
All GUI global variables need to be prefixed with "udg_" when referenced in custom script. Try...
JASS:
call SetUnitX(udg_Hero[GetPlayerId(GetTriggerPlayer())], udg_TempX)
call SetUnitY(udg_Hero[GetPlayerId(GetTriggerPlayer())], udg_TempY)

Something wrong, I did 2 heroes, Hero[1] for Red Player and Hero[2] for Blue Player. When I do command as red player, red hero not moves, but I get message of X and Y value. When I play as Blue player and type command it moves Red's hero. But in GUI function it was all right.

UPD: ah i got it, it seems that with custom script Hero[0] is Red Player and Hero[1] is Blue one.

Well, thak you guys for your help.
 
Last edited:
Location could be used as well, so like move to "Location (X,Y)" -- but then you require a location/point variable for it.
Because you would need to prevent the location leak with a "call RemoveLocation()" function.

it could look like:

  • Set Location = Point(TempX/TempY)
  • Unit - Move Unit to Location
  • Custom script: call RemoveLocation(udg_Location)
 
Status
Not open for further replies.
Top