Is there a sufficient and non-buggy way to detect when a unit steps on for example a lowered supply depot? Either through triggers or data. I need to order that unit to turn 90/180/-90/360 degrees when encountering a (for example) lowered supply depot.
I've tried but I suck sooo hard at coding and stuff, I just end up giving up after 3 hours of accomplishing nothing
I have yet to test it but it sounds like it should work. Thanks a lot
edit: tested it and it does not seem to work :S
I put a Lowered Supply Depot on the map and added it to unit group X via triggers.
Another trigger I had look like this:
Events: Any Unit Enters a Distance of 0.1 from (Random Living Unit from unit group X)
Actions: Order Triggering Unit to Stop
Make Triggering Unit face 180 Degrees
The unit just walks right over the Supply depot. I've tried changing the event to use "unit 1 from unit group X", I've tried to increase the distance to 5, nothing works
edit #2: it's the unit group thing that causes the problem. I changed the unit group to a specific unit and then it worked. what do?
Is there really no easy way to do this? I've tried giving the turn thingies an attack and using a "Any unit is attacked" event and a "unit type of unit == this and that" etc, but those sorts of methods are often so messy.
Why can't events use variables?
Also shameless self bump
I guess I should explain in closer detail what I want...
In my map I want certain worker units to be able to build "turn pads" which makes any unit that walk over it turn. Since these things need to be able to be constructed, I can't have them as presets in any trigger event because they wont exist when the map launches/loads.
ok looks like I was PMed to this thread cause I did something similar in raynor party
there's no easy way to do it that I know of, with triggers anyway - maybe effects or behaviours in the data editor can alter unit facing like that? I've not looked. if it's possible, you can then use a behaviour with a periodic search area effect to grab units who come close and set their facing
as you've discovered, you can't use the unit enters range of unit event as-is, because trigger events aren't dynamic like that: the event is "added" to the trigger on map initialization and the parameters evaluated there-and-then as with any other function, so if you try to use a variable there you'll just end up with whatever the initial value of the variable is as the unit
but there are some more complicated ways
the method I use in raynor party is pretty good, but it can only support a finite number of trap units at once. if the players can potentially create an unlimited number of traps you'll run into additional complications. the general idea is we pre-make a bunch of regions and move them during the game play when traps are created, and then use unit enters region on all these regions
SO!!
create a bunch of regions big enough to cover the trap unit-type anywhere on the map, call them TrapRegion00 to TrapRegion99 or whatever. you need enough regions to have one for every trap that can exist simultaeneously. make a region array variable with enough entries and set each entry to one of these regions (on map initialization). so Regions[0] = TrapRegion00, Regions[1] = TrapRegion01, and so on. Make a trigger and add a "unit enters region" event for all of these regions. You gotta do most of this manually so it's a giant pain in the arse if you need a lot of simultaeneous traps
THEN!!
You also need a unit array variable of the same size as the regions array, call it Units. Have an integer variable like RegionsUsed, initially zero. Whenever someone creates a trap, move Regions[RegionsUsed] to the position of the trap, set Units[RegionsUsed] to the trap unit and increment RegionsUsed. Then in the trigger with all the "enters region" events, loop through the regions array using some index variable i and check whether the triggering region is equal to Regions[i]. You only need to check values of i less than the current value of RegionsUsed. If it is, you know the triggering unit stepped on Units[i] and you can do what you like
UH OH!!
you need a separate region for each potential simultaeneously-existing trap, so obviously this won't work for an arbitrary number of traps. you can theoretically have 8192 regions in a big array but uh, you probably don't want to manually create 8192 regions, assign them to the array, and add an event with them... SO You can either limit the number of traps somehow, or destroy old traps if there's too many, or whatnot. if traps can be destroyed, you need to do some extra stuff too. you can keep a boolean array of IsRegionUsed[] in this case instead of using a RegionsUsed variable. When a trap is created, loop through to find the first unused region and use that. When it's destroyed, loop through the units array to find the index and set IsRegionUsed[i] to false. blah blah blah
THE OTHER METHOD :(
this works for an arbitrary number of traps but it's less straightforward. you need to create a trigger with no events as the "stepped on a trap" trigger. when a trap is created, you dynamically add a new event to the trigger. this gets around the problem mentioned earlier. you can only dynamically add events with custom script. for unit enters range of unit, the script you need is TriggerAddEventUnitRange(gt_NameOfYourTrigger, null, TRAP_UNIT, RANGE, true); Fill in the capitals with whatever. The trap unit will be Created Unit or some local variable or whatever, hit Ctrl+D to look at things and figure out what you need. Now you've got a trigger that, although it has no events, will fire whenever a unit enters range of one of your created traps. Triggering Unit will give you the unit that stepped on the trap. The problem now is that you don't know which trap was stepped on. You gotta come up with a way to get round this. Maybe check every trap on the map and see if the triggering unit is close enough to it; alternatively, you could duplicate the entire system for each distinct type of trap if knowing the type is enough.
WARNING I haven't actually tried this method but I'm pretty sure it should work, and it worked in war3. probably gonna change raynor party to use this sometime
i'm pretty much rambling here and it's a rough outline but hopefully you can figure out a decent system
EDIT i've been told there might actually be custom script for programatically creating regions at run-time which would simplify the first method a lot. haven't looked to see what it is. was possible in war3 but first I looked star2 stored regions as XML, but someone said only the editor uses that
I would look into using the Data Editor for this. You could give the turn pads a behavior (e.g. Look at the Science Vessel's "Irradiated" behavior) which searches for any units in range and performs a given action on that unit. Then, create a trigger which detects this action and checks for the desired conditions (i.e. unit type, unit is moving towards turn pad, etc.).
Thanks a lot guise. That's quite a read, grandseiken xD. The only thing I didn't quite get was "TRAP_UNIT"... Am I just supposed to change that to "Triggering_Unit" or whatever the syntax is ("TriggerUnit" like in jass?). I havn't used scripts yet, probably never will to any great extent :P
Basically what am I supposed to put instead of "TRAP_UNIT"?
I always ramble on
edit:
The problem now is that you don't know which trap was stepped on. You gotta come up with a way to get round this.
I think I'll just create four different triggers that detect when turn pads are made, and four different triggers without events, one of each for every turn direction (90, 180, 270, 360)
edit again: Ok, now I have a trigger with no events and the action to turn Triggering Unit 180 degrees.
My trigger which is supposed to add the events to the trigger I just mentioned runs whenever a "Turn Pad: Left" is constructed and the custom script looks like this:
[code]TriggerAddEventUnitRange(gt_StepOnTurnPadLeft, null, TRAP_UNIT, 0.1, true);[/code]
I'm still not sure what to put instead of TRAP_UNIT and I'm not sure if that semicolon is supposed to be there at the end. I'm so pro at this xD obs! read next edit
edit 3: Ok, so I figured out I'm supposed to put "Triggering Progress Unit" instead of TRAP_UNIT since the event I'm using is "Unit - Any Unit construction progress is Completed". My custom script looks like this atm:"TriggerAddEventUnitRange(gt_StepOnTurnPadLeft, null, EventUnitProgressUnit, 0.1, true);" but when saving/running the map I get an error message which says "Script failed to compile: Parameter type does not match the function definition". I tried to remvove the semicolon at the end but then I got two error messages, so I assume that it is supposed to be there.
My guess is that I'm missing some brackets here and there. any help?
thanks in advance
edit: the map is actually nearing a playable state. As soon as this hopefully small problem is fixed I think a beta version is imminent :) yay
I would look into using the Data Editor for this. You could give the turn pads a behavior (e.g. Look at the Science Vessel's "Irradiated" behavior) which searches for any units in range and performs a given action on that unit. Then, create a trigger which detects this action and checks for the desired conditions (i.e. unit type, unit is moving towards turn pad, etc.).
This might be a better method anyway; there seems to be an "Effect Used" event and a corresponding "Triggering Effect Unit" function which I've not tested but maybe they work like you want. The event doesn't have grammar text and has a mysterious integer parameter though so maybe it's not yet implemented or who knows
I always end up doing things the hard way but by jove does it work
yea, I suspected so aswell, as the data editor is supposed to be this all-powerful solution to every problem. I'm sure it is, but I'm way too uncomfortable and unexperianced in it, I'm so used to doing everything with triggers like in wc3 xD
I was going to try that method too, though either directly if this trigger method should'nt work or later when everything would be working and I'd have freedom to mess around and try things out.
Duplicating units and making new buttons is as far as I've gotten into the data editor basically :)
Edit: It works... Sometimes... Sometimes when units walks over a "Turn Pad" they just ignore it, sometimes they turn to an angle that's slightly off, like 80 degrees instead of 90 or 170 instead of 180... super duper weird. Sometimes it works though
Edit 2: This is sooo weird. It seems like the angle gets skewed by approx 10 degrees the SECOND time a unit steps on a "Leftie" turn pad OR the SECOND time a unit steps on a "Rightie" turn pad, no matter what happens in between. wtf
edit 3: like, my computer is litterally not executing what I'm telling it to do. Here's how my 2 triggers for a "Rightie" turn pad looks:
Trigger 1 (construction)
[code]BuildTurnPadRight
Events
Unit - Any Unit construction progress is Completed
Local Variables
Conditions
(Unit type of (Triggering progress unit)) == Turn Pad: Right <em>custom
Actions
General - Custom Script: TriggerAddEventUnitRange(gt_StepOnTurnPadRight, null, EventUnitProgressUnit(), 0.1, true);[/code]
Trigger 2 (when a unit walks on it):
[code]StepOnTurnPadRight
Events
Local Variables
unit = No Unit <Unit>
point = No Point <Point>
Conditions
((Triggering unit) is in Runners) == true
Actions
Variable - Set unit = (Triggering unit)
Variable - Set point = ((Position of unit) offset by 21.0 towards 360.0 degrees)
Unit - Order unit to ( Move targeting point) (Replace Existing Orders)[/code]
(lots of unnecessary variables, that's just things I've tried out to make it work. In vain.
why would the unit turn to like 350 or 340 degrees instead of 360? I'm suspecting it's maybe a collision issue that should be fixed in the Data Editor but I've set almost all values in Movement to 0 and unchecked all values under "Collide".
My other guess is that it has to do with the radius within which the unit must be in order for the trigger to detect it; the unit will just barely enter it, then turn and then just barely enter the next turn pad's radius etc, and finally it misses it. I've tried to fix this using local variables and a "Wait" function that waits 0.05 sec before ordering the unit to turn, but THAT didn't fix the issue either. The units just keep turning 10-20 degrees to much/little...
FFFFFFFFFFFFFFFFFUUUUUUUUUUUU
edit 3: lol i think I figured it out. The point I order the to go to is outside the map and therefore it gets "pushed" to the side. Gonna increase the map bounds and see what happens xD
Oh me
Is there a sufficient and non-buggy way to detect when a unit steps on for example a lowered supply depot? Either through triggers or data. I need to order that unit to turn 90/180/-90/360 degrees when encountering a (for example) lowered supply depot.
I've tried but I suck sooo hard at coding and stuff, I just end up giving up after 3 hours of accomplishing nothing
Ok you can easily do this.
Any unit enters range of unit from unit group.
For specifics, change any unit to unit from Unit group. And then change unit group to Units in region matching condition.
You can specify exactly what unit you want to come in contact with, and what unit you want it to come in contact with.
Then you change your range to 0.1 It's not specifically on top of but it's damn close. Maybe 0.0 might work.
Anyway.
Then you have your trigger make unit face angle.
Hope that helps.
@stevehammon: Go
I have yet to test it but it sounds like it should work. Thanks a lot
edit: tested it and it does not seem to work :S
I put a Lowered Supply Depot on the map and added it to unit group X via triggers. Another trigger I had look like this: Events: Any Unit Enters a Distance of 0.1 from (Random Living Unit from unit group X) Actions: Order Triggering Unit to Stop Make Triggering Unit face 180 Degrees
The unit just walks right over the Supply depot. I've tried changing the event to use "unit 1 from unit group X", I've tried to increase the distance to 5, nothing works
edit #2: it's the unit group thing that causes the problem. I changed the unit group to a specific unit and then it worked. what do?
Is there really no easy way to do this? I've tried giving the turn thingies an attack and using a "Any unit is attacked" event and a "unit type of unit == this and that" etc, but those sorts of methods are often so messy.
Why can't events use variables?
Also shameless self bump
I guess I should explain in closer detail what I want... In my map I want certain worker units to be able to build "turn pads" which makes any unit that walk over it turn. Since these things need to be able to be constructed, I can't have them as presets in any trigger event because they wont exist when the map launches/loads.
ok looks like I was PMed to this thread cause I did something similar in raynor party
there's no easy way to do it that I know of, with triggers anyway - maybe effects or behaviours in the data editor can alter unit facing like that? I've not looked. if it's possible, you can then use a behaviour with a periodic search area effect to grab units who come close and set their facing
as you've discovered, you can't use the unit enters range of unit event as-is, because trigger events aren't dynamic like that: the event is "added" to the trigger on map initialization and the parameters evaluated there-and-then as with any other function, so if you try to use a variable there you'll just end up with whatever the initial value of the variable is as the unit
but there are some more complicated ways
the method I use in raynor party is pretty good, but it can only support a finite number of trap units at once. if the players can potentially create an unlimited number of traps you'll run into additional complications. the general idea is we pre-make a bunch of regions and move them during the game play when traps are created, and then use unit enters region on all these regions
SO!!
create a bunch of regions big enough to cover the trap unit-type anywhere on the map, call them TrapRegion00 to TrapRegion99 or whatever. you need enough regions to have one for every trap that can exist simultaeneously. make a region array variable with enough entries and set each entry to one of these regions (on map initialization). so Regions[0] = TrapRegion00, Regions[1] = TrapRegion01, and so on. Make a trigger and add a "unit enters region" event for all of these regions. You gotta do most of this manually so it's a giant pain in the arse if you need a lot of simultaeneous traps
THEN!!
You also need a unit array variable of the same size as the regions array, call it Units. Have an integer variable like RegionsUsed, initially zero. Whenever someone creates a trap, move Regions[RegionsUsed] to the position of the trap, set Units[RegionsUsed] to the trap unit and increment RegionsUsed. Then in the trigger with all the "enters region" events, loop through the regions array using some index variable i and check whether the triggering region is equal to Regions[i]. You only need to check values of i less than the current value of RegionsUsed. If it is, you know the triggering unit stepped on Units[i] and you can do what you like
UH OH!!
you need a separate region for each potential simultaeneously-existing trap, so obviously this won't work for an arbitrary number of traps. you can theoretically have 8192 regions in a big array but uh, you probably don't want to manually create 8192 regions, assign them to the array, and add an event with them... SO You can either limit the number of traps somehow, or destroy old traps if there's too many, or whatnot. if traps can be destroyed, you need to do some extra stuff too. you can keep a boolean array of IsRegionUsed[] in this case instead of using a RegionsUsed variable. When a trap is created, loop through to find the first unused region and use that. When it's destroyed, loop through the units array to find the index and set IsRegionUsed[i] to false. blah blah blah
THE OTHER METHOD :(
this works for an arbitrary number of traps but it's less straightforward. you need to create a trigger with no events as the "stepped on a trap" trigger. when a trap is created, you dynamically add a new event to the trigger. this gets around the problem mentioned earlier. you can only dynamically add events with custom script. for unit enters range of unit, the script you need is TriggerAddEventUnitRange(gt_NameOfYourTrigger, null, TRAP_UNIT, RANGE, true); Fill in the capitals with whatever. The trap unit will be Created Unit or some local variable or whatever, hit Ctrl+D to look at things and figure out what you need. Now you've got a trigger that, although it has no events, will fire whenever a unit enters range of one of your created traps. Triggering Unit will give you the unit that stepped on the trap. The problem now is that you don't know which trap was stepped on. You gotta come up with a way to get round this. Maybe check every trap on the map and see if the triggering unit is close enough to it; alternatively, you could duplicate the entire system for each distinct type of trap if knowing the type is enough.
WARNING I haven't actually tried this method but I'm pretty sure it should work, and it worked in war3. probably gonna change raynor party to use this sometime
i'm pretty much rambling here and it's a rough outline but hopefully you can figure out a decent system
EDIT i've been told there might actually be custom script for programatically creating regions at run-time which would simplify the first method a lot. haven't looked to see what it is. was possible in war3 but first I looked star2 stored regions as XML, but someone said only the editor uses that
@FIRETRUCKEU: Go
I would look into using the Data Editor for this. You could give the turn pads a behavior (e.g. Look at the Science Vessel's "Irradiated" behavior) which searches for any units in range and performs a given action on that unit. Then, create a trigger which detects this action and checks for the desired conditions (i.e. unit type, unit is moving towards turn pad, etc.).
Thanks a lot guise. That's quite a read, grandseiken xD. The only thing I didn't quite get was "TRAP_UNIT"... Am I just supposed to change that to "Triggering_Unit" or whatever the syntax is ("TriggerUnit" like in jass?). I havn't used scripts yet, probably never will to any great extent :P Basically what am I supposed to put instead of "TRAP_UNIT"?
I always ramble on
edit:
I think I'll just create four different triggers that detect when turn pads are made, and four different triggers without events, one of each for every turn direction (90, 180, 270, 360)edit again: Ok, now I have a trigger with no events and the action to turn Triggering Unit 180 degrees. My trigger which is supposed to add the events to the trigger I just mentioned runs whenever a "Turn Pad: Left" is constructed and the custom script looks like this: [code]TriggerAddEventUnitRange(gt_StepOnTurnPadLeft, null, TRAP_UNIT, 0.1, true);[/code]
I'm still not sure what to put instead of TRAP_UNIT and I'm not sure if that semicolon is supposed to be there at the end. I'm so pro at this xD obs! read next edit
edit 3: Ok, so I figured out I'm supposed to put "Triggering Progress Unit" instead of TRAP_UNIT since the event I'm using is "Unit - Any Unit construction progress is Completed". My custom script looks like this atm:"TriggerAddEventUnitRange(gt_StepOnTurnPadLeft, null, EventUnitProgressUnit, 0.1, true);" but when saving/running the map I get an error message which says "Script failed to compile: Parameter type does not match the function definition". I tried to remvove the semicolon at the end but then I got two error messages, so I assume that it is supposed to be there. My guess is that I'm missing some brackets here and there. any help? thanks in advance
edit: the map is actually nearing a playable state. As soon as this hopefully small problem is fixed I think a beta version is imminent :) yay
@FIRETRUCKEU:
EventUnitProgressUnit()
This might be a better method anyway; there seems to be an "Effect Used" event and a corresponding "Triggering Effect Unit" function which I've not tested but maybe they work like you want. The event doesn't have grammar text and has a mysterious integer parameter though so maybe it's not yet implemented or who knows
I always end up doing things the hard way but by jove does it work
@grandseiken: Go
sweet. thanks!
@grandseiken: Go
yea, I suspected so aswell, as the data editor is supposed to be this all-powerful solution to every problem. I'm sure it is, but I'm way too uncomfortable and unexperianced in it, I'm so used to doing everything with triggers like in wc3 xD
I was going to try that method too, though either directly if this trigger method should'nt work or later when everything would be working and I'd have freedom to mess around and try things out.
Duplicating units and making new buttons is as far as I've gotten into the data editor basically :)
Edit: It works... Sometimes... Sometimes when units walks over a "Turn Pad" they just ignore it, sometimes they turn to an angle that's slightly off, like 80 degrees instead of 90 or 170 instead of 180... super duper weird. Sometimes it works though
Edit 2: This is sooo weird. It seems like the angle gets skewed by approx 10 degrees the SECOND time a unit steps on a "Leftie" turn pad OR the SECOND time a unit steps on a "Rightie" turn pad, no matter what happens in between. wtf edit 3: like, my computer is litterally not executing what I'm telling it to do. Here's how my 2 triggers for a "Rightie" turn pad looks:
Trigger 1 (construction) [code]BuildTurnPadRight Events Unit - Any Unit construction progress is Completed Local Variables Conditions (Unit type of (Triggering progress unit)) == Turn Pad: Right <em>custom Actions General - Custom Script: TriggerAddEventUnitRange(gt_StepOnTurnPadRight, null, EventUnitProgressUnit(), 0.1, true);[/code]
Trigger 2 (when a unit walks on it): [code]StepOnTurnPadRight Events Local Variables unit = No Unit <Unit> point = No Point <Point> Conditions ((Triggering unit) is in Runners) == true Actions Variable - Set unit = (Triggering unit) Variable - Set point = ((Position of unit) offset by 21.0 towards 360.0 degrees) Unit - Order unit to ( Move targeting point) (Replace Existing Orders)[/code] (lots of unnecessary variables, that's just things I've tried out to make it work. In vain.
why would the unit turn to like 350 or 340 degrees instead of 360? I'm suspecting it's maybe a collision issue that should be fixed in the Data Editor but I've set almost all values in Movement to 0 and unchecked all values under "Collide".
My other guess is that it has to do with the radius within which the unit must be in order for the trigger to detect it; the unit will just barely enter it, then turn and then just barely enter the next turn pad's radius etc, and finally it misses it. I've tried to fix this using local variables and a "Wait" function that waits 0.05 sec before ordering the unit to turn, but THAT didn't fix the issue either. The units just keep turning 10-20 degrees to much/little...
FFFFFFFFFFFFFFFFFUUUUUUUUUUUU
edit 3: lol i think I figured it out. The point I order the to go to is outside the map and therefore it gets "pushed" to the side. Gonna increase the map bounds and see what happens xD Oh me
edit 4: yep. that fixed it. fakking sweeeet