Staredit Network > Forums > SC1 UMS Mapmaking Assistance > Topic: player units swap trigger. please help
player units swap trigger. please help
Dec 16 2013, 1:34 am
By: hobbes  

Dec 16 2013, 1:34 am hobbes Post #1



hi guys,

i'm editing a map for free for all play with a twist. I want to make it so that at some point during the game, the units of one player are given to another player, swapping everybody around.

I'm having a bit of difficulty setting this up.

What i started with is this:
give all units owned by player 1 to player 2
give all units owned by player 2 to player 3
etc....
and finally
give all units owned by playe 7 to player 1

There are issues with this:

1) units are not properly swapped
2) if one of the player is defeated, leaves, or we simply play with less than a full house, the trigger is busted.

I tried to figure this out on my own but my trigger expertise is rather limited. I tried setting a trigger that said "if player x has 0 buildings, set switch", but i'm not sure where to go from there.

How do i set this up so that each player properly receives another players units, and how do i set t so the trigger checks for what players are still alive in the game?

i have scmdraft so i can make use of the non playable player spots like player 12, if necessary.

Post has been edited 1 time(s), last time on Dec 16 2013, 1:40 am by hobbes.



None.

Dec 16 2013, 2:41 am Roy Post #2

An artist's depiction of an Extended Unit Death

Try something like this (assuming all your human-controlled players are in Force 1):

Trigger
Players
  • Force 1
  • Conditions
  • Switch 1 is Set
  • Actions
  • Give all [Any Unit] owned by Current Player at Anywhere to Player 10
  • Give all [Any Unit] owned by Player 9 at Anywhere to Current Player
  • Give all [Any Unit] owned by Player 10 at Anywhere to Player 9
  • Preserve Trigger


  • Then to cause the switch, you'd have a trigger like so:

    Trigger
    Players
  • Force 1
  • Conditions
  • (Your conditions)
  • Switch 1 is Cleared
  • Actions
  • (Your actions)
  • Give all [Any Unit] owned by Current Player at Anywhere to Player 9
  • Set Switch 1
  • Wait 0 milliseconds
  • Clear Switch 1
  • Preserve Trigger


  • (Please note that with this implementation, it is crucial that the "Start Swap" trigger is below the "Exchange Units" trigger in the trigger list. If you want it to be above, you'll need to move the give action after the wait action inside the "Start Swap" trigger.)

    For "(Your conditions)" and "(Your actions)," put what is appropriate for when you want the swap to occur. For example, if you wanted to swap every time a 60-second countdown timer finished, you would have your condition be that the timer reached 0 seconds, and the action would be to set the timer to 60 seconds.

    This is a minimalist approach to hit all players within 2 trigger cycles. Here's basically what happens:

    The first player in the game (usually Player 1) will execute the "Start Swap" trigger, which does the following:
    • Gives the first player's units to Player 9 (initial setup for the exchange triggers).
    • Sets a switch (Preventing other players from running the "Start Swap" trigger, and starting "Exchange Units" for all players).
    • Waits 0 milliseconds (makes all other triggers execute exactly one time before continuing this trigger).
    • Clears the switch (Ending the exchange system).

    During the exchange system, "Exchange Units" runs for each player, doing the following:
    • Gives all the player's units to Player 10 (temporary hold).
    • Gives Player 9's units to the player (gives the previous player's units to the current player).
    • Gives Player 10's units to Player 9 (moves the current player's units to Player 9 for the next player).

    So if Players 2, 4, and 5 are in the game, the following happens when "Start Swap" is ready to run:
    • Player 1 does not execute triggers because he is not in the game.
    • Player 2 executes "Start Swap" by giving her units to Player 9, setting the switch and waiting 0 milliseconds
    • Player 3 does not execute triggers because he is not in the game.
    • Player 4 sees the switch is set, so she does the exchange by moving her units to Player 10, taking Player 9's units (which used to belong to Player 2), and then moving her old units from Player 10 to Player 9.
    • Player 5 sees the switch is set, so he does the exchange by moving his units to Player 10, taking Player 9's units (which used to belong to Player 4), and then moving his old units from Player 10 to Player 9.
    • Player 6 does not execute triggers because she is not in the game.
    • Player 7 does not execute triggers because he is not in the game.
    • Player 8 I'm assuming is a computer player, so it has a jolly old time number crunching or whatever it is that it does.
    • (The trigger cycle ends and restarts)
    • Player 1 does not execute triggers because he is not in the game.
    • Player 2 sees the switch is set, so she does the exchange by moving her units (if she had any) to Player 10, taking Player 9's units (which used to belong to Player 5), and then moving her old units (if she had any) from Player 10 to Player 9.
    • Player 2 finishes waiting 0 milliseconds, and continues on to clear the switch to end the exchange.

    A special note on the second-to-last bullet here: remember that Player 2 gave all her units to Player 9 at the very beginning of this process, so she has no units to give to Player 10 (and later move to Player 9) when the "Exchange Units" trigger runs for her, so effectively the trigger just gives her Player 5's units.

    Post has been edited 1 time(s), last time on Dec 16 2013, 2:47 am by Roy. Reason: My hands are typing words




    Dec 16 2013, 8:23 am hobbes Post #3



    hi Roy,

    thank you for your quick response. I read and re-read your post and i understand how it functions now. I didn't realize that triggers are activated in sequential order for each player. I thought that triggers affecting all players activated simultaneously for each of them.

    I created the triggers as you presented them, but it's a bit doesn't work every time.

    I have to computers with starcraft on which i am testing this trigger.
    When i set my condition to "elapsed game time is 5 seconds", then the trigger works, at least it does in 2 player mode.
    However, when i set a longer time such as 6 seconds or more, or if my condition is even another set switch, it will not work.

    When i do the countdown method as you mentioned in the example example, it activates oddly: one player will get both bases and the other gets none. I can't seem to figure out the issue.

    I included the map to with the triggers set as you mentioned. Please ignore the triggers for force 4, i just put them there to get them out of the way.

    Ideally, i'd like to set this trigger in such a way that it activates at 5 or 6 minute intervals. I don't want the timer to be visible for that long though. I wanted to set it up so that after 5 minutes you see a 10 second countdown, then a visual and audio alert that warns the players of the swap. I know how to make these, but before i do them i have to figure out why the trigger isn't working as planned.

    any thoughts?

    Attachments:
    switch places test.scx
    Hits: 2 Size: 109.68kb



    None.

    Dec 16 2013, 11:25 am Wormer Post #4



    Hello, guys!

    Roy,
    Excellent triggers! Smart and compact! One little note. The system will loop on itself when the head player leaves in the gap between 0ms wait. I suggest the following fix:

    Triggers


    hobbes,
    Several comments on your map triggers. You have 2 unused triggers for Force 4 that never fire. You can merge Force 1 triggers that give minerals and show leaderboard. You may want to preserve triggers that give vision to observers to prevent players from turning vision off. You forgot to preserve the trigger that exchanges units.

    Trigger with the condition "Elapsed time is exactly 20 game seconds" doesn't fire because triggers normally execute only once in every 2 game seconds. It means that your triggers see only odd values of the elapsed game time timer.

    However the core of the problem is that the condition you put on place of "Conditions to start the swap" in the trigger that starts the exchange isn't exclusive. You must make it the way that it becomes false right before the trigger finishes or encounters any wait. The condition "Countdown timer is exactly 1 game second" is not exclusive since SC schedules another extra trigger run after it hits wait action. This extra trigger run is held almost immediatelly after the previous one (42ms delay inbetween on fastest speed). Since you have (for instance) 2 players in the game and the condition "Countdown timer is exatly 1 game second" is still true the trigger will run on this next extra cycle for the second player starting another exchange. The soulution might be to force the countdown timer to 0 right in the trigger.

    Then you probably might want to use so called hyper triggers, a technique that utilizes the described behaviour of waits to speed triggers execution to every second game frame (42ms on fastest). You just need to add 3 following triggers at the bottom of the triggers list (important!):

    // Hyper triggers
    TRIGGER (Force 1)
    CONDITIONS
    Always.
    ACTIONS
    // Overall 63 waits.
    Wait 0 milliseconds.
    Wait 0 milliseconds.
    ...
    Wait 0 milliseconds.
    Preserve trigger.


    When using hyper triggers you should avoid using any waits for other purposes. Use so called death counters for an internal countdown timer. Please ask if you need further help on this topic.

    EDIT:
    I attached a test map that shows triggers of players who leave the game aren't finishing.

    Attachments:
    LeftPlayerTrigFinishTest.scx
    Hits: 1 Size: 51.34kb

    Post has been edited 2 time(s), last time on Dec 16 2013, 1:31 pm by Wormer. Reason: Attached a test map.



    Some.

    Dec 16 2013, 1:55 pm Azrael Post #5



    I agree with Roy that using two unused players would be the easiest way to accomplish what you want. His system would probably be the fastest and most compact way to implement it as well.

    However, I wouldn't implement it in that exact way personally, due to it being split up over two trigger cycles. It will often result in the first player in the game being able to see the swap happen, as their units will change to the unused player's color momentarily on the minimap. Additionally, if they were engaged in a fight with someone else, their units may take longer to continue attacking nearby enemies, which would result in a disadvantage.

    You're also opening yourself up to unnecessary trigger conflicts and oversights in the future, such as the one Wormer noticed. This becomes especially true as new triggers are added, especially if you're implementing them in a similar way. You should never use "Wait" outside of hyper triggers, it's akin to using "Goto" in other programming languages.

    These things might not bother you at all, or not enough to warrant changing them. However, if you do want to, then making the system finish within a single cycle will solve the issues mentioned. It will also make the triggers more straightforward, since they will follow the normal order of execution.

    Trying to keep it as simple as possible, this is one way you could do it:

    Trigger
    Players
  • Force 1
  • Conditions
  • (Your conditions to start swap)
  • Force 1 has suffered exactly 0 deaths of Cantina
  • Actions
  • Set deaths of Cantina to 1 for Current Player
  • Set deaths of Cave to 1 for Force 1
  • Preserve Trigger

  • ^ This detects which player is first (Cantina DC) and it will let you figure out which player is last (Cave DC).

    Trigger
    Players
  • Force 1
  • Conditions
  • Force 1 has suffered exactly 1 death of Cantina
  • Actions
  • Set deaths of Cave to 0 for Current Player
  • Give all [Any Unit] owned by Current Player at Anywhere to Player 10
  • Give all [Any Unit] owned by Player 9 at Anywhere to Current Player
  • Give all [Any Unit] owned by Player 10 at Anywhere to Player 9
  • Preserve Trigger

  • ^ This begins the same exchange between all the players, as before. It also removes the Cave death from each player as their swap finishes.

    Trigger
    Players
  • Force 1
  • Conditions
  • Player 1 has suffered exactly 1 death of Cantina
  • Force 1 has suffered exactly 0 deaths of Cave
  • Actions
  • Set deaths of Cantina to 0 for Force 1
  • Give all [Any Unit] owned by Player 9 at Anywhere to Player 1
  • Preserve Trigger


  • Trigger
    Players
  • Force 1
  • Conditions
  • Player 2 has suffered exactly 1 death of Cantina
  • Force 1 has suffered exactly 0 deaths of Cave
  • Actions
  • Set deaths of Cantina to 0 for Force 1
  • Give all [Any Unit] owned by Player 9 at Anywhere to Player 2
  • Preserve Trigger


  • Trigger
    Players
  • Force 1
  • Conditions
  • Player 3 has suffered exactly 1 death of Cantina
  • Force 1 has suffered exactly 0 deaths of Cave
  • Actions
  • Set deaths of Cantina to 0 for Force 1
  • Give all [Any Unit] owned by Player 9 at Anywhere to Player 3
  • Preserve Trigger

  • ^ And then you make another one for each remaining player. This is designed to be as easy to duplicate as possible, so making six copies of the first one is easy.

    Of course, as with any system, you'd need to add an action to clear "your conditions" from the first trigger before the trigger cycle ends, otherwise it would repeat every cycle.

    As for your timer question, as Wormer said, you'll want to use hyper triggers. They are a critical part of nearly all trigger systems, and should be in every map you make by default.

    Just create the trigger as he wrote it there, with 63 "Wait 0" actions followed by 1 "Preserve Trigger". That is a single hyper trigger.

    You want to have 4 of these hyper triggers (not 3). The difference between 3 and 4 is how long your triggers will run super fast (12 times a second instead of 1 time every 1.5 seconds) without any hiccups. 3 hypers only gives you 6 hours, which is reached all the time, as people go AFK or play solo or are chatting or just take a long time. 4 hypers gives you 16 days, which is not only never going to happen on your map, but it's realistically possible that no one has reached that on any map (but there's always that one guy).

    Also, it's not important to put your hyper triggers at the bottom of the trigger list. It doesn't matter, because you shouldn't be using any other Wait actions in your map.

    Once the hyper triggers are added to your map, your triggers will be running about 12 cycles per second. Timers like the one you described become extremely easy to implement. For a 5 minute timer, you would change it to 300 seconds, and then multiply by 12 cycles per second, to arrive at 3600 trigger cycles.

    To implement a timer, you can do this:

    Trigger
    Players
  • Force 1
  • Conditions
  • Always
  • Actions
  • Add 1 death to Cave-in for Current Player
  • Preserve Trigger

  • ^ This is measuring the number of trigger cycles that pass.

    If you want to use "has been 5 minutes" as a condition, you would need to know how many trigger cycles that equals. Since 12 trigger cycles is equal to 1 second, the result is that 5 minutes is equal to 3600 trigger cycles (as shown earlier).

    Modifying the first trigger from before, this is how you would make it swap every 5 minutes:

    Trigger
    Players
  • Force 1
  • Conditions
  • Current Player has suffered exactly 3600 deaths of Cave-in
  • Force 1 has suffered exactly 0 deaths of Cantina
  • Actions
  • Set deaths of Cantina to 1 for Current Player
  • Set deaths of Cave to 1 for Force 1
  • Preserve Trigger

  • As mentioned earlier, you will need to clear "your condition" (3600 deaths of Cave-in) before the end of the trigger cycle. The action you would use is:

    Trigger
    Players
  • Conditions
  • Actions
  • Set deaths of Cave-in to 0 for Force 1

  • ^ You can add this action to the "Exchange Units" trigger or the "Finish Swap" triggers.

    The last thing to note here is that the Timer trigger must be moved higher than the Start Swap trigger in the trigger list. This is because it's otherwise possible for the first player to not have the highest timer value (like if you do a swap, it runs all the triggers, clears the timer, and then gives Player 7 +1 to his timer). The reason this is such an issue is that it means Player 7 would reach 3600 while everyone else is at 3599, so he'd do the swap by himself (everyone else would end up swapping without him on the next trigger cycle).

    If you have any other questions, just let us know.

    Post has been edited 2 time(s), last time on Dec 16 2013, 2:08 pm by Azrael.




    Dec 17 2013, 3:59 am hobbes Post #6



    So i've worked most of the kinks and did a bit of testing with 2 and 3 players, and it seems to be working now. The only issue now is that when a player is swapped, the workers will stop mining. I was aware that this would happen, but is there any way to prevent this?
    Terran buildings in progress get stopped, units and researches in progress get cancelled, but i know there's nothing i can do about these.

    I attached the current version of the map, in case you guys wanted to look at the trigger setup you've helped me assemble.

    For now i set it up so that the first swap occurs at 5 minutes, with every round thereafter at 3 minutes. Once i test it with a full house, we'll determine if the round time is too much or too little.

    If my friends end up liking this map enough, i'll make an sc2 version, which would probably allow better transition of ownership between players (no halted mining, no cancelled units or research progression). If anybody else feels like doing it, by all means, please do. :)

    Wormer,
    Thanks for pointing out that i forgot to put in the preserve trigger function. Must have slipped my mind.

    Regarding the triggers in Force 4, those were there because i wanted to get them out of the way, but not necessarily delete them, so i rerouted them from force 1 to force 4. I ended up deleting them anyway as i decided not to implement an observer mode.

    I put in the hyper triggers at the bottom of my trigger tree. Thank you.
    I'm using a few wait commands for the sole purpose of audio and text display, and they don't seem to be causing any issues.

    Azrael,
    i'm having a bit of trouble understanding what you wrote and those triggers. Sorry! I'm not quite sure what Cave and Cantina are supposed to represent. :D


    I put the kill count scoreboard because i wanted to encourage players to fight for bragging rights. I can imagine players killing off their own base just before the timer runs out putting the next player in difficulty, possibly in a fatal position. It will probably happen anyway but i'd like to discourage that, and i'm hoping the scoreboard will help.

    If you guys have more suggestions, i'm all ears.

    Attachments:
    (7)Change Places!.scx
    Hits: 0 Size: 625.95kb

    Post has been edited 1 time(s), last time on Dec 17 2013, 4:07 am by hobbes.



    None.

    Dec 17 2013, 4:05 am O)FaRTy1billion[MM] Post #7

    👻 👾 👽 💪

    Cave and Cantina are some unused units that are commonly used for death counter, which are basically used as timers, trigger sequencers, multi-state switches or general-purpose variables.



    TinyMap2 - Latest in map compression! ( 7/09/14 - New build! )
    EUD Action Enabler - Lightweight EUD/EPD support! (ChaosLauncher/MPQDraft support!)
    EUDDB - topic - Help out by adding your EUDs! Or Submit reference files in the References tab!
    MapSketch - New image->map generator!
    EUDTrig - topic - Quickly and easily convert offsets to EUDs! (extended players supported)
    SC2 Map Texture Mask Importer/Exporter - Edit texture placement in an image editor!
    \:farty\: This page has been viewed [img]http://farty1billion.dyndns.org/Clicky.php?img.gif[/img] times!

    Dec 17 2013, 8:32 am hobbes Post #8



    could i use that cave and cantina thing to transfer minerals to player 10/9 and then over to another player?



    None.

    Dec 17 2013, 6:51 pm Azrael Post #9



    If you want the players to swap their minerals, I can come up with a system for that.

    There were 3 units I referenced: "Cantina", "Cave", and "Cave-in". These are the same as any other units, except for the fact that they are never going to die in any map.

    Short version: Just copy the triggers the way they are written and the system will work. No understanding necessary.

    Long version: As Farty said, this is something called a Death Counter. It is another of the most important mapping techniques, alongside hyper triggers. You'll notice my original post says "Cantina DC" and "Cave DC", where the DC means "Death Counter". The way DCs work is very simple, basically the same way as a switch, except with a lot more possible values.

    Every single unit (Marines, Firebats, Zerglings, Photon Cannons, Barracks, Mineral Chunks, Cantinas, Caves, etc) has a death count. You can check the death count with the condition "Deaths" and you can change the death count with the action "Set Deaths". It also measures actual unit deaths, so if you place a Marine on the ground for Player 1, and a Zergling kills it, then the death count for Marine will go up by 1 for Player 1.

    That's why you want to use "unused" units, or any other units that cannot be killed (so the only way their deaths will ever change is if you change it with the "Set Deaths" action). One of the units used most frequently for this is Cantina, and other examples (which immediately follow Cantina in the unit list) are Cave and Cave-in.

    For a full list of units that can't be killed, you can check the Death Counter page which I linked to earlier.

    Post has been edited 3 time(s), last time on Dec 17 2013, 9:12 pm by Azrael.




    Options
      Back to forum
    Please log in to reply to this topic or to report it.
    Members in this topic: None.
    [09:18 pm]
    Ultraviolet -- 🔪🐈
    [12:34 pm]
    NudeRaider -- curiosity kills the cat!
    [06:18 am]
    Sylph-Of-Space -- No complaints here, i'm just curious!
    [2024-5-18. : 11:05 pm]
    Ultraviolet -- :wob:
    [2024-5-18. : 3:55 pm]
    Zoan -- :wob:
    [2024-5-18. : 10:34 am]
    NudeRaider -- SEN doesn't rely on spammers initiate its sleep cycle. It hat fully automated rest and clean-up phases. Please understand that this is necessary for the smooth operation of the site. Thank you.
    [2024-5-18. : 3:45 am]
    Sylph-Of-Space -- Does the shoutbox get disabled when there's spammers?
    [2024-5-17. : 6:47 am]
    NudeRaider -- lil-Inferno
    lil-Inferno shouted: nah
    strong
    [2024-5-17. : 5:41 am]
    Ultraviolet -- 🤔 so inf is in you?
    [2024-5-17. : 4:57 am]
    O)FaRTy1billion[MM] -- my name is mud
    Please log in to shout.


    Members Online: Rawflesh0615