• 0

    posted a message on SC2 Bank Issue

    I'm might be wrong here, but I remember that someone said you have to use explicit values in the parameters of the bank functions.

    So, you can't have BankExists("bankname", i);
    It has to be BankExists("bankname", 1);

    Posted in: Triggers
  • 0

    posted a message on Steal unit buff ability

    So make it triggers + data.
    Repeat the effect using triggers as long as there is at least one buff on the target.

    Posted in: Data
  • 0

    posted a message on So is "Show/Hide Mouse Cursor" just broken now?

    Hi,

    It works for me, however the mouse shows up when I hit "enter" to type in a message.
    When I'm done typing, the mouse is hidden again, but still, it is strange.

     

    Maybe the problem is that you do that on the map initialization, or because you are doing it for (All Players).

     

    Debug - Show Mouse
        Events
            Game - Player Any Player types a chat message containing "-debug show mouse", matching Exactly
        Local Variables
        Conditions
            (Game is running via Manual test) == True
        Actions
            UI - Show the mouse cursor for (Player group((Triggering player))).
    

     

    Debug - Hide Mouse
        Events
            Game - Player Any Player types a chat message containing "-debug hide mouse", matching Exactly
        Local Variables
        Conditions
            (Game is running via Manual test) == True
        Actions
            UI - Hide the mouse cursor for (Player group((Triggering player))).
    

     

    Posted in: Triggers
  • 0

    posted a message on Event not firing? (Unit Enters/Leaves Range of Unit)

    No, that is not how events work.
    You need to specify a unit that is already on the map, or (Any Unit).
    You cannot use (Unit 1 from GrenadeGroup), or a variable or anything similar.

    Something like this: Any Unit Enters a distance of 1.25 from (Any Unit),
    than in conditions you have to check if (Triggering Unit) == <your specific unit>

    Posted in: Triggers
  • 0

    posted a message on [Solved] How to kill or remove unit after a duration?

    Hi there,

    Check behavior called "timed life". Play around with it, you can add it directly to unit types in data editor or add them when you believe is applicable in triggers.

    Regards
    Matic

    Posted in: Triggers
  • 0

    posted a message on Enemy units with dodgeable auto attacks

    Make it weapon instead of ability. I believe that simply pasting launch missile effect into weapon effect will do the job. Of course, actors will have to be aligned too, but that shouldn't be a problem.

    Posted in: Data
  • 0

    posted a message on Build buildings with trigger

    Yeah, its very easy. Just use this:

    CLICK MAP
        Events
            UI - Player Any Player clicks Any mouse button Down.
        Local Variables
        Conditions
        Actions
            Unit - Create 1 Pylon for player 1 at (Point((Mouse X position clicked in the world), (Mouse Y position clicked in the world))) using default facing (Under Construction)
    

    and check attached map.

    Regards
    Matic

    Posted in: Triggers
  • 0

    posted a message on You can submit bug/suggestion for my War3 Mod here

    Hi,

    Great mod Renee!
    I do have two quick questions. Forgive me if this not a right place for posting but I didn't want to create a new thread.

    1.
    How do I remove UpKeep frame?
    I've tried:

    Dialog - Hooks up an existing Label in the standard UI called 
    "UIContainer/FullscreenUpperContainer/ResourcePanel/ResourceFrame/UpkeepLabel"
    Dialog - Hide (Last created dialog item) for (All players)
    

    but it says that upkeep frame is already hooked up and it cannot be done again.
    Also, I can't find any respective action that could help me do that.



    2.
    How do I change UI of the player? For some reason I'm always seeing an Orc UI. Race is selected (Human), also I tried this action:

    Set Player UI Race(1, Human)
    

    but it doesn't do anything (at least I can't see anything).
    I haven't tested the map online tho.


    Thanks!
    Regards
    Matic

    Posted in: Warcraft Modding
  • 0

    posted a message on [Triggers, Data] Reliable Boss Battles (Multiplayer)

    @Hockleberry: Go

    Sure thing Hockleberry!
    I didn't put it there cause to be honest I didn't know how to do it...

    Thanks!

    Posted in: Tutorials
  • 0

    posted a message on [Triggers, Data] Reliable Boss Battles (Multiplayer)

    Thanks for kind words guys!

    @EivindL: Go

    I agree that having dodgeable missiles or something similar really gives that "boss fight feeling". Personally I've learned a lot from OneTwo's tutorial:
    http://www.sc2mapster.com/forums/resources/tutorials/25781-diablo-fireball-spell-tutorial/

    However, I didn't want to focus on abilities. I wanted to show general trigger template that can be used to make sure that boss will do what you want. There are many great ideas for abilities and those contained here are only examples.

    Posted in: Tutorials
  • 0

    posted a message on [Triggers, Data] Reliable Boss Battles (Multiplayer)

    RELIABLE BOSS BATTLES
    (Multiplayer)






    Hi there,

    For sometime now I've been living with a need of giving something back to the community that I've took so much from. This page is great source of various tutorials and I've saved tons of hours finding stuff that I need. I've decided to write a tutorial on how to create boss fight as this is the topic I am really enjoying, and to be honest I didn't find many

    This tutorial will describe how to create a boss fight that will work in multiplayer environment and will be easy to customize. The final effect you can see on the video.
    Let's start.

    1. DATA STUFF


    I don't want to go too deep into data detail, here are few tips that are easy to miss when trying to recreate what I did.

    • Boss Unit must have "Behavior: Response -> No Response" and "Combat: Default Acquire Level -> None" set. First one will make him not responding when attacked, and second one will make him not helping allied units when they are attacked. This will allow us to gain full control over boss unit with triggers.
    • Zergling adds should have "Tactical AI: None". Having there default value can lead to AI handling burrow/unburrow actions and can screw up your battle.
    • To create green acid pool I've used model Floating Creep Pad and set it's tint color in "Actor: Events". Make sure that this color has a label as it may not work when you leave it empty.
    • Rest is all about what you want the boss to do. I believe that all abilities that boss can/will use should be always done in data and only control and AI should be in triggers - but, if you find something difficult to recreate do not hesitate to make abilities triggers driven. Unless you add too much stuff and execute it too often you should be just fine.



    2. PREPARATION


    For each boss that I create, at first I prepare a record that will hold all variables connected to specified boss fight. As you can easily notice it is divided to two parts: Generic and Specific. Generic is something that is applicable to every boss that is created with this method. For example, you can be sure that every boss should have marker that will be telling if it is engaged. In specific part we will put all stuff connected to boss abilities that is valid only for this specific boss. Unfortunately there is no "inheritance" mechanism like in C++ or Java, but it is not a big deal. We can live with just repeating this kind of a generic stuff.

    Of course, this is not very strict. If you need f.e. three variables to hold three different boss units you can easily change these.

    BOSS - ACID ROACH

        VARIABLES
            // ------- ------- ------- -------
            // GENERIC
            // These variables are common and should be in all boss records
            // ------- ------- ------- -------
            // array of players that are active on this boss
            active = False <Boolean<maxPlayers>>
            // is boss engaged
            engaged = False <Boolean>
            // is boss alive
            alive = False <Boolean>
            // unit that represents the boss
            unit = No Unit <Unit>
            // variable containing players that are fighting the boss
            // note that this group might be different than (Active Hero Players)
            // as not everyone might choose to engage the boss
            playersFighting = (Empty player group) <Player Group>
            // good practice is to provide text tips to players
            // all boss info will be in this variable
            tip = No Text <Text>
            // at the begining of the fight we might want to introduce
            // boss somehow
            talks = True <Boolean>
            // phase at which boss is (generic)
            phase = 0 <Integer>
            // wait timer for next boss action (generic)
            wait = 0.0 <Real>
            // gate to the boss
            gate = No Unit <Unit>
            // ------- -------
    
            // ------- ------- ------- -------
            // BOSS SPECIFIC
            // These variables are only for this particular boss
            // ------- ------- ------- -------
            // phase of boss (ability)
            burrowPhase = 0 <Integer>
            burrowUnits = (Empty unit group) <Unit Group>
            // number of lings that will be unburrowed
            unburrowLingsNumber = 0 <Integer>
            // ------- -------
    



    3. ACTIVATION

    Activation is the semi-starting phase. It launches when one of the players enters boss area. This will allow you to make all necessary setups before fight starts. It is used for following things:

    • creating revealers on whole boss area
    • showing a boss bar
    • changing the camera
    • displaying a tip or description about the boss
    • playing intro sequence for the boss

    Fight didn't start yet, but we can prepare players and show them what they are about to face. It is still possible that after reading description they might want to run away so we will leave that possibility as well.

    Area setup looks like this:

    http://www.sc2mapster.com/media/attachments/48/913/boss_area.jpg

    As you can notice, Boss.AcidRoach.Activate is inside of Boss.AcidRoach.Area. Also, make sure that it won't be possible to attack boss without going through "Activate" area first. While this script should handle such situation just fine, you don't want that.


    ACID ROACH - ACTIVATE

        EVENTS
            // player entered area that is smaller then whole arena
            Unit - Any Unit Enters Boss.AcidRoach.Activate
    
        LOCAL VARIABLES
    
        CONDITIONS
            // activate should fire before boss is engaged
            // if someone won't be fast enough to enter this region together with the rest,
            // we will check for fighting players again when boss is attacked
            bossAcidRoach.engaged == False
            // boss must be alive
            bossAcidRoach.alive == True
            // player that entered is hero player
            ((Owner of (Triggering unit)) is in (Active Hero Players)) == True
            // this player is not active on this boss yet
            bossAcidRoach.active[(Triggering player)] == False
    
        ACTIONS
            // -------
            Debug - Debug Text((Combine ("DEBUG # ", "Boss Acid Roach - Activate, Player:...", (Text((Triggering player))))))
            // -------
            // activate player on boss
            Variable - Set bossAcidRoach.active[(Triggering player)] = True
            // -------
            // create revealers for this particular player
            Visibility - Create Revealers for player group(2, (Player group((Triggering player))), Boss.AcidRoach.Area)
            // -------
            // check if there is an intro for this fight
            General - If (Conditions) then do (Actions) else do (Actions)
    
                If
                    bossAcidRoach.talks == True
                Then
                    // ------- ------- -------
                    Debug - Debug Text((Combine ("DEBUG # ", "Boss Acid Roach - Intro Playing")))
                    // we won't bother players with this intro again
                    Variable - Set bossAcidRoach.talks = False
                    // find all players for playing the intro
                    // it won't show for the rest but this what happens when they are lazy
                    Variable - Set bossAcidRoach.playersFighting = (Players Having Units in Region(Boss.AcidRoach.Area, (Active Hero Players)))
                    // make sure fight won't start yet
                    Unit - Make bossAcidRoach.unit Invulnerable
                    // ------- ------- -------
                    // play intro
                    Camera - Apply Camera 001 for bossAcidRoach.playersFighting over 1.0 seconds
                    General - Wait 1.0 Game Time seconds
                    Camera - Apply Camera 002 for bossAcidRoach.playersFighting over 6.0 seconds
                    General - Wait 2.0 Game Time seconds
                    Sound - Play Mutalisk_Pissed for bossAcidRoach.playersFighting on bossAcidRoach.unit with Z offset 0.0 (at 300.0% volume, skip the first 0.0 seconds)
                    Animation - Play Fidget animation for (Actor for bossAcidRoach.unit) as Default, using No Options options and Default Time blend time
                    UI - Display "ACID ROACH: <frightening roar>" for bossAcidRoach.playersFighting to Chat area
                    General - Wait 6.0 Game Time seconds
                    Camera - Apply (Default game camera) for bossAcidRoach.playersFighting over 2.0 seconds (No Target)
                    General - Wait 4.0 Game Time seconds
                    // ------- ------- -------
                    // make boss attackable again
                    Unit - Make bossAcidRoach.unit Vulnerable
                Else
                    // -------
                    Debug - Debug Text((Combine ("DEBUG # ", "Boss Acid Roach - Intro Skip")))
                    // -------
    
            // -------
            // show boss bar
            // player number is used as Boss Bar ID to make it easier
            UI - Display boss bar (Triggering player) with title "ACID ROACH", portrait Assets\Textures\btn-unit-zerg-primalroach.dds and maximum value 100 for (Player group((Triggering player)))
            UI - Set boss bar (Triggering player) boss to bossAcidRoach.unit (Do refresh the boss bar)
            // -------
            // this also good place to change the camera if you want
            // to have different view on particular fight
            // just remember to change it back to (Default Game Camera) when fight ends
            // -------
    



    When player will decide to not fight the boss we must handle this situation as well:

    • destroy revealers
    • hide a boss bar
    • revert the camera

    Note that deactivation happens when player leave Boss.AcidRoach.Area, not the activation area.


    ACID ROACH - DEACTIVATE

        EVENTS
            Unit - Any Unit Leaves Boss.AcidRoach.Area
    
        LOCAL VARIABLES
    
        CONDITIONS
            // deactivate can only happen before boss is engaged
            bossAcidRoach.engaged == False
            // if boss is not alive this means that fight already ended
            // so no need to deactivate
            bossAcidRoach.alive == True
            // player that left is hero player
            ((Owner of (Triggering unit)) is in (Active Hero Players)) == True
            // obviously player must be active on boss
            // before we deactivate him
            bossAcidRoach.active[(Triggering player)] == True
            // no other unit of this player is left on fighting area
            (Number of Living units in (Any units in Boss.AcidRoach.Area owned by player (Triggering player) matching Excluded: Structure, Missile, Item, Dead, Hidden, Invulnerable, with at most Any Amount)) == 0
        
        ACTIONS
            // -------
            Debug - Debug Text((Combine ("DEBUG # ", "Boss Acid Roach - Deactivate, Playe...", (Text((Triggering player))))))
            // -------
            // deactivate player on boss
            Variable - Set bossAcidRoach.active[(Triggering player)] = False
            // -----
            // hide boss bar
            UI - Hide boss bar (Triggering player)
            UI - Set boss bar (Triggering player) boss to No Unit (Do refresh the boss bar)
            // -------
            // destroy revealers
            Visibility - Destroy Revealers for player group(2, (Player group((Triggering player))))
            // -------
    





    4. ENGAGE

    Engage is the real start phase. It is important to remember that all variables should be set here. Usually I tend to reset them when fight ends and set them again here, even though it is clearly redundant. When boss will be attacked, we will check again for all players in the fighting area and "activate" them if necessary. This is to cover situations when not all players were fast enough to reach activation area. Also, note that controller won't have any event that it will react to. It will be run from here, only after everything is initialized properly.

    ACID ROACH - ENGAGE

        EVENTS
            // using this event instead of "unit is attacked" is better
            // because players can also use specific abilities to start the fight
            // which are not always registred as an attack
            Unit - Any Unit takes Fatal or Non-Fatal Any damage (from Any effects)
    
        LOCAL VARIABLES
    
        CONDITIONS
            bossAcidRoach.unit == (Triggering unit)
            bossAcidRoach.engaged == False
            bossAcidRoach.alive == True
    
        ACTIONS
            // -------
            Debug - Debug Text((Combine ("DEBUG # ", "Boss Acid Roach - Engaged...")))
            // -------
            // mark as engaged
            Variable - Set bossAcidRoach.engaged = True
            // start with phase 1
            Variable - Set bossAcidRoach.phase = 1
            // collect player group for whole area
            Variable - Set bossAcidRoach.playersFighting = (Players Having Units in Region(Boss.AcidRoach.Area, (Active Hero Players)))
            // -------
            // turn on Zergling AI trigger, it will be needed only during this fight
            Trigger - Turn Acid Roach - Zergling Adds AI On
            // -------
            // set fight specific variables
            Variable - Set bossAcidRoach.burrowPhase = 0
            // -------
            // for all players that are in area but wasn't fast enough to reach activate area
            // let's activate the fight (no intro obviously)
            Player Group - Pick each player in bossAcidRoach.playersFighting and do (Actions)
                Actions
                    // -------
                    // wait with revive till fight ends
                    Variable - Set players[(Picked player)].haltRevive = True
                    // -------
                    // activate rest of the players that are in the fighting area
                    // and create revealers and boss bar for them
                    General - If (Conditions) then do (Actions) else do (Actions)
                        If
                            bossAcidRoach.active[(Picked player)] == False
                        Then
                            // -------
                            Debug - Debug Text((Combine ("DEBUG # ", "Boss Acid Roach - Force activate, P...", (Text((Picked player))))))
                            // -------
                            Variable - Set bossAcidRoach.active[(Picked player)] = True
                            Visibility - Create Revealers for player group(2, (Player group((Picked player))), Boss.AcidRoach.Area)
                            // when copying from ACTIVATE trigger make sure you change (Triggering Player) to (Picked Player) in 3 places here
                            UI - Display boss bar (Picked player) with title "ACID ROACH", portrait Assets\Textures\btn-unit-zerg-primalroach.dds and maximum value 100 for (Player group((Picked player)))
                            UI - Set boss bar (Picked player) boss to bossAcidRoach.unit (Do refresh the boss bar)
                        Else
    
            // -------
            // sounds for effect
            Sound - Play Roach_Ready for bossAcidRoach.playersFighting on bossAcidRoach.unit with Z offset 0.0 (at 300.0% volume, skip the first 0.0 seconds)
            // -------
            // close area gate
            Unit - Order bossAcidRoach.gate to ( Close Gate) (Replace Existing Orders)
            // -------
            // run the controler
            Trigger - Run Acid Roach - Controler  (Check Conditions, Don't Wait until it finishes)
            // -------
    



    5. CONTROLLER

    Controller is where the magic happens. Boss unit is handled completely by the script. No data, nor automatic AI should be used as it is very hard to predict what will happen. The whole idea is based on having so called "idle loop". During this time in the loop, boss will use his default attack and follow closest enemy (or whatever attack-move command will order him to follow). When the "idle loop" will end, depending on boss phase held in proper variable, he will use one of his deadly abilities. Also, it is possible to implement abilities that will launch depending on current boss HP. To do that we will add checks inside of the loop. When specific ability is done, we will set loop timer to desired value, change boss phase and return to the loop itself. It is very simple and gives many possibilities for customization.

    ACID ROACH - CONTROLER

        EVENTS
    
        LOCAL VARIABLES
    
        CONDITIONS
    
        ACTION
            // -------
            Debug - Debug Text((Combine ("DEBUG # ", "Boss Acid Roach - Controler Starts")))
            // -------
            // set initial wait to 10 seconds
            Variable - Set bossAcidRoach.wait = 10.0
            // -------
            // controler will run only till boss engaged
            // this trigger will be stopped anyway but just for making sure it won't go forever
            General - While (Conditions) are true, do (Actions)
                Conditions
                    bossAcidRoach.engaged == True
                Actions
                    // ------- ------- -------
                    // IDLE LOOP
                    // this loop will go while "wait" variable is bigger than 0
                    // meaning that boss is not using any abilities yet
                    // ------- ------- -------
                    Debug - Debug Text((Combine ("DEBUG # ", "Boss Acid Roach - Idle Loop Starts,...", (Text(bossAcidRoach.wait) with 2 decimal places))))
                    // ------- ------- -------
    
                    General - While (Conditions) are true, do (Actions)
                        Conditions
                            bossAcidRoach.wait > 0.0
                        Actions
                            // ------- ------- -------
                            // ------- ------- -------
                            // ------- ------- -------
                            // ------- ------- -------
                            // HEALTH PERCENT ABILITIES
                            // these kind of abilites can be started when idle is bigger than 0
                            // ------- ------- -------
    
                            // BURROWED SWARMLINGS
                            // this ability will fire on 75%, 50% and 25% boss hp
    
                            General - If (Conditions) then do (Actions) else do (Actions)
                                If
                                    Or
                                        Conditions
                                            And
                                                Conditions
                                                    bossAcidRoach.burrowPhase == 0
                                                    (bossAcidRoach.unit Life (Percent) (Current)) <= 75.0
                                            And
                                                Conditions
                                                    bossAcidRoach.burrowPhase == 1
                                                    (bossAcidRoach.unit Life (Percent) (Current)) <= 50.0
                                            And
                                                Conditions
                                                    bossAcidRoach.burrowPhase == 2
                                                    (bossAcidRoach.unit Life (Percent) (Current)) <= 25.0
                                Then
                                    // ------- ------- -------
                                    Debug - Debug Text((Combine ("DEBUG # ", "Boss Acid Roach - Burrow Phase: ", (Text(bossAcidRoach.burrowPhase)))))
                                    // ------- ------- -------
                                    // make sure that given phase will launch only once
                                    Variable - Modify bossAcidRoach.burrowPhase: + 1
                                    // ------- ------- -------
                                    Unit - Order bossAcidRoach.unit to (Acid Roach - Burrow) (Replace Existing Orders)
                                    // ------- ------- -------
                                    General - Switch (Actions) depending on settings.difficulty
                                        Cases
                                            General - If (1)
                                                Actions
                                                    General - Wait 8.0 Game Time seconds
                                                    Variable - Set bossAcidRoach.unburrowLingsNumber = 8
                                            General - If (2)
                                                Actions
                                                    General - Wait 8.0 Game Time seconds
                                                    Variable - Set bossAcidRoach.unburrowLingsNumber = 10
                                            General - If (3)
                                                Actions
                                                    General - Wait 6.0 Game Time seconds
                                                    Variable - Set bossAcidRoach.unburrowLingsNumber = 10
                                        Default
                                            General - Wait 8.0 Game Time seconds
                                            Variable - Set bossAcidRoach.unburrowLingsNumber = 10
                                    // ------- ------- -------
                                    General - Repeat (Actions) bossAcidRoach.unburrowLingsNumber times
                                        Actions
                                            Unit - Create 1 Boss - Zergling (Add Burrowed) for player 5 at (Random point in Boss.AcidRoach.ZerglingAddSpawn) using default facing (No Options)
                                            Unit Group - Add (Last created unit) to bossAcidRoach.burrowUnits
                                            Unit - Order (Last created unit) to (Zergling Add - Unburrow) (After Existing Orders)
                                    // ------- ------- -------
                                    // give player time to clean up zergling adds
                                    General - Wait 20.0 Game Time seconds
                                    // ------- ------- -------
                                    // don't forget to unburrow boss
                                    Unit - Order bossAcidRoach.unit to (Acid Roach - Unburrow) (Replace Existing Orders)
                                    // ------- ------- -------
                                    // return to idle loop with new wait
                                    Variable - Set bossAcidRoach.wait = 10.0
                                    // ------- ------- -------
                                Else
    
                            // ------- ------- -------
                            // ------- ------- -------
                            // ------- ------- -------
                            // ------- ------- -------
                            // IDLE CHECK
                            // ------- ------- -------
                            General - If (Conditions) then do (Actions) else do (Actions)
                                If
                                    (bossAcidRoach.unit is in (Idle Units for player 5)) == True
                                    (Number of Living units in (Units in Boss.AcidRoach.Area having alliance Enemy with player 5 matching Required: Visible; Excluded: Structure, Missile, Item, Dead, Hidden, Invulnerable, with at most Any Amount)) > 0
                                Then
                                    Debug - Debug Text((Combine ("DEBUG # ", "Boss Acid Roach - Order: Attack")))
                                    Unit - Order bossAcidRoach.unit to ( Attack targeting (Position of (Random Living unit from (Units in Boss.AcidRoach.Area having alliance Enemy with player 7 matching Required: Ground, Visible; Excluded: Player, Ally, Neutral, Structure, Missile, Item, Stasis, Dead, Hidden, Invulnerable, with at most Any Amount)))) (Replace Existing Orders)
                                Else
                            // ------- ------- -------
                            // ------- ------- -------
                            // ------- ------- -------
                            // ------- ------- -------
                            // TIMER
                            // ------- ------- -------
                            General - Wait 0.25 Game Time seconds
                            Variable - Modify bossAcidRoach.wait: - 0.25
                            // ------- ------- -------
    
                    // ------- ------- -------
                    // ------- ------- -------
                    // ------- ------- -------
                    // PHASE ABILITIES
                    // phase abilities are the ones that fire when "wait" is equal to 0.0
                    // ------- ------- -------
    
                    General - Switch (Actions) depending on bossAcidRoach.phase
                        Cases
    
                            // ACID SPIT
                            General - If (1)
                                Actions
                                    // -------
                                    // it is good practice to give some kind of warning for players
                                    // random text works very well and adding specific sounds allows
                                    // players to feel the rythm of the fight and adapt more easily
                                    Send transmission (advanced)  to (All players) from (bossAcidRoach.unit with Flash (Do Not override portrait) playing Talk) playing RoachPrimal_Pissed with name "ACID ROACH: " and message "<frightening roar>" using No Portrait with "" playing Talk (Set To 4.0 seconds, Don't Wait until it finishes)
                                    Sound - Play Mutalisk_Pissed for bossAcidRoach.playersFighting on bossAcidRoach.unit with Z offset 0.0 (at 300.0% volume, skip the first 0.0 seconds)
                                    UI - Display "ACID ROACH: <frightening roar>" for bossAcidRoach.playersFighting to Chat area
                                    // -------
                                    // give order to boss to perform ability
                                    // we will choose furthest unit from boss location
                                    Debug - Debug Text((Combine ("DEBUG # ", "Boss Acid Roach - Order: Acid Spit")))
                                    Unit - Order bossAcidRoach.unit to (Acid Roach - Acid Roach - Acid Spit targeting (Position of (Random Living unit from (Units in Boss.AcidRoach.Area having alliance Enemy with player 5 matching Excluded: Structure, Missile, Item, Dead, Hidden, Invulnerable, with at most Any Amount)))) (Replace Existing Orders)
                                    Unit - Order bossAcidRoach.unit to (Acid Roach - Acid Roach - Acid Spit targeting (Position of (Furthest Unit From Point((Position of bossAcidRoach.unit), (Units in Boss.AcidRoach.Area having alliance Enemy with player 7 matching Excluded: Structure, Missile, Item, Dead, Hidden, Invulnerable, with at most Any Amount))))) (Replace Existing Orders)
                                    // -------
                                    // allow boss to finish his ability
                                    // even if it will take longer it is no problem as
                                    // we will still go back to IDLE LOOP
                                    General - Wait 6.0 Game Time seconds
                                    // -------
                                    // set IDLE LOOP time and next phase
                                    Variable - Set bossAcidRoach.wait = 10.0
                                    Variable - Set bossAcidRoach.phase = 1
                                    // -------
    
                            General - If (2)
                                Actions
                                    // -------
                                    // other ability could be used here
                                    // also it is possible to have here some switch random action to choose one of abilities
                                    General - Switch (Actions) depending on (Random integer between 2 and 4)
                                        Cases
                                            General - If (2)
                                                Actions
                                                    // do ability 2
                                            General - If (3)
                                                Actions
                                                    // do ability 3
                                            General - If (4)
                                                Actions
                                                    // do ability 4
                                        Default
                                    // -------
                        Default
                    // ------- ------- -------
            // -------
    



    6. END FIGHT

    Boss fight can end two ways. Either players defeat the boss, or boss kill all players.
    Simple as that.

    ACID ROACH - PLAYERS DEFEATED

        EVENTS
            Unit - Any Unit dies
    
        LOCAL VARIABLES
    
        CONDITIONS
            // only check if we are fighting this particular boss
            bossAcidRoach.engaged == True
            // player that died is hero player
            ((Triggering player) is in (Active Hero Players)) == True
            // player that died was fighting boss
            ((Triggering player) is in bossAcidRoach.playersFighting) == True
            // no one else left fighting the boss
            // with exception of:
            // - invunerable - doors at entrance
            // - items - if your game features items and inventory, players would be able to place them on the ground and bug out the fight
            // - structures - all special stuff that is summoned or placed by players (bunkers/ turrets / mines) is also not counting
            (Number of Living units in (Units in Boss.AcidRoach.Area having alliance Enemy with player 5 matching Excluded: Structure, Missile, Item, Dead, Hidden, Invulnerable, Summoned, with at most Any Amount)) == 0
        
        ACTIONS
            // -------
            Debug - Debug Text((Combine ("DEBUG # ", "Boss Acid Roach - Players Defeated")))
            // -------
            // reset all important variables
            Variable - Set bossAcidRoach.engaged = False
            Variable - Set bossAcidRoach.phase = 0
            // -------
            // turn off Zergling AI trigger to reduce number of calls
            Trigger - Turn Acid Roach - Zergling Adds AI Off
            // -------
            // stop controler immiediatly
            Trigger - Stop all instances of Acid Roach - Controler
            // -------
            // in case of some special ability of the heroes (like f.e. planting mines)
            // it is good practice to make boss invunerable at this point
            // fight is already over and if something would now hit boss and kill him
            // that could cause other trigger (Boss Defeated) to fire and
            // everything to break down
            Unit - Add 1 Invulnerable Hidden (Hit) to bossAcidRoach.unit from player 7
            // we order boss to go stop all his movement and other actions,
            // we will order him to move back to his starting point later on
            Unit - Order bossAcidRoach.unit to ( Stop) (Replace Existing Orders)
            // -------
            // wait for better effect
            General - Wait 2.0 Game Time seconds
            // -------
            // kill all adds and other stuff that might be leftover from the fight
            Unit Group - Pick each unit in (Boss - Acid Roach - Acid Lake (Placed Unit) units in Boss.AcidRoach.Area owned by player Any Player matching Excluded: Dead, with at most Any Amount) and do (Actions)
                Actions
                    Unit - Kill (Picked unit)
            Unit Group - Pick each unit in bossAcidRoach.burrowUnits and do (Actions)
                Actions
                    Unit - Kill (Picked unit)
            Unit Group - Pick each unit in (Boss - Zergling (Add Burrowed) units in Boss.AcidRoach.Area owned by player 5 matching Excluded: Dead, with at most Any Amount) and do (Actions)
                Actions
                    Unit - Kill (Picked unit)
            Unit Group - Pick each unit in (Any units in Boss.AcidRoach.Area owned by player Any Player matching Required: Structure; Excluded: Missile, Item, Dead, Invulnerable, with at most Any Amount) and do (Actions)
                Actions
                    Unit - Kill (Picked unit)
            Unit Group - Remove all units from bossAcidRoach.burrowUnits
            // -------
            // order boss to move at his starting point and turn towards entrance
            Unit - Order bossAcidRoach.unit to (Acid Roach - Unburrow) (Replace Existing Orders)
            Unit - Order bossAcidRoach.unit to ( Move targeting Boss.AcidRoach.Start) (After Existing Orders)
            Unit - Order bossAcidRoach.unit to ( Turn targeting (Boss.AcidRoach.Start offset by 1.0 towards 270.0 degrees)) (After Existing Orders)
            // -------
            // reset players activity, destroy revealers and hide boss bars
            Visibility - Destroy Revealers for player group(2, bossAcidRoach.playersFighting)
            Player Group - Pick each player in bossAcidRoach.playersFighting and do (Actions)
                Actions
                    Variable - Set players[(Picked player)].haltRevive = False
                    Variable - Set bossAcidRoach.active[(Picked player)] = False
                    UI - Hide boss bar (Picked player)
                    UI - Set boss bar (Picked player) boss to No Unit (Do refresh the boss bar)
            //-------
            // wait for better effect
            General - Wait 4.0 Game Time seconds
            // -------
            // open boss doors
            Unit - Order bossAcidRoach.gate to ( Open Gate) (Replace Existing Orders)
            // -------
            // remove invunerability and reset boss health
            // boss is ready to fight again
            Unit - Remove 1 Invulnerable Hidden (Hit) from bossAcidRoach.unit from player 7
            Unit - Set bossAcidRoach.unit Life (Percent) to 100.0
            Unit - Set bossAcidRoach.unit Shields (Percent) to 100.0
            // -------
    

    ACID ROACH - BOSS DEFEATED

        EVENTS
            Unit - Any Unit dies
    
        LOCAL VARIABLES
    
        CONDITIONS
            // good practice is not to check anything else here
            // in case anything bugs out, players still will be able to complete
            // the fight just by killing the boss unit
            bossAcidRoach.unit == (Triggering unit)
    
        ACTIONS
            // -------
            Debug - Debug Text((Combine ("DEBUG # ", "Boss Acid Roach - Boss Defeated")))
            // -------
            // reset all important variables
            Variable - Set bossAcidRoach.alive = False
            Variable - Set bossAcidRoach.engaged = False
            Variable - Set bossAcidRoach.phase = 100
            // -------
            // turn off Zergling AI trigger to reduce number of calls
            Trigger - Turn Acid Roach - Zergling Adds AI Off
            // -------
            // stop controler immiediatly
            Trigger - Stop all instances of Acid Roach - Controler
            // -------
            // wait for better effect
            General - Wait 2.0 Game Time seconds
            // -------
            // remove all stuff that might have been summoned by the boss
            Unit Group - Pick each unit in (Boss - Acid Roach - Acid Lake (Placed Unit) units in Boss.AcidRoach.Area owned by player Any Player matching Excluded: Dead, with at most Any Amount) and do (Actions)
                Actions
                    Unit - Remove All Acid Roach - Acid Lake (Start Shrink Visual) from (Picked unit)
            Unit Group - Pick each unit in bossAcidRoach.burrowUnits and do (Actions)
                Actions
                    Unit - Kill (Picked unit)
            // -------
            // wait for better effect
            General - Wait 3.0 Game Time seconds
            // -------
            // additional removal due to visuals
            Unit Group - Pick each unit in (Boss - Acid Roach - Acid Lake (Placed Unit) units in Boss.AcidRoach.Area owned by player Any Player matching Excluded: Dead, with at most Any Amount) and do (Actions)
                Actions
                    Unit - Kill (Picked unit)
            // -------
            // reset players activity, destroy revealers and hide boss bars
            Visibility - Destroy Revealers for player group(2, bossAcidRoach.playersFighting)
            Player Group - Pick each player in bossAcidRoach.playersFighting and do (Actions)
                Actions
                    Variable - Set bossAcidRoach.active[(Picked player)] = False
                    UI - Hide boss bar (Picked player)
                    UI - Set boss bar (Picked player) boss to No Unit (Do refresh the boss bar)
            // -------
            // open boss doors
            Unit - Order bossAcidRoach.gate to ( Open Gate) (Replace Existing Orders)
            // -------
            // show victory message
            UI - Display "ACID ROACH DEFEATED!" for bossAcidRoach.playersFighting to Directive area
            // -------
            General - Wait 10.0 Game Time seconds
            // -------
            // remove victory message
            UI - Clear Directive Messages for bossAcidRoach.playersFighting
            // -------
    



    7. TIPS


    • Never use "Break" action in Pick Each Player, Pick Each Unit, Pick Each Integer loops. This can lead to very hard to find bugs.
    • Not sure if this is true but just in case never use (Triggering ...) in a trigger after you had a "Wait" action. Other trigger might fire when you are waiting and the value will be overwritten.





    Okay, so, this is it.
    As usual you can find the map in the attachment. I know there are other sources to learn from (like campaign fight with Archangel, or three Zerus bosses) but they are not really applicable to multiplayer environment. I'm not claiming this is BEST METHOD EVER - it is just something that I came up with during my adventure with editor. F.e. I'm still wondering how SCU is handling boss battles, do they have similar template and just customize it every time? That would be cool to know.

    Anyway, I hope you will like it and someone will find it actually useful.


    Thank you
    Regards
    Matic

    Posted in: Tutorials
  • 0

    posted a message on Blue, red and yellow square on terrain

    They are simply map boundaries (yellow) and camera boundaries (blue). Map bound means that units won't be able to get past it, and camera bound will block camera. You can modify them in Map->Map Bounds, and to show/hide you can use hotkey 'O'.

    No idea about red squares but maybe that was just pathing (hotkey 'H' and 'shift+H' to see it).

    Regards
    Matic

    Posted in: Terrain
  • 0

    posted a message on "Boss Battle" basics? Tutorial?

    I'm not sure when I will end, this or next week probably. However, the map is finished and only text part of the tutorial left. I guess the triggers are pretty well commented so you should have no trouble digging through it.

    You can find the map attached to this post. Let me know what do you think and in case you have any additional question I will gladly answer them. Just a note, I don't claim this is a best method ever, but just something that I came up with during work on my maps.

    Regards
    Matic

    Posted in: Data
  • 0

    posted a message on "Boss Battle" basics? Tutorial?

    Hello there,

    I'm actually working on tutorial called "Reliable Boss Fights".
    I wouldn't call it "raid style" but I believe the method itself can be easily scaled depending on what you need. It covers four main phases which I call: Activate, Engage, Control (AI), End Fight. Creating boss fight might seem simple but I found out it is harder than it looks, especially in multiplayer environment. There are many things that can go wrong when players start to mess with the map and won't play it as they should.
    Also, this tutorial is very much focused on triggers, not data stuff (only boss abilities are in data). All AI is in triggers, but I wouldn't worry about trigger lag, there are ways to reduce it, as well as, in my opinion, it doesn't have such big impact.

    Let me know if you are interested, I can send this map to you or upload it somewhere before I finish the tutorial.

    Regards
    Matic

    Posted in: Data
  • 0

    posted a message on Sound at Initialization

    Hi there,

    Maybe it is "ambience" that you are missing?
    These two actions should do the trick:

            Sound - Pause Music soundtrack for (All players) (Immediately)
            Sound - Pause Ambience soundtrack for (All players) (Immediately)
    


    Regards
    Matic

    Posted in: Triggers
  • To post a comment, please or register a new account.