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

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

Status
Not open for further replies.
Level 2
Joined
Jul 6, 2011
Messages
4
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 :eek: (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 RegionAddRect(ENTERREGION[1], RECT[3])
    call RegionAddRect(ENTERREGION[2], RECT[4])
    call RegionAddRect(ENTERREGION[3], RECT[5])
    call RegionAddRect(ENTERREGION[4], RECT[6])
    call RegionAddRect(ENTERREGION[5], RECT[7])
    call RegionAddRect(ENTERREGION[6], RECT[8])
    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)
    call TriggerAddCondition(MOVE, function MOVE_CONDITION)
    call TriggerAddAction(MOVE, function MOVE_ACTION)
    endfunction
    
endlibrary
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
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?
 
Level 2
Joined
Jul 6, 2011
Messages
4
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~
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
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.
 
Level 2
Joined
Jul 6, 2011
Messages
4
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("MetalWeapon___ITEM_UPGRADES_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) )
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
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 :p

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.
 
Level 2
Joined
Jul 6, 2011
Messages
4
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.

Thanks for your tips!

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 ;)
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
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.
 
Status
Not open for further replies.
Top