| 11-16-2007, 04:33 AM | #1 |
I would like to design a trigger that will cause a unit to strafe when the left or right arrow keys are placed. I understand it is possible to order a unit to move leftward or rightward, however this will cause the unit to face 0 or 180 degrees, which is not what i desire. Basically i would like to design a system that -Allows units to move left and right while maintaining the direction it is facing. For example, if a unit is facing 90 degrees, i want it to always be facing 90 degrees during strafing movement. I have thought of a possible way to do this but im not sure how or weather it is possible. -Basically i am just required to move the unit (instead of order it to move) sideways. -The alternative would be to have a dummy unit that forces the unit sideways upon contact, but i have no idea how to do this.. If anyone has played dota before im thinking of spiritbreakers greater bash. Thanks in advance Regards, FuzzyetDeadly. |
| 11-16-2007, 04:38 AM | #2 |
play the units walk animation and move it instantly left or right. It would be the best solution. (and 5 minutes to code it using JASS...) |
| 11-16-2007, 07:17 AM | #3 | |
Quote:
Im still quite new to JASS, but im interested in learning it. Do you think you could give me an idea of what natives i require to perform the JASS coding for this? |
| 11-16-2007, 01:01 PM | #4 |
JASS:native SetUnitAnimation takes unit whichUnit,string whichAnimation returns nothing // Or, even better but more complex: native SetUnitAnimationByIndex takes unit whichUnit,integer whichAnimation returns nothing native SetUnitX takes unit whichUnit,real newX returns nothing native SetUnitY takes unit whichUnit,real newY returns nothing native CreateTimer takes nothing returns timer native TimerStart takes timer whichTimer,real timeout,boolean periodic,code handlerFunc returns nothing i would use a global array of units and loop throgh it each iteration of a timer, moving them based on a value attatched to the units. If you need an easy method of attatchment, i use Grim's data system (requires vJASS): http://wc3campaigns.net/pastebint.ph...3ffd04408ae7e1 also, a decent timeout for the timer would be around 1/40, so it would loop 40 times a second giving decently smooth movement. SetUnitX and Y can move units outside of the map, causing a crash. make sure a unit does not exit the playable map area. these two functiosn also ignore pathing, so you will need a method of detecting the patability of terrain. (moving a global item and detecting if the position it was actually moved to was the desired position, down to a specific error range, is one of the fastest ways) |
| 11-16-2007, 02:45 PM | #5 |
Ill keep a note of those natives you mentioned.. tho i think itll be awhile before i actually learn how to use them properly. Ive done some trial and error with the GUI then tried to make my own version of it with JASS. I tried running the Movement system with the GUI trigger and it was really smooth. I tried testing again with the JASS script i programmed and the movement was kinda choppy.. ill paste a copy of the code here and the map too, if its not too troublesome maybe you could take a look and tell me what ive done wrong. Im taking a guess its got something to do with the multitude of function calls the GUI uses.. But im not so sure. Im pretty sure my script isnt optimized as this is my official first attempt at JASS. Heres my script JASS://Function call to move location of unit. function moveloc takes unit u1,real x,real y returns nothing call SetUnitPositionLoc( u1, OffsetLocation(GetUnitLoc(u1), x, y) ) endfunction //udg_mU00, udg_mD00, udg_mR00 and udg_mL00 are boolean variables used to determine keystrokes. function Trig_move_Actions takes nothing returns nothing call SetUnitAnimation( gg_unit_hgyr_0000, "walk" ) if ( udg_mU00 == true ) then // call SetUnitPositionLoc( gg_unit_hgyr_0000, OffsetLocation(GetUnitLoc(gg_unit_hgyr_0000), 0.00, 15.00) ) if ( udg_mL00 == true and udg_mR00 == false) then call moveloc( gg_unit_hgyr_0000, -15.00, 15.00 ) elseif ( udg_mL00 == false and udg_mR00 == true) then call moveloc( gg_unit_hgyr_0000, 15.00, 15.00 ) else call moveloc( gg_unit_hgyr_0000, 0.00, 15.00 ) endif elseif ( udg_mD00 == true) then if ( udg_mL00 == true and udg_mR00 == false) then call moveloc( gg_unit_hgyr_0000, -15.00, -15.00 ) elseif ( udg_mL00 == false and udg_mR00 == true) then call moveloc( gg_unit_hgyr_0000, 15.00, -15.00 ) else call moveloc( gg_unit_hgyr_0000, 0.00, -15.00 ) endif else if ( udg_mL00 == true) then call moveloc( gg_unit_hgyr_0000, -15.00, 0.00 ) elseif ( udg_mR00 == true) then call moveloc( gg_unit_hgyr_0000, 15.00, 0.00 ) else endif endif endfunction //=========================================================================== function InitTrig_move takes nothing returns nothing set gg_trg_move = CreateTrigger( ) call TriggerRegisterTimerEventPeriodic( gg_trg_move, 0.05 ) call TriggerAddAction( gg_trg_move, function Trig_move_Actions ) endfunction Thanks in advance for you help =) |
| 11-16-2007, 03:15 PM | #6 | |
Quote:
|
| 11-16-2007, 04:40 PM | #7 |
#1: Download JASS NewGen (in the tools section of this site) #2: Stop using the variable editor. Its a pile of shit. NewGen allows you to define globals in the code, ala: JASS:globals integer MyGlobalVariableName = 23 endglobals JASS:globals [scope] [constant] type [array] name [= default value] endglobals constant being the optional word constant (makes a variable read-only, thus its default value is its only value) type being the variables type, like real integer boolean ext. array would be included to make it an array name is self-evident [= default value] is not applicable for arrays. Also, your variable names all suck. And you use locations, which are evil. use raw X and Y cords. (NewGen includes TESH, which has a function finder) you should only use locations when absolutely nessisary. (the only time i've found myself requiring locations is with GetLocationZ()) two more natives: JASS:constant native GetUnitX takes unit whichUnit returns real constant native GetUnitY takes unit whichUnit returns real also, you code brackets in if statements as: if ( condition ) then wheras you could do: if condition then (note: just a style thing... i like it without the un-needed brackets) the logic of your movement could be improved to somethins as: JASS:local real newx = GetUnitX(u) local real newy = GetUnitY(u) if UpPressed then set newy = newy + 15 endif if DownPressed then set newx = newx + 15 endif Also, using trigenometry to base the direction of movement on a units facing would be nice. As for making this multi-instanciable, you would need to have an array of units, each at a playerid's index. (the owning player) then, you loop throgh player indexes (say, 0 to 11 for all 12 players) and check what keys are pressed, modifying a units position as such. JASS:constant native GetPlayerId takes player whichPlayer returns integer |
| 11-16-2007, 05:00 PM | #8 |
Wow.. thanks alot for the explanation. Looks like i got alot of code revamping to do then. Heh. Ill get back to you again as soon as ive given it a shot. The newgen thing, i already had it :P i just arent familiar with how to take advantage of it just yet, hence the lousy coding (which was actually converted from GUI and modified.) Anyways To note: Rep added ![]() Edit: JASS feels so hard when you started off with GUI =/ |
| 11-16-2007, 06:41 PM | #9 |
In response to a PM, posted here to allow others to learn from this conversation: #1: use a scope. JASS:scope MovementSystem globals private constant real UpdatesPerSecond = 40 endglobals private function DoMove takes nothing returns nothing // The TimerStart() in the InitTrig function starts a looping timer with a timeout of 1/UpdatesPerSecond, which calls this function every time the timer expires. endfunction public function InitTrig takes nothing returns nothing // In a scope, a public function named InitTrig gets post-fixed with the scope name. // Thus, name the trigger the same thing you name the scope, and it will become InitTrig_MovementSystem. // InitTrig functions are automagically called by warcraft 3 before pretty much any other function. when usng Jass NewGen, you do not have to include an InitTrig function in a trigger. But in vanilla, normal WE, you do have to include one. call TimerStart(CreateTimer(), 1/UpdatesPerSecond, true, function DoMove) endfunction endscope #2: the warcraft 3 map script is a single script, which all the GUI "Triggers" from the world editor get compiled in to. in the map script, there is a single block for declaring globals, and it is located at the top of the script. JASS NewGen simply takes all globals blocks it finds in a script, and merges them in to that single globals block. you can have a limitless number of globals blocks anywhere in your script. I can't see any issue with the code you PMed me, but i'm going to presume those udg_ prefixed variables are not defined. Convert your key-press triggers to JASS, and define the key press variables with decent names, like IsUpPressed. then simply, in the action function do: JASS:set IsUpPressed = not IsUpPressed |
| 11-17-2007, 04:18 PM | #10 |
Ok.. it took me awhile but ive revamped the movement system into JASS code. (Hopefully it looks alot cleaner and more readable now) Im having trouble declaring globals though, ill show you what i tried.. it gives me compile errors. Its got something to do with the scoping i think. *Note: The scope name is the same as the trigger name. I tried to have my global variables declared.. JASS:scope movesystem globals private constant real UpdatesPerSecond = 40 private unit array u //Temporary names for the boolean variables, //assuming i do not use the vannilla WE variable creator thing. //I labelled them public because i need them to be used for //the key detection triggers public boolean hdg_mR00 = false public boolean hdg_mL00 = false public boolean hdg_mU00 = false public boolean hdg_mD00 = false endglobals This is the main section that creates movement: JASS:private function DoMove takes nothing returns nothing //note, original code was just "function DoMove takes nothing returns nothing" set u[0] = gg_unit_hgyr_0000 //Originally "local unit u = gg_unit_hgyr_0000" local real a = 30.00 local real newx = GetUnitX(u[0]) local real newy = GetUnitY(u[0]) if udg_mL00 then set newx = newx - a endif if udg_mR00 then set newx = newx + a endif if udg_mU00 then set newy = newy + a endif if udg_mD00 then set newy = newy - a endif call SetUnitX(u[0],newx) call SetUnitY(u[0],newy) endfunction I added this: JASS:public function InitTrig takes nothing returns nothing call TimerStart(CreateTimer(), 1/UpdatesPerSecond, true, function DoMove) endfunction endscope I omitted this section of my code: JASS://=========================================================================== function InitTrig_movesystem takes nothing returns nothing set gg_trg_movesystem = CreateTrigger( ) call TriggerRegisterTimerEventPeriodic( gg_trg_movesystem, 0.05 ) call TriggerAddAction( gg_trg_movesystem, function DoMove ) endfunction Without the added stuff, the original code works fine, but now i need to use global arrays to make this multi-instancible. Also, i would like to get rid of the ugly boolean variable names generated by WE. Wonder what silly mistake i made this time.. ![]() Edit: The compile error i recieved was "Expected end of line" I tested it out, it appears when i attempt to use globals and endglobals could it have something to do with the vJASS thing?.. im using the newgen4b at the moment so im assuming it comes with vJASS. Also.. i cant quite understand the Grim01 data system thing.. might have something to do with that as well. |
| 11-17-2007, 06:32 PM | #11 |
JASS:private function DoMove takes nothing returns nothing //note, original code was just "function DoMove takes nothing returns nothing" set u[0] = gg_unit_hgyr_0000 //Originally "local unit u = gg_unit_hgyr_0000" local real a = 30.00 local real newx = GetUnitX(u[0]) local real newy = GetUnitY(u[0]) convert your keypress detecting triggers to JASS, and include them in the movesystem scope. Declare key-press variables as arrays, just like your unit array (which has a horrible name) then, you loop from 0 to 11 in the DoMove function and check each key press boolean for each player, moving the unit at the players index in the array based on user input. Your global declarations appear to be fine, and they compile fine with the fix i mentioned: JASS:scope movesystem globals private constant real UpdatesPerSecond = 40 private unit array u //Temporary names for the boolean variables, //assuming i do not use the vannilla WE variable creator thing. //I labelled them public because i need them to be used for //the key detection triggers public boolean hdg_mR00 = false public boolean hdg_mL00 = false public boolean hdg_mU00 = false public boolean hdg_mD00 = false endglobals private function DoMove takes nothing returns nothing //note, original code was just "function DoMove takes nothing returns nothing" local real a = 30.00 local real newx = GetUnitX(u[0]) local real newy = GetUnitY(u[0]) set u[0] = null//gg_unit_hgyr_0000 //Originally "local unit u = gg_unit_hgyr_0000" if hdg_mL00 then set newx = newx - a endif if hdg_mR00 then set newx = newx + a endif if hdg_mU00 then set newy = newy + a endif if hdg_mD00 then set newy = newy - a endif call SetUnitX(u[0],newx) call SetUnitY(u[0],newy) endfunction public function InitTrig takes nothing returns nothing call TimerStart(CreateTimer(), 1/UpdatesPerSecond, true, function DoMove) endfunction endscope anyway, as for adding the keypress triggers to the scope, you will end up with 4 functions, one handling up, one handling down, ect, ect. Then, you will need to inline all the InitTrig functions in to the one in the scope. Use a local trigger, ala: JASS:public function InitTrig takes nothing returns nothing local trigger t set t = CreateTrigger() call TriggerRegisterWhateverEvent(t, blah blah blah) call TriggerAddAction(t, function SetUpKeyState) set t = CreateTrigger() call TriggerRegisterWhateverEvent(t, blah blah blah) call TriggerAddAction(t, function SetDownKeyState) // ext ext endfunction As for why your code doesn't compile, i have no idea, as other than that one error, it compiles fine for me... Odd. |
| 11-17-2007, 07:23 PM | #12 |
are you using the syntax checker of TESH? If you do, try saving the map. The problem is, that TESH only uses PJASS to check and does not preprocess the script. Scopes are things that need to be preprocessed, because this is not a normal feature of JASS. |
| 11-17-2007, 11:28 PM | #13 |
Ignore this >> |
| 11-18-2007, 04:00 AM | #14 |
...? That has nothing to do with what he wants. |
| 11-18-2007, 04:18 AM | #15 |
I presume im using TESH, as it is stated that it is included in the NewGen 1.4b Package. I think its as you say, my scope is not preprocessing, merely getting checked by PJASS. Scopes and globals are the main things that cause the errors, when i omit them the trigger works alright. But i would really like to implement scopes and globals to get a better insight on how they work. My question is, how exactly do i have my script pre-processed? |
