# [JASS]Unit move Order per Trigger, not moving sometimes?

#### RundasX

Level 2
Well, hello there,

this question might be asked a thousand times already, but either im too stupid to search correctly or im using the wrong keywords...nvm, here´s my problem:

After a unit gets trained, he shall automove from point A-B with a few checkpoints (I have three lines in total, up, middle and down)

When I first Order the unit to "attack" move to the next Point, all units are moving as they should.
JASS:
``call IssuePointOrder(wichUnit, "attack", GetRandomX(RECT[6]), GetRandomY(RECT[6]))``

Ignore GetRandomX and Y, it just gives a random real out of RectMaxX/Y and MinX/Y to get a random point inside the given rect~

Now, when they step into one of the 2 Checkpoints of any line (Each line has 2 Checkpoints), they should recieve the order to "attack" move to the next checkpoint. Quite simple, but something is broken here:

Some units wont move. If I manually select them and give them a move order, they start moving towards the given Checkpoint once again, but only then.

I am using the following stuff to make the continuos movement:

(Variables are globals) First, Creating a few regions...
JASS:
``````set ENTERREGION[1] = CreateRegion()
...``````

After that, Add the Rect (Saved in a global too)...

JASS:
``````call RegionAddRect(ENTERREGION[1], RECT[3])
...``````

And finally adding the Event with the previously created Regons...

JASS:
``````call TriggerRegisterEnterRegion(MOVE, ENTERREGION[1], null)
...``````

Is this way too slow for wc3 to handle more than like 30-40 units at once? Im saving every unit in a local variable (wich gets nulled afterwards ofcourse) so it should not overlap at all (That´s what im thinking at least)

I thought about doing something with unit groups and make the order apply to the specific unit group (Depends on how far the unit has actually moved, unit_group0 for moving to checkpoint 1, unit_group1 for moving to checkpoint 2 etc..), maybe that would work?

Has anyone of you had this kind of problem before too? A good solution is appreciatet aswell, im willing to just delete the trigger and redo it completly~

Cheers

PS: If youre interested, here is the complete trigger (It´s just made to work, not to be fancy~):
JASS:
``````library MoveOn initializer MOVE_INIT requires Settings

globals
private trigger MOVE = CreateTrigger()
private region array ENTERREGION
endglobals

/*
*RECT[1] = WEST_SPAWN
*RECT[2] = EAST_SPAWN
*RECT[3] = WEST_UP
*RECT[4] = EAST_UP
*RECT[5] = WEST_DOWN
*RECT[6] = EAST_DOWN
*RECT[7] = WEST_MIDDLE
*RECT[8] = EAST_MIDDLE
*RECT[9] = WEST_MAIN
*RECT[10] = EAST_MAIN
*RECT[11] = HERO_WEST
*RECT[12] = HERO_EAST
*/

private function MOVE_CONDITION takes nothing returns boolean
return(not IsUnitType(GetEnteringUnit(), UNIT_TYPE_HERO))
endfunction

private function MOVE_ACTION takes nothing returns nothing
local real x
local real y
local unit u = GetEnteringUnit()
local integer i = GetPlayerId(GetOwningPlayer(u))
if IsPlayerInForce(Player(i), forceWest) then
if IsUnitInRegion(ENTERREGION[1], u) then
set x = GetRandomX(RECT[4])
set y = GetRandomY(RECT[4])
elseif IsUnitInRegion(ENTERREGION[2], u) then
set x = GetRandomX(RECT[10])
set y = GetRandomY(RECT[10])
elseif IsUnitInRegion(ENTERREGION[3], u) then
set x = GetRandomX(RECT[6])
set y = GetRandomY(RECT[6])
elseif IsUnitInRegion(ENTERREGION[4], u) then
set x = GetRandomX(RECT[10])
set y = GetRandomY(RECT[10])
elseif IsUnitInRegion(ENTERREGION[5], u) then
set x = GetRandomX(RECT[8])
set y = GetRandomY(RECT[8])
elseif IsUnitInRegion(ENTERREGION[6], u) then
set x = GetRandomX(RECT[10])
set y = GetRandomY(RECT[10])
endif
else
if IsUnitInRegion(ENTERREGION[1], u) then
set x = GetRandomX(RECT[3])
set y = GetRandomY(RECT[3])
elseif IsUnitInRegion(ENTERREGION[2], u) then
set x = GetRandomX(RECT[9])
set y = GetRandomY(RECT[9])
elseif IsUnitInRegion(ENTERREGION[3], u) then
set x = GetRandomX(RECT[5])
set y = GetRandomY(RECT[5])
elseif IsUnitInRegion(ENTERREGION[4], u) then
set x = GetRandomX(RECT[9])
set y = GetRandomY(RECT[9])
elseif IsUnitInRegion(ENTERREGION[5], u) then
set x = GetRandomX(RECT[7])
set y = GetRandomY(RECT[7])
elseif IsUnitInRegion(ENTERREGION[6], u) then
set x = GetRandomX(RECT[9])
set y = GetRandomY(RECT[9])
endif
endif
call IssuePointOrder(u, "attack", x, y)
set u = null
endfunction

private function MOVE_INIT takes nothing returns nothing
set ENTERREGION[1] = CreateRegion()
set ENTERREGION[2] = CreateRegion()
set ENTERREGION[3] = CreateRegion()
set ENTERREGION[4] = CreateRegion()
set ENTERREGION[5] = CreateRegion()
set ENTERREGION[6] = CreateRegion()
call TriggerRegisterEnterRegion(MOVE, ENTERREGION[1], null)
call TriggerRegisterEnterRegion(MOVE, ENTERREGION[2], null)
call TriggerRegisterEnterRegion(MOVE, ENTERREGION[3], null)
call TriggerRegisterEnterRegion(MOVE, ENTERREGION[4], null)
call TriggerRegisterEnterRegion(MOVE, ENTERREGION[5], null)
call TriggerRegisterEnterRegion(MOVE, ENTERREGION[6], null)
endfunction

endlibrary``````

#### edo494

Level 23
wc3 has general problem of moving many units on the same space, try placing 200 units to the edges of the map at 64x64 and then order every single unit to move to the center, they will not move that clearly and nicely

also your trigger's condition and action could've been merged into one function

edit: after re-reading the post, this is not really the issue

are you sure that the RECTs are initialized before the initializer of this scope runs?

#### WaterKnight

Level 25
Check GetTriggeringRegion not via IsUnitInRegion.

#### Troll-Brain

Level 17
There is a known bug, an unit can be outside a region when the enter region event fire (X or Y), so yes use GetTriggeringRegion, or just X triggers for X regions.

Last edited:

#### RundasX

Level 2
Will try your suggestions tomorrow. Will post the results (Edit this if noone replys in the meanwhile ofc~) afterwards.

@edo

Yea, ill merge them when it works. Im just doing it the simple way currently and thats (for me at least) one by one, everything visible, nothing fancy as i said.

The rects are not trigger-made, they are preplaced and (should?) be created right when the map starts and before the init of the trigger runs (please confirm? Never actually thought about that)

@Troll

I once had that bug, a long time ago, but it was rarely happening so i didnt really cared about it. I hope your suggestions with GetTriggeringRegion will work, as I don´t really want to create 6 stupid triggers for one (actual) function~

Thanks guys and Cheers~

#### Troll-Brain

Level 17
Hmm mix GUI stuff and vJass init is not a good idea, because if i remember correctly, vjass inits are done before GUI init stuff.
So look and eventually share us your map script.

That still doesn't change the bug about regions and events though.

#### edo494

Level 23
thats quite new to me lol, but good to know that

yes, preplaced rects are initialized/created before anything else runs afaik, but they usually have quite a bit different names

#### RundasX

Level 2
So, I´ve changed "IsUnitInRegion(...)" to...

local region r = GetTriggeringRegion()
...
if r == ENTERRECT[X] then...

And i´ve also made the Rects quite a bit bigger and now using the CenterX coords instead of RandomX()...

On a few Tests of 50+ Units, it worked way better than before. But it doesn´t seem perfect neither. There are still a few Units just staying at a Checkpoint, mostly only 1-2 Units, but isn´t there a simple way to make a movement flawless? In TD´s it works...

If you guys have no idea, I might try my mention idea at the top of my first post (Unit Groups and timed orders), but only if there isn´t really another simple way instead of storing every trash unit into a variable...

@Troll-Brain
I think the Original Map Inits are not under the vjass Inits:
(mpqmaster ftw!)
JASS:
``````function main takes nothing returns nothing
call SetCameraBounds(- 10240.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), - 10240.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM), 10240.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), 10240.0 - GetCameraMargin(CAMERA_MARGIN_TOP), - 10240.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), 10240.0 - GetCameraMargin(CAMERA_MARGIN_TOP), 10240.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), - 10240.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM))
call SetDayNightModels("Environment\\DNC\\DNCDalaran\\DNCDalaranTerrain\\DNCDalaranTerrain.mdl", "Environment\\DNC\\DNCDalaran\\DNCDalaranUnit\\DNCDalaranUnit.mdl")
call NewSoundEnvironment("Default")
call SetAmbientDaySound("DalaranDay")
call SetAmbientNightSound("DalaranNight")
call SetMapMusic("Music", true, 0)
call InitSounds()
call CreateRegions()
call CreateAllItems()
call CreateAllUnits()
call InitBlizzard()

call ExecuteFunc("BonusMod___Initialize")
call ExecuteFunc("ChangeOrder___CHANGE_ORDER_INIT")
call ExecuteFunc("GoldIncome___GOLD_INCOME_INIT")
call ExecuteFunc("RangersDuty___i")
call ExecuteFunc("SetUnitMaxState___Initialize")
call ExecuteFunc("Settings___onInit")
call ExecuteFunc("TechResearch___TECH_INIT")
call ExecuteFunc("Attributes___onInit")
call ExecuteFunc("MoveOn___MOVE_INIT")
call ExecuteFunc("UnitTrainer___UNIT_TRAINER_INIT")

call InitGlobals()
call InitTrig_Quests() // INLINED!!
call RunInitializationTriggers()

endfunction``````

"call CreateRegions()" runs before any other vJass Init will be executed, at least it looks like it though
(Yes, the map is still WIP, there is still many things todo, thats why there are so less actuall inits for now x) )

#### Troll-Brain

Level 17
So there is this part which is done after vJass inits :

call InitGlobals()
call InitTrig_Quests() // INLINED!!
call RunInitializationTriggers

I suppose InitGlobals if for "defaults values", RunInitializationTriggers for GUI triggers with the "event" map initialization and InitTrig_Quests for ... quests

Are you using computer players or neutral players ?
Because computer players seems to be more "obedient", the neutral player are more "rebels", maybe it could be fixed with the ai but you would just consider to lose a player slot and use a computer player instead.

#### RundasX

Level 2
The variables I use are all done inside the vJass stuff. Nothing is done in GUI or anywhere. Just so that this thing is clear, its just the "general" bug

The map is supposed to be 6v6 max, I could actually try to let a computer player move the units, but I wanted to add the option to manually control your "mass" of units and a computer player would create some additional lines.

I´ll try the option with Unit_Groups now (So no Regionchecking whatsoever) and give them timed Orders. I think that option should 100% work if I do it correctly.

If THIS doesn´t work either (wich I highly doubt), I will try a computer player.

Cheers

EDIT: Just checked about the last lines after the vJass inits. They don´t do anything because there is nothing for them to do actually

#### WaterKnight

Level 25
A typical problem of moving spawns is that the units block each other or a unit may lose its order if it cannot reach the destination point any longer because of surrounds for example. Also when spawning, the new unit will snap to a free space and may therefore appear outside of the region it was supposed to spawn in. Then it was already mentioned that units do not necessarily walk straight. Or neutrals may return due to guarding behavior.

Replies
4
Views
736
Replies
11
Views
819
Replies
7
Views
6K
Replies
8
Views
520
Replies
1
Views
451