• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Need optmize this trigger (IA sell item in a shop)

Level 13
Joined
Oct 28, 2019
Messages
523
A woodcutter cuts trees, and a serf picks up the trunks and takes them to the sawmill.
  • UnitSerfWood1a
    • Events
      • Unit - A unit Acquires an item
    • Conditions
      • (Hero manipulating item) Equal to UnitSerfWood1a
      • (Item being manipulated) Equal to ItemWood1a
    • Actions
      • Game - Display to (All players) the text: Acquires Wood1a
      • Set VariableSet ItemWood1a = No item
      • Set VariableSet ItemWoodCarry1a = (Item being manipulated)
      • Wait 0.10 seconds
      • Unit - Order UnitSerfWood1a to give ItemWoodCarry1a to UnitSawmill1
the trigger works, but sometimes bugs, and IDK why
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,871
You're referencing global variables after a Wait. They're global, meaning that they're being shared by all of your triggers and instances of those triggers.

So if this trigger runs twice in a row, the variables will get set twice, and have a final value equal to whatever the last trigger instance set them to. The first trigger will also be referencing these "last values", since again they're being shared.

There's another concept of variables called local variables, which only exist within the trigger INSTANCE that created them. These are useful when you want to use Waits in your triggers since they won't be shared and avoid the issue of being changed from an outside source. A lot of Event Responses already act like local variables, such as (Triggering unit).

The Trigger Editor doesn't have native support for local variables, but you can use Custom Script to get access to them:
  • UnitSerfWood1a
    • Events
      • Unit - A unit Acquires an item
    • Conditions
      • (Hero manipulating item) Equal to UnitSerfWood1a
      • (Item being manipulated) Equal to ItemWood1a
    • Actions
      • Custom script: local item wood = GetManipulatedItem()
      • Game - Display to (All players) the text: Acquires Wood1a
      • Set VariableSet ItemWood1a = No item
      • Wait 0.10 seconds
      • Custom script: set udg_ItemWoodCarry1a = wood
      • Unit - Order UnitSerfWood1a to give ItemWoodCarry1a to UnitSawmill1
      • Custom script: set wood = null
I also deal with a memory leak associated with using local variables (null).

Note that this trigger may still have issues. If you pick-up a lot of items very quickly it'll probably not do what you want. I have a feeling you're trying to do something a bit more advanced and don't really know how to do it yet. Arrays, Unit Indexing, these sorts of things are likely necessary.
 
Last edited:
Level 45
Joined
Feb 27, 2007
Messages
5,578
  • From your variable names it seems like you don't realize you can make array variables. Instead of Serf1A and Serf2A as separate varaibles you could have SerfA[] and use indices 1 and 2. This could remove even the need to have A and B versions (which I presume should exist from your examples) as it can all be kept in one array.

  • To that end, using a Hashtable or a set of parallel arrays to associate a Serf, a unit of Wood, and a Sawmill together as a unit. This would then allow you to 'learn' the destination for any given serf just by querying the array or hashtable (which has that information in it already), allowing the system to work dynamically. I agree with Uncle that you just aren't aware of the scope of this functionality you want, so when you get there this comment may make more sense.

  • Any amount of any type of local variables can be declared at the top of a GUI trigger (and in other locations). You must define the variable locally as the first line of the trigger (if multiple are defined the order doesn't matter but they all still must be defined at the top) and you must use the proper JASS syntax when referring to its type. In Uncle's example it's an item variable so the definition line says "local item ...". Another variant of this is to make a regular GUI variable behave as though it is a local variable within the function it was made local to. In this instance I think it would cause you harm because the variable itself will not have that local value if you query it anywhere else. Here's a useful tutorial on the matter: local udg_

  • Whether or not any of this is necessary depends on how the sawmill, serf, and wood variables are assigned/manipulated/referenced elsewhere in the other triggers we can't see. It's my intuition that you're tracking a bit more stuff than you need to be, but without seeing more I cannot say so for sure.

  • Waits are imprecise and have a minimum duration of about 0.27s so that 0.1 will not actually be 0.1.
 
Level 13
Joined
Oct 28, 2019
Messages
523
Is necessary to create the itens, but even If I remove all variables the trouble continues, the first item the serf sells and others it remains walking around the sawmill and return to the creation point. Maybe a problem with Object editor
1732655235738.png
 
Level 13
Joined
Oct 28, 2019
Messages
523
A trigger detects iddle serfs, maybe the unit variable is wrong

  • SerfsGetWood1a
    • Events
      • Time - Every 2.00 seconds of game time
    • Conditions
      • (ItemWood1a is in (Playable map area)) Equal to True
      • (Number of units in UGIddleSerfs) Greater than or equal to 1
      • IntegerSawmill Greater than or equal to 1
    • Actions
      • Trigger - Turn off (This trigger)
      • Set VariableSet UnitSerfWood1a = (Random unit from UGIddleSerfs)
      • Unit Group - Remove UnitSerfWood1a from UGIddleSerfs.
      • Unit - Order UnitSerfWood1a to Right-Click ItemWood1a
each item wood1a, wood1b and wood1c has a serf1a, 1b and 1c to carry it
 
Top