The functionality I am trying to create is simple - a 2-way teleport pad. Enter region A and you are teleported to B. Once you leave region B and re-enter, you are teleported back to region A. And the cycle continues ad infinitum.
My current approach uses 2 triggers, here is a rough outline:
Trigger1:Teleport(InitiallyON)Events:-UnitentersA-UnitentersBActions:-TurnTeleportOFF-Switch(triggeringregion)caseA: MovetriggeringunittoBcaseB: MovetriggeringunittoA// ~~ Problems unless I place a Wait here ~~-TurnTeleportEnableONTrigger2:TeleportEnable(InitiallyOFF)Events:-UnitexitsA-UnitexitsBActions:-TurnTeleportEnableOFF-TurnTeleportON
The issue is that even though I am turning TeleportEnable on after the move action (in theory), what's actually happening is that move action triggers the teleport enable. For example, lets say the unit enters A. That triggers Teleport and moves unit to B. Moving unit from A to B triggers TeleportEnable as the unit exits A. The unit enters B, triggering Teleport, and teleports back to A.
However, IF I place a wait in the commented line, everything works "fine," for 1 player anyway, with nothing else going on. But I easily see this bugging out with 10 players all teleporting around at the same time, and possible other waits that I need for the actual gameplay. I suppose I could use a periodic trigger or a timer to create a makeshift "safe" wait, but I'm really wondering if there's a clean way to implement this system, and what my actual problem is.
The problem you are noticing has to do with the fact that events do not trigger instantly, but have a delay of up to one game loop.
So if you turn TeleportEnable on instantly after teleporting the unit, the event did not yet fire but is still sitting in the event queue. A short moment later it will get consumed and therefore executes the teleport enable.
To come back to your specific problem: The by far easiest way to do this is by using behaviors. Create a behavior called "No Teleport" in the data editor and set its duration to 0.1 seconds (or even shorter). When one unit enters A, add the behavior to it and after that teleport it to B. If any unit enters A or B but has the behavior, do nothing. That prevents an endless teleportation loop and is multiplayer save. It also supports multiple units per player. You can set the behavior to hidden by checking the hidden behavior flag so players will not even notice that it exists.
The behavior method Mille mentioned will work. Personally I'd make a global boolean variable as an array. Then instead of turning triggers on or off, I'd set the variable[triggering player] to true/false.
Thanks for the detailed and helpful response! I hate the data editor, but given how you described it that sounds like a very clean solution so I will go for it.
Edit: Worked like a charm, one minor thing though. I started by making the buff length 0.05 and it actually was too short (infinite teleport loop), so I knocked it up to 0.1 and it works fine. I have noticed that the editor seems to have problems with really short time windows (specifically durations less than 0.1 seconds), i.e. cannot make unit face angle instantly, cannot wait for very small amounts of time, etc.
-
And MaskedImpostor, that doesn't circumvent the issue at hand here. That was my initial implementation :P
The functionality I am trying to create is simple - a 2-way teleport pad. Enter region A and you are teleported to B. Once you leave region B and re-enter, you are teleported back to region A. And the cycle continues ad infinitum.
My current approach uses 2 triggers, here is a rough outline:
The issue is that even though I am turning TeleportEnable on after the move action (in theory), what's actually happening is that move action triggers the teleport enable. For example, lets say the unit enters A. That triggers Teleport and moves unit to B. Moving unit from A to B triggers TeleportEnable as the unit exits A. The unit enters B, triggering Teleport, and teleports back to A.
However, IF I place a wait in the commented line, everything works "fine," for 1 player anyway, with nothing else going on. But I easily see this bugging out with 10 players all teleporting around at the same time, and possible other waits that I need for the actual gameplay. I suppose I could use a periodic trigger or a timer to create a makeshift "safe" wait, but I'm really wondering if there's a clean way to implement this system, and what my actual problem is.
The problem you are noticing has to do with the fact that events do not trigger instantly, but have a delay of up to one game loop.
So if you turn TeleportEnable on instantly after teleporting the unit, the event did not yet fire but is still sitting in the event queue. A short moment later it will get consumed and therefore executes the teleport enable.
To come back to your specific problem: The by far easiest way to do this is by using behaviors. Create a behavior called "No Teleport" in the data editor and set its duration to 0.1 seconds (or even shorter). When one unit enters A, add the behavior to it and after that teleport it to B. If any unit enters A or B but has the behavior, do nothing. That prevents an endless teleportation loop and is multiplayer save. It also supports multiple units per player. You can set the behavior to hidden by checking the hidden behavior flag so players will not even notice that it exists.
The behavior method Mille mentioned will work. Personally I'd make a global boolean variable as an array. Then instead of turning triggers on or off, I'd set the variable[triggering player] to true/false.
@Mille25: Go
Thanks for the detailed and helpful response! I hate the data editor, but given how you described it that sounds like a very clean solution so I will go for it.
Edit: Worked like a charm, one minor thing though. I started by making the buff length 0.05 and it actually was too short (infinite teleport loop), so I knocked it up to 0.1 and it works fine. I have noticed that the editor seems to have problems with really short time windows (specifically durations less than 0.1 seconds), i.e. cannot make unit face angle instantly, cannot wait for very small amounts of time, etc.
-
And MaskedImpostor, that doesn't circumvent the issue at hand here. That was my initial implementation :P