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))).
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>
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.
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.
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.
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 bossactive=False<Boolean<maxPlayers>>// is boss engagedengaged=False<Boolean>// is boss alivealive=False<Boolean>// unit that represents the bossunit=NoUnit<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 bossplayersFighting=(Emptyplayergroup)<PlayerGroup>// good practice is to provide text tips to players// all boss info will be in this variabletip=NoText<Text>// at the begining of the fight we might want to introduce// boss somehowtalks=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 bossgate=NoUnit<Unit>// ------- -------// ------- ------- ------- -------// BOSS SPECIFIC// These variables are only for this particular boss// ------- ------- ------- -------// phase of boss (ability)burrowPhase=0<Integer>burrowUnits=(Emptyunitgroup)<UnitGroup>// number of lings that will be unburrowedunburrowLingsNumber=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:
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 arenaUnit-AnyUnitEntersBoss.AcidRoach.ActivateLOCALVARIABLESCONDITIONS// 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 attackedbossAcidRoach.engaged==False// boss must be alivebossAcidRoach.alive==True// player that entered is hero player((Ownerof(Triggeringunit))isin(ActiveHeroPlayers))==True// this player is not active on this boss yetbossAcidRoach.active[(Triggeringplayer)]==FalseACTIONS// -------Debug-DebugText((Combine("DEBUG # ","Boss Acid Roach - Activate, Player:...",(Text((Triggeringplayer))))))// -------// activate player on bossVariable-SetbossAcidRoach.active[(Triggeringplayer)]=True// -------// create revealers for this particular playerVisibility-CreateRevealersforplayergroup(2,(Playergroup((Triggeringplayer))),Boss.AcidRoach.Area)// -------// check if there is an intro for this fightGeneral-If(Conditions)thendo(Actions)elsedo(Actions)IfbossAcidRoach.talks==TrueThen// ------- ------- -------Debug-DebugText((Combine("DEBUG # ","Boss Acid Roach - Intro Playing")))// we won't bother players with this intro againVariable-SetbossAcidRoach.talks=False// find all players for playing the intro// it won't show for the rest but this what happens when they are lazyVariable-SetbossAcidRoach.playersFighting=(PlayersHavingUnitsinRegion(Boss.AcidRoach.Area,(ActiveHeroPlayers)))// make sure fight won't start yetUnit-MakebossAcidRoach.unitInvulnerable// ------- ------- -------// play introCamera-ApplyCamera001forbossAcidRoach.playersFightingover1.0secondsGeneral-Wait1.0GameTimesecondsCamera-ApplyCamera002forbossAcidRoach.playersFightingover6.0secondsGeneral-Wait2.0GameTimesecondsSound-PlayMutalisk_PissedforbossAcidRoach.playersFightingonbossAcidRoach.unitwithZoffset0.0(at300.0%volume,skipthefirst0.0seconds)Animation-PlayFidgetanimationfor(ActorforbossAcidRoach.unit)asDefault,usingNoOptionsoptionsandDefaultTimeblendtimeUI-Display"ACID ROACH: <frightening roar>"forbossAcidRoach.playersFightingtoChatareaGeneral-Wait6.0GameTimesecondsCamera-Apply(Defaultgamecamera)forbossAcidRoach.playersFightingover2.0seconds(NoTarget)General-Wait4.0GameTimeseconds// ------- ------- -------// make boss attackable againUnit-MakebossAcidRoach.unitVulnerableElse// -------Debug-DebugText((Combine("DEBUG # ","Boss Acid Roach - Intro Skip")))// -------// -------// show boss bar// player number is used as Boss Bar ID to make it easierUI-Displaybossbar(Triggeringplayer)withtitle"ACID ROACH",portraitAssets\Textures\btn-unit-zerg-primalroach.ddsandmaximumvalue100for(Playergroup((Triggeringplayer)))UI-Setbossbar(Triggeringplayer)bosstobossAcidRoach.unit(Dorefreshthebossbar)// -------// 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
EVENTSUnit-AnyUnitLeavesBoss.AcidRoach.AreaLOCALVARIABLESCONDITIONS// deactivate can only happen before boss is engagedbossAcidRoach.engaged==False// if boss is not alive this means that fight already ended// so no need to deactivatebossAcidRoach.alive==True// player that left is hero player((Ownerof(Triggeringunit))isin(ActiveHeroPlayers))==True// obviously player must be active on boss// before we deactivate himbossAcidRoach.active[(Triggeringplayer)]==True// no other unit of this player is left on fighting area(NumberofLivingunitsin(AnyunitsinBoss.AcidRoach.Areaownedbyplayer(Triggeringplayer)matchingExcluded:Structure,Missile,Item,Dead,Hidden,Invulnerable,withatmostAnyAmount))==0ACTIONS// -------Debug-DebugText((Combine("DEBUG # ","Boss Acid Roach - Deactivate, Playe...",(Text((Triggeringplayer))))))// -------// deactivate player on bossVariable-SetbossAcidRoach.active[(Triggeringplayer)]=False// -----// hide boss barUI-Hidebossbar(Triggeringplayer)UI-Setbossbar(Triggeringplayer)bosstoNoUnit(Dorefreshthebossbar)// -------// destroy revealersVisibility-DestroyRevealersforplayergroup(2,(Playergroup((Triggeringplayer))))// -------
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 attackUnit-AnyUnittakesFatalorNon-FatalAnydamage(fromAnyeffects)LOCALVARIABLESCONDITIONSbossAcidRoach.unit==(Triggeringunit)bossAcidRoach.engaged==FalsebossAcidRoach.alive==TrueACTIONS// -------Debug-DebugText((Combine("DEBUG # ","Boss Acid Roach - Engaged...")))// -------// mark as engagedVariable-SetbossAcidRoach.engaged=True// start with phase 1Variable-SetbossAcidRoach.phase=1// collect player group for whole areaVariable-SetbossAcidRoach.playersFighting=(PlayersHavingUnitsinRegion(Boss.AcidRoach.Area,(ActiveHeroPlayers)))// -------// turn on Zergling AI trigger, it will be needed only during this fightTrigger-TurnAcidRoach-ZerglingAddsAIOn// -------// set fight specific variablesVariable-SetbossAcidRoach.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)PlayerGroup-PickeachplayerinbossAcidRoach.playersFightinganddo(Actions)Actions// -------// wait with revive till fight endsVariable-Setplayers[(Pickedplayer)].haltRevive=True// -------// activate rest of the players that are in the fighting area// and create revealers and boss bar for themGeneral-If(Conditions)thendo(Actions)elsedo(Actions)IfbossAcidRoach.active[(Pickedplayer)]==FalseThen// -------Debug-DebugText((Combine("DEBUG # ","Boss Acid Roach - Force activate, P...",(Text((Pickedplayer))))))// -------Variable-SetbossAcidRoach.active[(Pickedplayer)]=TrueVisibility-CreateRevealersforplayergroup(2,(Playergroup((Pickedplayer))),Boss.AcidRoach.Area)// when copying from ACTIVATE trigger make sure you change (Triggering Player) to (Picked Player) in 3 places hereUI-Displaybossbar(Pickedplayer)withtitle"ACID ROACH",portraitAssets\Textures\btn-unit-zerg-primalroach.ddsandmaximumvalue100for(Playergroup((Pickedplayer)))UI-Setbossbar(Pickedplayer)bosstobossAcidRoach.unit(Dorefreshthebossbar)Else// -------// sounds for effectSound-PlayRoach_ReadyforbossAcidRoach.playersFightingonbossAcidRoach.unitwithZoffset0.0(at300.0%volume,skipthefirst0.0seconds)// -------// close area gateUnit-OrderbossAcidRoach.gateto(CloseGate)(ReplaceExistingOrders)// -------// run the controlerTrigger-RunAcidRoach-Controler(CheckConditions,Don'tWaituntilitfinishes)// -------
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
EVENTSLOCALVARIABLESCONDITIONSACTION// -------Debug-DebugText((Combine("DEBUG # ","Boss Acid Roach - Controler Starts")))// -------// set initial wait to 10 secondsVariable-SetbossAcidRoach.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 foreverGeneral-While(Conditions)aretrue,do(Actions)ConditionsbossAcidRoach.engaged==TrueActions// ------- ------- -------// IDLE LOOP// this loop will go while "wait" variable is bigger than 0// meaning that boss is not using any abilities yet// ------- ------- -------Debug-DebugText((Combine("DEBUG # ","Boss Acid Roach - Idle Loop Starts,...",(Text(bossAcidRoach.wait)with2decimalplaces))))// ------- ------- -------General-While(Conditions)aretrue,do(Actions)ConditionsbossAcidRoach.wait>0.0Actions// ------- ------- -------// ------- ------- -------// ------- ------- -------// ------- ------- -------// 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 hpGeneral-If(Conditions)thendo(Actions)elsedo(Actions)IfOrConditionsAndConditionsbossAcidRoach.burrowPhase==0(bossAcidRoach.unitLife(Percent)(Current))<=75.0AndConditionsbossAcidRoach.burrowPhase==1(bossAcidRoach.unitLife(Percent)(Current))<=50.0AndConditionsbossAcidRoach.burrowPhase==2(bossAcidRoach.unitLife(Percent)(Current))<=25.0Then// ------- ------- -------Debug-DebugText((Combine("DEBUG # ","Boss Acid Roach - Burrow Phase: ",(Text(bossAcidRoach.burrowPhase)))))// ------- ------- -------// make sure that given phase will launch only onceVariable-ModifybossAcidRoach.burrowPhase:+1// ------- ------- -------Unit-OrderbossAcidRoach.unitto(AcidRoach-Burrow)(ReplaceExistingOrders)// ------- ------- -------General-Switch(Actions)dependingonsettings.difficultyCasesGeneral-If(1)ActionsGeneral-Wait8.0GameTimesecondsVariable-SetbossAcidRoach.unburrowLingsNumber=8General-If(2)ActionsGeneral-Wait8.0GameTimesecondsVariable-SetbossAcidRoach.unburrowLingsNumber=10General-If(3)ActionsGeneral-Wait6.0GameTimesecondsVariable-SetbossAcidRoach.unburrowLingsNumber=10DefaultGeneral-Wait8.0GameTimesecondsVariable-SetbossAcidRoach.unburrowLingsNumber=10// ------- ------- -------General-Repeat(Actions)bossAcidRoach.unburrowLingsNumbertimesActionsUnit-Create1Boss-Zergling(AddBurrowed)forplayer5at(RandompointinBoss.AcidRoach.ZerglingAddSpawn)usingdefaultfacing(NoOptions)UnitGroup-Add(Lastcreatedunit)tobossAcidRoach.burrowUnitsUnit-Order(Lastcreatedunit)to(ZerglingAdd-Unburrow)(AfterExistingOrders)// ------- ------- -------// give player time to clean up zergling addsGeneral-Wait20.0GameTimeseconds// ------- ------- -------// don't forget to unburrow bossUnit-OrderbossAcidRoach.unitto(AcidRoach-Unburrow)(ReplaceExistingOrders)// ------- ------- -------// return to idle loop with new waitVariable-SetbossAcidRoach.wait=10.0// ------- ------- -------Else// ------- ------- -------// ------- ------- -------// ------- ------- -------// ------- ------- -------// IDLE CHECK// ------- ------- -------General-If(Conditions)thendo(Actions)elsedo(Actions)If(bossAcidRoach.unitisin(IdleUnitsforplayer5))==True(NumberofLivingunitsin(UnitsinBoss.AcidRoach.AreahavingallianceEnemywithplayer5matchingRequired:Visible;Excluded:Structure,Missile,Item,Dead,Hidden,Invulnerable,withatmostAnyAmount))>0ThenDebug-DebugText((Combine("DEBUG # ","Boss Acid Roach - Order: Attack")))Unit-OrderbossAcidRoach.unitto(Attacktargeting(Positionof(RandomLivingunitfrom(UnitsinBoss.AcidRoach.AreahavingallianceEnemywithplayer7matchingRequired:Ground,Visible;Excluded:Player,Ally,Neutral,Structure,Missile,Item,Stasis,Dead,Hidden,Invulnerable,withatmostAnyAmount))))(ReplaceExistingOrders)Else// ------- ------- -------// ------- ------- -------// ------- ------- -------// ------- ------- -------// TIMER// ------- ------- -------General-Wait0.25GameTimesecondsVariable-ModifybossAcidRoach.wait:-0.25// ------- ------- -------// ------- ------- -------// ------- ------- -------// ------- ------- -------// PHASE ABILITIES// phase abilities are the ones that fire when "wait" is equal to 0.0// ------- ------- -------General-Switch(Actions)dependingonbossAcidRoach.phaseCases// ACID SPITGeneral-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 easilySendtransmission(advanced)to(Allplayers)from(bossAcidRoach.unitwithFlash(DoNotoverrideportrait)playingTalk)playingRoachPrimal_Pissedwithname"ACID ROACH: "andmessage"<frightening roar>"usingNoPortraitwith""playingTalk(SetTo4.0seconds,Don'tWaituntilitfinishes)Sound-PlayMutalisk_PissedforbossAcidRoach.playersFightingonbossAcidRoach.unitwithZoffset0.0(at300.0%volume,skipthefirst0.0seconds)UI-Display"ACID ROACH: <frightening roar>"forbossAcidRoach.playersFightingtoChatarea// -------// give order to boss to perform ability// we will choose furthest unit from boss locationDebug-DebugText((Combine("DEBUG # ","Boss Acid Roach - Order: Acid Spit")))Unit-OrderbossAcidRoach.unitto(AcidRoach-AcidRoach-AcidSpittargeting(Positionof(RandomLivingunitfrom(UnitsinBoss.AcidRoach.AreahavingallianceEnemywithplayer5matchingExcluded:Structure,Missile,Item,Dead,Hidden,Invulnerable,withatmostAnyAmount))))(ReplaceExistingOrders)Unit-OrderbossAcidRoach.unitto(AcidRoach-AcidRoach-AcidSpittargeting(Positionof(FurthestUnitFromPoint((PositionofbossAcidRoach.unit),(UnitsinBoss.AcidRoach.AreahavingallianceEnemywithplayer7matchingExcluded:Structure,Missile,Item,Dead,Hidden,Invulnerable,withatmostAnyAmount)))))(ReplaceExistingOrders)// -------// allow boss to finish his ability// even if it will take longer it is no problem as// we will still go back to IDLE LOOPGeneral-Wait6.0GameTimeseconds// -------// set IDLE LOOP time and next phaseVariable-SetbossAcidRoach.wait=10.0Variable-SetbossAcidRoach.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 abilitiesGeneral-Switch(Actions)dependingon(Randomintegerbetween2and4)CasesGeneral-If(2)Actions// do ability 2General-If(3)Actions// do ability 3General-If(4)Actions// do ability 4Default// -------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
EVENTSUnit-AnyUnitdiesLOCALVARIABLESCONDITIONS// only check if we are fighting this particular bossbossAcidRoach.engaged==True// player that died is hero player((Triggeringplayer)isin(ActiveHeroPlayers))==True// player that died was fighting boss((Triggeringplayer)isinbossAcidRoach.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(NumberofLivingunitsin(UnitsinBoss.AcidRoach.AreahavingallianceEnemywithplayer5matchingExcluded:Structure,Missile,Item,Dead,Hidden,Invulnerable,Summoned,withatmostAnyAmount))==0ACTIONS// -------Debug-DebugText((Combine("DEBUG # ","Boss Acid Roach - Players Defeated")))// -------// reset all important variablesVariable-SetbossAcidRoach.engaged=FalseVariable-SetbossAcidRoach.phase=0// -------// turn off Zergling AI trigger to reduce number of callsTrigger-TurnAcidRoach-ZerglingAddsAIOff// -------// stop controler immiediatlyTrigger-StopallinstancesofAcidRoach-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 downUnit-Add1InvulnerableHidden(Hit)tobossAcidRoach.unitfromplayer7// we order boss to go stop all his movement and other actions,// we will order him to move back to his starting point later onUnit-OrderbossAcidRoach.unitto(Stop)(ReplaceExistingOrders)// -------// wait for better effectGeneral-Wait2.0GameTimeseconds// -------// kill all adds and other stuff that might be leftover from the fightUnitGroup-Pickeachunitin(Boss-AcidRoach-AcidLake(PlacedUnit)unitsinBoss.AcidRoach.AreaownedbyplayerAnyPlayermatchingExcluded:Dead,withatmostAnyAmount)anddo(Actions)ActionsUnit-Kill(Pickedunit)UnitGroup-PickeachunitinbossAcidRoach.burrowUnitsanddo(Actions)ActionsUnit-Kill(Pickedunit)UnitGroup-Pickeachunitin(Boss-Zergling(AddBurrowed)unitsinBoss.AcidRoach.Areaownedbyplayer5matchingExcluded:Dead,withatmostAnyAmount)anddo(Actions)ActionsUnit-Kill(Pickedunit)UnitGroup-Pickeachunitin(AnyunitsinBoss.AcidRoach.AreaownedbyplayerAnyPlayermatchingRequired:Structure;Excluded:Missile,Item,Dead,Invulnerable,withatmostAnyAmount)anddo(Actions)ActionsUnit-Kill(Pickedunit)UnitGroup-RemoveallunitsfrombossAcidRoach.burrowUnits// -------// order boss to move at his starting point and turn towards entranceUnit-OrderbossAcidRoach.unitto(AcidRoach-Unburrow)(ReplaceExistingOrders)Unit-OrderbossAcidRoach.unitto(MovetargetingBoss.AcidRoach.Start)(AfterExistingOrders)Unit-OrderbossAcidRoach.unitto(Turntargeting(Boss.AcidRoach.Startoffsetby1.0towards270.0degrees))(AfterExistingOrders)// -------// reset players activity, destroy revealers and hide boss barsVisibility-DestroyRevealersforplayergroup(2,bossAcidRoach.playersFighting)PlayerGroup-PickeachplayerinbossAcidRoach.playersFightinganddo(Actions)ActionsVariable-Setplayers[(Pickedplayer)].haltRevive=FalseVariable-SetbossAcidRoach.active[(Pickedplayer)]=FalseUI-Hidebossbar(Pickedplayer)UI-Setbossbar(Pickedplayer)bosstoNoUnit(Dorefreshthebossbar)//-------// wait for better effectGeneral-Wait4.0GameTimeseconds// -------// open boss doorsUnit-OrderbossAcidRoach.gateto(OpenGate)(ReplaceExistingOrders)// -------// remove invunerability and reset boss health// boss is ready to fight againUnit-Remove1InvulnerableHidden(Hit)frombossAcidRoach.unitfromplayer7Unit-SetbossAcidRoach.unitLife(Percent)to100.0Unit-SetbossAcidRoach.unitShields(Percent)to100.0// -------
ACID ROACH - BOSS DEFEATED
EVENTSUnit-AnyUnitdiesLOCALVARIABLESCONDITIONS// 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 unitbossAcidRoach.unit==(Triggeringunit)ACTIONS// -------Debug-DebugText((Combine("DEBUG # ","Boss Acid Roach - Boss Defeated")))// -------// reset all important variablesVariable-SetbossAcidRoach.alive=FalseVariable-SetbossAcidRoach.engaged=FalseVariable-SetbossAcidRoach.phase=100// -------// turn off Zergling AI trigger to reduce number of callsTrigger-TurnAcidRoach-ZerglingAddsAIOff// -------// stop controler immiediatlyTrigger-StopallinstancesofAcidRoach-Controler// -------// wait for better effectGeneral-Wait2.0GameTimeseconds// -------// remove all stuff that might have been summoned by the bossUnitGroup-Pickeachunitin(Boss-AcidRoach-AcidLake(PlacedUnit)unitsinBoss.AcidRoach.AreaownedbyplayerAnyPlayermatchingExcluded:Dead,withatmostAnyAmount)anddo(Actions)ActionsUnit-RemoveAllAcidRoach-AcidLake(StartShrinkVisual)from(Pickedunit)UnitGroup-PickeachunitinbossAcidRoach.burrowUnitsanddo(Actions)ActionsUnit-Kill(Pickedunit)// -------// wait for better effectGeneral-Wait3.0GameTimeseconds// -------// additional removal due to visualsUnitGroup-Pickeachunitin(Boss-AcidRoach-AcidLake(PlacedUnit)unitsinBoss.AcidRoach.AreaownedbyplayerAnyPlayermatchingExcluded:Dead,withatmostAnyAmount)anddo(Actions)ActionsUnit-Kill(Pickedunit)// -------// reset players activity, destroy revealers and hide boss barsVisibility-DestroyRevealersforplayergroup(2,bossAcidRoach.playersFighting)PlayerGroup-PickeachplayerinbossAcidRoach.playersFightinganddo(Actions)ActionsVariable-SetbossAcidRoach.active[(Pickedplayer)]=FalseUI-Hidebossbar(Pickedplayer)UI-Setbossbar(Pickedplayer)bosstoNoUnit(Dorefreshthebossbar)// -------// open boss doorsUnit-OrderbossAcidRoach.gateto(OpenGate)(ReplaceExistingOrders)// -------// show victory messageUI-Display"ACID ROACH DEFEATED!"forbossAcidRoach.playersFightingtoDirectivearea// -------General-Wait10.0GameTimeseconds// -------// remove victory messageUI-ClearDirectiveMessagesforbossAcidRoach.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.
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).
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.
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.
0
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);
0
So make it triggers + data.
Repeat the effect using triggers as long as there is at least one buff on the target.
0
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).
0
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>
0
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
0
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.
0
Yeah, its very easy. Just use this:
and check attached map.
Regards
Matic
0
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:
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:
but it doesn't do anything (at least I can't see anything).
I haven't tested the map online tho.
Thanks!
Regards
Matic
0
@Hockleberry: Go
Sure thing Hockleberry!
I didn't put it there cause to be honest I didn't know how to do it...
Thanks!
0
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.
0
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.
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
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:
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:
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
When player will decide to not fight the boss we must handle this situation as well:
Note that deactivation happens when player leave Boss.AcidRoach.Area, not the activation area.
ACID ROACH - DEACTIVATE
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
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
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
ACID ROACH - BOSS DEFEATED
7. TIPS
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
0
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
0
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
0
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
0
Hi there,
Maybe it is "ambience" that you are missing?
These two actions should do the trick:
Regards
Matic