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

Is there a way to read out the loaded units in a unit?

Status
Not open for further replies.
Level 2
Joined
Sep 1, 2014
Messages
14
Hey,
I want to pick all units out of another unit and save them in a unit group.
Is that possible?
Thank you
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,199
Unfortunately there is not. You will need some complex and bug prone system to keep track of units loaded in and out of transports. Be aware that unload can be issued to the same unit in cargo multiple times but it will only unload that 1 unit.

In SC2 they added natives to do this making cargo management a breeze.
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
What I did was the following:
There is an event for units that are loaded into transport. I use that to catch each unit that is loaded. I save those units into unit group.
There is no event for units that leave transport, however those units fire the "Unit enters (playable map area)" event, so I use that and to know that it was indeed a transported unit, I check if it is in the unit group I wrote about above.
 
Level 2
Joined
Sep 1, 2014
Messages
14
Thank you all guys. I have build a system which save the loaded units in another unit.

Here are my triggers:

The trigger when the ability (take over the units from one transporter to the other) is activated:
  • TruppenUebernehmen
    • Events
      • Unit - A unit Begins channeling an ability
    • Conditions
      • (Ability being cast) Equal to Entangling Roots
    • Actions
      • For each (Integer A) from 0 to intConnecter, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Target unit of ability being cast) Equal to dorf[(Integer A)]
            • Then - Actions
              • Unit Group - Pick every unit in doerferGruppen[intConnecter] and do (Actions)
                • Loop - Actions
                  • Game - Display to (All players) the text: Load out
                  • Unit - Order (Target unit of ability being cast) to Unload (Picked unit)
                  • Unit Group - Remove (Picked unit) from doerferGruppen[(Integer A)]
                  • Unit - Order (Casting unit) to Load (Picked unit)
            • Else - Actions
The trigger to save the units in a unitgroup for each transporter:
  • einheitWirdGeladen
    • Events
      • Unit - A unit Is loaded into a transport
    • Conditions
    • Actions
      • For each (Integer A) from 0 to intConnecter, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Transporting unit) Equal to dorf[(Integer A)]
            • Then - Actions
              • Unit Group - Add (Loading unit) to doerferGruppen[(Integer A)]
            • Else - Actions
              • Set intConnecter = (intConnecter + 1)
              • Set dorf[intConnecter] = (Transporting unit)
              • Unit Group - Add (Loading unit) to doerferGruppen[intConnecter]
#Edit: Have patched my wc3 to english
 
Last edited:
Level 25
Joined
Sep 26, 2009
Messages
2,378
Your loops are wrong. The code in them is wrong as well.

First of all, the condition in loops is wrong. If you are using a loop "For each (Integer A) from 0 to intConnecter", then you should reference the instances as "dorf[(Integer A)]". What you have right now checks repeatedly only the last instance (the last instance is dorf[intConnecter]).

Second, there is no need to use "wait" in the loop. Also, the "wait" action is never accurate, so the wait time actually differs each time it is used.

Third and most important, the "Else" part of If/Then/Else in your loops is wrong. What your loop does right now is that it checks each transport and if the conditions do not match, it indexes the transport into the dorf[] array (at least that's what I understand from the german trigger).

Now imagine this scenario: Your dorf[] array already contains 3 transports - for simplicity I will call them "Transport_1", "Transport_2" and "Transport_3". So basically your dorf[] array is filled like this: dorf[Transport_1, Transport_2, Transport_3, <other indices are null>].
Imagine a unit entering "Transport_2".

Your loop does this:
Is used transport == dorf[1]? Which can be translated into Is Transport_2 == Transport_1?
- no, it's not, so it creates new instance at the end. Now it continues
Is used transport == dorf[2]? Which is Is Transport_2 == Transport_2?
-
In this case it is. So nothing happens bad happens. And last iteration
Is used transport == dorf[3]? Which is Is Transport_2 == Transport_3?
- Nope, create new instance.

Now, I can't say for sure how the "wait" will affect the result, but you can see that this is not what you want.
What you should aim for should be "If transport isn't equal to any in the dorf[] array, then create a new instance". What you have now is "if transport isn't equal to a dorf[] array instance, then create new instance".
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,199
Zathcore TruppenUebernehmen is broken because you cannot use TriggerSleepAction (GUI Wait) in a group enum (pick every unit in group and do). Doing so causes a thread crash at the time TriggerSleepAction is called.

You really should not be using TriggerSleepAction at any time during this as the resulting delay is unpredictable and can be considerably longer in multiplayer.
 
Level 2
Joined
Sep 1, 2014
Messages
14
First of all, the condition in loops is wrong. If you are using a loop "For each (Integer A) from 0 to intConnecter", then you should reference the instances as "dorf[(Integer A)]". What you have right now checks repeatedly only the last instance (the last instance is dorf[intConnecter]).

Changed that.

Second, there is no need to use "wait" in the loop. Also, the "wait" action is never accurate, so the wait time actually differs each time it is used.

Deleted them.

Third and most important, the "Else" part of If/Then/Else in your loops is wrong. What your loop does right now is that it checks each transport and if the conditions do not match, it indexes the transport into the dorf[] array (at least that's what I understand from the german trigger).

Now imagine this scenario: Your dorf[] array already contains 3 transports - for simplicity I will call them "Transport_1", "Transport_2" and "Transport_3". So basically your dorf[] array is filled like this: dorf[Transport_1, Transport_2, Transport_3, <other indices are null>].
Imagine a unit entering "Transport_2".

Your loop does this:
Is used transport == dorf[1]? Which can be translated into Is Transport_2 == Transport_1?
- no, it's not, so it creates new instance at the end. Now it continues
Is used transport == dorf[2]? Which is Is Transport_2 == Transport_2?
-
In this case it is. So nothing happens bad happens. And last iteration
Is used transport == dorf[3]? Which is Is Transport_2 == Transport_3?
- Nope, create new instance.

This it that what it should do. The reason for that is my Map mechanic. In german dorf means village. So I have a few villages on my map. They all could contain units.
Maybe this ingame picture helps to understand what im tryin to do:
WC9HPRU.jpg


What you should aim for should be "If transport isn't equal to any in the dorf[] array, then create a new instance". What you have now is "if transport isn't equal to a dorf[] array instance, then create new instance".

Didn't know exactly how i could change that.

But thank you man that you are so dedicated. +rep
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,199
I would like to remind you that THW does have a multi-post rule. Please refrain from double posting within 48 hours of the previous post.

A demonstration map showing what you have and the triggers involved might be useful. That way people can experiment around until it works rather than having to visualize the changes needed.
 
Level 2
Joined
Sep 1, 2014
Messages
14
Ohh sry man haven't seen that in the rules :eek:
So i have created a map which is an example for an skill which pulls out all units of an transporter.

So i got the Load in trigger working, but the ability trigger doesn't work for me.


  • LoadIn
    • Events
      • Unit - A unit Is loaded into a transport
    • Conditions
    • Actions
      • Set unit = (Transporting unit)
      • For each (Integer A) from 0 to connecter, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • unit Equal to transporter[(Integer A)]
            • Then - Actions
              • -------- Transporter Unit have an Array. Then; --------
              • Set transporter[(Integer A)] = (Transporting unit)
              • Game - Display to (All players) the text: (Added Unit to the + ((String((Integer A))) + UnitGroup))
              • Unit Group - Add (Loading unit) to unitsInTransporter[(Integer A)]
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Integer A) Equal to 0) and (truth Equal to False)
                • Then - Actions
                  • -------- Transporter Unit is null and hasn't an array yet. Then: --------
                  • Set truth = True
                  • Set transporter[0] = (Transporting unit)
                  • Game - Display to (All players) the text: Added Unit to the 0...
                  • Unit Group - Add (Loading unit) to unitsInTransporter[0]
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • transporter[0] Equal to unit
                    • Then - Actions
                      • -------- Transporter Unit is null and has an array. Then: --------
                      • Game - Display to (All players) the text: Added Unit to the 0...
                      • Unit Group - Add (Loading unit) to unitsInTransporter[0]
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • connecter Equal to (Integer A)
                        • Then - Actions
                          • -------- Transporter Unit hasn't an array and isn't nulll. Then: --------
                          • Set connecter = (connecter + 1)
                          • Set transporter[connecter] = (Transporting unit)
                          • Game - Display to (All players) the text: (Added Unit to the + ((String(connecter)) + UnitGroup))
                          • Unit Group - Add (Loading unit) to unitsInTransporter[(connecter + 1)]
                        • Else - Actions
                          • Do nothing
The trigger which doesnt work:

  • TruppenUebernehmen
    • Events
      • Unit - A unit Begins channeling an ability
    • Conditions
      • (Ability being cast) Equal to takeover
    • Actions
      • For each (Integer A) from 0 to connecter, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Target unit of ability being cast) Equal to transporter[(Integer A)]
            • Then - Actions
              • Unit Group - Pick every unit in unitsInTransporter[(Integer A)] and do (Actions)
                • Loop - Actions
                • Unit - Order transporter[(Integer A)] to Unload (Picked unit)
                • Game - Display to (All players) the text: unloaded
                • Unit - Order (Casting unit) to Load (Picked unit)
                • Game - Display to (All players) the text: loaded
                • Unit Group - Remove (Picked unit) from unitsInTransporter[(Integer A)]
            • Else - Actions
I know the issue but didn't know how to fix it. The problem is that after the units are unloaded there is no time for the other unit to pick the unloaded unit up.
 

Attachments

  • test.w3x
    18.7 KB · Views: 36
Last edited:
Level 37
Joined
Jul 22, 2015
Messages
3,485
Why not just use Bribe's GUI Unit Event?

Bribe said:
Use the event "Game - CargoEvent becomes Equal to 1.00" to detect when a unit is loaded into a transport. Use the event "Game - CargoEvent becomes Equal to 2.00" to detect when it is unloaded.

You also have "CargoTransportUnit[(Custom value of Unit)]" to get the unit who is carrying the unit, and "CargoTransportGroup[(Custom value of Transport)]" to pick all units that the transport is carrying.
 
Status
Not open for further replies.
Top