diff --git a/defendTheCastleExtended/README.md b/defendTheCastleExtended/README.md new file mode 100644 index 0000000..fa80792 --- /dev/null +++ b/defendTheCastleExtended/README.md @@ -0,0 +1,204 @@ +# Variables + +## Global + +| Position | Variable | Description | +|----------|-------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 0 | gatePosition | Defines the position of the gate | +| 1 | zenSpawnPositions[2](#spawnPositions) | Counter used for increasing the possible spawn positions over time | +| 3 | loopIterator | Used as counter for the current iteration of a loop | +| 4 | bigBossSpawnPositions[2](#spawnPositions) | Defines the possible spawn positions for Orisa | +| 5 | playerSpawnPositions[2](#spawnPositions) | Defines the possible spawn positions for players | +| 6 | gateHealthChase | Variable being chased in order to show the gate health bar | +| 7 | gateHealth | Current gate health | +| 8 | gateMaxHealth | Max gate health | +| 9 | gateProgressBarColorCurrent | Contains the current color the gate health bar is supposed to have | +| 10 | gateProgressBarColorComponent | Used to calculate the gateProgressBarColorCurrent | +| 11 | gateHealthEvent | Contains the amount of health the gate has on the last event | +| 12 | bastionTargetPositions[1](#targetPositions) | Defines target positions for Bastion | +| 13 | sniperPositions[2](#spawnPositions) | Defines spawn Positions for Widowmaker | +| 14 | ballSpawnPositions[2](#spawnPositions) | Defines spawn Positions for Wreckingball | +| 15 | zenRespawnTime | Defines Zenyattas respawn time | +| 16 | timeSeconds | Contains the seconds part of the match timer | +| 17 | timeMinutes | Contains the minutes part of the match timer | +| 18 | defaultCurrentBot | Contains the bot that will be destroyed/replaced next
Might be renamed soon | +| 19 | defaultHeroBotsPool | Defines the heroes being played by ai
Code around this could need some serious rework
Hukuta left us with a bunch of seriously unnecessary complexity | +| 20 | defaultHeroBotsPoolCurrentId | This is pretty much just an iteration counter for defaultHeroBotsPool | +| 21 | isDebug | Determines if the debug mode is active | +| 22 | botOrisaParent | Contains the current Orisa Dummy | +| 24 | botOrisaChild | Contains the current Bastion Dummy being stuck onto botOrisaParent | +| 25 | gateRepairPosition | Defines the position you have to look at when trying to repair the gate | +| 26 | botOrisaTargetPosition[1](#targetPositions) | Defines the target position for Orisa | +| 27 | botEchoRespawnPosition[2](#spawnPositions) | Defines the spawn/portal position for Echo | +| 28 | botEchoTeleportPositions | Defines the player teleport positions for Echo | +| 29 | upgradeGateMaxHealthValue[3](#teamChallenges) | Contains the current amount of repaired gate health | +| 30 | upgradeGateMaxHealthHudId[3](#teamChallenges) | Contains the challenge HUD | +| 31 | upgradePlayerMaxHealthValue[3](#teamChallenges) | Contains the current amount of healed player health | +| 32 | upgradePlayerMaxHealthHudId[3](#teamChallenges) | Contains the challenge HUD | +| 33 | upgradeCriticalDamageValue[3](#teamChallenges) | Contains the current amount Widowmaker/Echo kills | +| 34 | upgradeCriticalDamageHudId[3](#teamChallenges) | Contains the challenge HUD | +| 35 | upgradeMaxAmmoValue[3](#teamChallenges) | Contains the current amount of Zenyatta kills | +| 36 | upgradeMaxAmmoHudId[3](#teamChallenges) | Contains the challenge HUD | +| 37 | upgradeMaxAmmoMaxValue[3](#teamChallenges) | Contains the value needed to finish the challenge | +| 38 | upgradePlayerMaxHealthMaxValue[3](#teamChallenges) | Contains the value needed to finish the challenge | +| 39 | upgradePlayerMaxHealthMaxValue[3](#teamChallenges) | Contains the value needed to finish the challenge | +| 40 | upgradeGateMaxHealthMaxValue[3](#teamChallenges) | Contains the value needed to finish the challenge | +| 41 | damageBoost | Contains the damage % that is being put on top of the base damage | +| 42 | isDebugAINavigation | | +| 43 | gameLogicCountOfUniqueHeroes | | +| 44 | isNewWaveGameLogicProcessing | | +| 45 | automaticRepair | | +| 46 | upgradePerkSharpshooterValue | | +| 47 | perk | | +| 48 | maxHealthDone | | +| 49 | startMoney | | +| 50 | time5Minutes | | +| 51 | selfNanoWorkshopSetting | | +| 52 | shopCamPosition | | +| 53 | shopBasePosition | | +| 54 | shopPositionAngle | | +| 55 | activeBoss | | +| 57 | bossRotation | | +| 58 | lastBoss | | +| 59 | time10Minutes | | +| 60 | moneyMultiplier | | +| 61 | challengeCount | | +| 62 | upgradeBossHealthValue | | +| 63 | globalHUDs | | +| 64 | baseStats | | +| 112 | allPositions | | +| 113 | allDirections | | +| 114 | firstPosition | | +| 115 | secondPosition | | +| 116 | firstPoint | | +| 117 | secondPoint | | +| 118 | second | | +| 119 | z | | +| 120 | wallId | | +| 121 | showWalls | | +| 122 | isGrounded | | +| 123 | beamType | | +| 125 | nodePositions | | +| 126 | nodeConnections | | +| 127 | distanceMatrix | | + +> 1: Target position variables can pretty much be merged +> +> 2: Spawn position variables can pretty much be merged +> +> 3: upgrade* variables can be merged into one + +## Player +| Position | Variable | Description | +|----------|----------------------------------------------------------------------------------------------------|-------------| +| 0 | botSeePlayer | | +| 1 | botDoesUniqueBehaviour | | +| 2 | botEffects | | +| 3 | botRayCastHitPosition | | +| 4 | botEventPosition | | +| 5 | currentHero | | +| 6 | isDead | | +| 7 | isRespawning | | +| 8 | botBastionArtilleryDidShotsCount | | +| 9 | botCounter | | +| 10 | hasBadStatus | | +| 11 | eventHealth | | +| 12 | healOverTimeId | | +| 13 | botIsOrisaChild | | +| 14 | botEchoCapturedPlayer | | +| 15 | botPlayersInRadius | | +| 16 | botLoopIterator2 | | +| 17 | botWidowShotTime | | +| 18 | botWidowTeleportTime | | +| 19 | isNanoed | | +| 20 | abilityHUD | | +| 21 | lucioDashActive | | +| 22 | lucioDashIcon | | +| 23 | anaEntityID | | +| 24 | abilities | | +| 25 | money | | +| 26 | heroTalentText | | +| 27 | damageBoost | | +| 28 | playerHealth | | +| 29 | abilityCountdown | | +| 30 | hpPool | | +| 31 | effects | | +| 32 | abilityProjectile | | +| 33 | abilityEnd | | +| 34 | abilityAvailable | | +| 35 | moveSpeed | | +| 36 | damageMod | | +| 37 | critDamageBoost | | +| 38 | soldierEspionage | | +| 39 | healingDealt | | +| 41 | chainReactionOn | | +| 42 | chainReactionImmune | | +| 43 | abilityActive | | +| 45 | secondWindActive | | +| 46 | isInMenu | | +| 48 | playerFacing | | +| 49 | isBoss | | +| 53 | deathPosition | | +| 54 | lastSecondWind | | +| 55 | vote | | +| 105 | filterPosition | | +| 106 | lastSavedPosition | | +| 107 | closestBodyPosition | | +| 108 | fullBodyPosition | | +| 109 | previousPositionIntersection | | +| 110 | activeWall | | +| 111 | closestWall | | +| 112 | x | | +| 113 | intersectionLength | | +| 114 | thickness | | +| 115 | botCancelPathFinding | | +| 116 | botLoopIterator1 | | +| 117 | botTempArray | | +| 118 | botTargetPlayer | | +| 119 | botTargetPosition | | +| 120 | botClosestNodeIdToTarget | | +| 121 | botClosestNodeIdToBot | | +| 122 | botPreviousNodeId | | +| 123 | botNextNodeId | | +| 124 | botNextNodePosition | | +| 125 | botCurrentDistanceToTarget | | +| 126 | botShortestDistanceToTarget | | +| 127 | botIsPathFinding | | + + +## Subroutine + +| Position | Variable | Description | +|----------|------------------------------------------------------------------------------------------|-------------| +| 0 | BotBastionArtilleryDamage | | +| 2 | BotBastionRespawn | | +| 3 | GateProgressBarColor | | +| 4 | BotZenyattaRespawn | | +| 5 | BotWidowRespawn | | +| 6 | BotBallRespawn | | +| 7 | GameLogicAddNextHeroInGame | | +| 8 | BotOrisaRespawn | | +| 9 | BotLandingFromSky | | +| 10 | BotEchoRespawn | | +| 11 | BotEchoDetachPlayer | | +| 12 | BotEchoFlyToPlayer | | +| 13 | BotEchoFlyToPortal | | +| 14 | GameLogicSetBotProperties | | +| 15 | DisablePlayer | | +| 16 | BotAppearFromUnderground | | +| 17 | BotReinRespawn | | +| 18 | PlayerInit | | +| 19 | BotInit | | +| 20 | PlayerRespawn | | +| 21 | BotRespawn | | +| 22 | BotWidowBadStatus | | +| 23 | GameLogicWave0 | | +| 24 | Refund | | +| 25 | EnablePlayer | | +| 26 | GateRepair | | +| 27 | CancelMomentum | | +| 28 | UpdateDamage | | +| 124 | BotStartPathFinding | | +| 125 | BotGetClosestNodeIdToTarget | | +| 126 | BotGetNextNodeIdAndPosition | | +| 127 | BotResetPathFinding | | diff --git a/defendTheCastleExtended/changelog b/defendTheCastleExtended/changelog new file mode 100644 index 0000000..3109568 --- /dev/null +++ b/defendTheCastleExtended/changelog @@ -0,0 +1,80 @@ +c121: +-> Reduced hammond speed +-> Increased manual repair amount if 4 players in team 1 +-> deactivated spectators +-> Reduced amount of Zens in team 2 + +c122: +-> Added new workshop setting: Money Multiplicator +-> Increased money on kill by 5 for the following enemies: + -> Zenyatta + -> Reinhardt + -> Wrecking Ball + -> Widowmaker + +c123: +-> Widow can't shoot right after teleporting +-> Reduced amount of needed Echo & Boss kills from 10 to 5 +-> Fixed Mercy rez respawn position + +c124: +-> Game now starts after 1 Player pressed Interact +-> Changed the notification of the unlocked optional ending from a big message to a hud text, that stays for 3 seconds + +c125: +-> Decreased money on kill by 5 for reinhardt and zenyatta +-> Damage and health of all enemies increases all 5 + 10 Minutes (means all 10 minutes it actually increases twice) +-> Made widow shoot faster again +-> Added a circle at the spawn where you can change your hero anytime by pressing Interact + +c126: +-> Fixed Huds being added when player switches hero using the circle at spawn +-> Fixed player spawn position when player switches hero using the circle at the spawn + +c127: +-> refactor variable/rule names and case +-> fix hero switch station +-> fix condition for exfiltration + +c128: +-> move spawn and hero switch station inside castle +-> fix mercy rez teleporting to spawn + +c130: +-> change team challenge values +-> remove some disabled rules +-> merge rules with similar conditions +-> refactor repair rules + +c131: +-> remove old "story heroes" from original mode +-> remove/merge old debug rules +-> rearrange and fix max ammo challenges +-> show current challengeCount in HUD +-> actually finally fix mercy rezz +-> remove "rein boss wave" messages +-> fix zen boss not giving more zen kills + +c132: +-> removed all disabled rules/actions/conditions +-> merged all Player Dealt Damage/Healing rules +-> increased waits +This update is supposed to improve the performance. +Actual changes coming with the next update + +c133: +-> make players in shop not being attacked +-> fix sombra being attacked while invis +-> remove most small/big messages +-> change effect visibility to team 1 only +-> add actual vote to start the mode +-> remove boss timer +-> allow echo to repair when duplicating rein +-> fix some effect bugs + + +c135: +-> add fixes i prepared ages ago +-> remove rein cancel (obsolete in ow2) + +c136: diff --git a/defendTheCastleExtended/latest.ow b/defendTheCastleExtended/latest.ow new file mode 100644 index 0000000..75f936a --- /dev/null +++ b/defendTheCastleExtended/latest.ow @@ -0,0 +1,8988 @@ +settings +{ + main + { + Description: "Defend The Castle Extended Version d143\nby ShuriZma#2349\nJ1K6F (Code Version: d143)\nOriginal mode by HuKuTa94#2589\n\nDefend the gate, kill enemies\nand don't allow them to damage the gate!\n\nSpecial Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents\n& Josbird for teaching me about Menus!\n\nFind this mode on: workshop.codes/defend-the-castle\nFind the Original Mode on: workshop.codes/BQEGS\nTell me what you think on Discord: dc.shuri.gg\n\nPS: SHINGEN PLS COME BACK" + Mode Name: "Defend The Castle Extended" + } + + lobby + { + Max Spectators: 0 + Max Team 1 Players: 4 + Max Team 2 Players: 0 + Return To Lobby: Never + Swap Teams After Match: No + } + + modes + { + Escort + { + enabled maps + { + Havana 0 + } + } + + Team Deathmatch + { + enabled maps + { + } + } + + General + { + Game Mode Start: Immediately + Spawn Health Packs: Disabled + } + } + + extensions + { + Beam Effects + Buff Status Effects + Kinetic Explosion Effects + Explosion Sounds + Play More Effects + Spawn More Dummy Bots + } +} + +variables +{ + global: + 0: gatePosition + 1: zenSpawnPositions + 2: spawnPositionMaxId + 3: loopIterator + 4: bigBossSpawnPositions + 5: playerSpawnPositions + 6: gateHealthChase + 7: gateHealth + 8: gateMaxHealth + 9: gateProgressBarColorCurrent + 10: gateProgressBarColorComponent + 11: gateHealthEvent + 12: bastionTargetPositions + 13: sniperPositions + 14: ballSpawnPositions + 15: zenRespawnTime + 16: timeSeconds + 17: timeMinutes + 18: defaultCurrentBot + 19: defaultHeroBotsPool + 21: isDebug + 22: botOrisaParent + 24: botOrisaChild + 25: gateRepairPosition + 26: botOrisaTargetPosition + 27: botEchoRespawnPosition + 28: botEchoTeleportPositions + 29: upgradeGateMaxHealthValue + 30: upgradeGateMaxHealthHudId + 31: upgradePlayerMaxHealthValue + 32: upgradePlayerMaxHealthHudId + 33: upgradeCriticalDamageValue + 34: upgradeCriticalDamageHudId + 35: upgradeMaxAmmoValue + 36: upgradeMaxAmmoHudId + 37: upgradeMaxAmmoMaxValue + 38: upgradePlayerMaxHealthMaxValue + 39: upgradeCriticalDamageMaxValue + 40: upgradeGateMaxHealthMaxValue + 42: isDebugAINavigation + 43: gameLogicCountOfUniqueHeroes + 44: isNewWaveGameLogicProcessing + 45: automaticRepair + 46: upgradePerkSharpshooterValue + 47: perk + 48: maxHealthDone + 49: startMoney + 50: time5Minutes + 51: selfNanoWorkshopSetting + 52: shopCamPosition + 53: shopBasePosition + 54: shopPositionAngle + 55: activeBoss + 57: bossRotation + 58: lastBoss + 59: time10Minutes + 60: moneyMultiplier + 61: challengeCount + 62: upgradeBossHealthValue + 63: globalHUDs + 108: extendedGlobalCollection + 109: arrayBuilder + 111: exitButtonProperties + 112: allPositions + 113: allDirections + 114: firstPosition + 115: secondPosition + 116: firstPoint + 117: secondPoint + 118: second + 119: z + 120: wallId + 121: showWalls + 122: isGrounded + 123: beamType + 125: nodePositions + 126: nodeConnections + 127: distanceMatrix + + player: + 0: botSeePlayer + 1: botDoesUniqueBehaviour + 2: botEffects + 3: botRayCastHitPosition + 4: botEventPosition + 5: currentHero + 6: isDead + 7: isRespawning + 8: botBastionArtilleryDidShotsCount + 9: botCounter + 10: hasBadStatus + 11: eventHealth + 12: healOverTimeId + 13: botIsOrisaChild + 14: botEchoCapturedPlayer + 15: botPlayersInRadius + 16: botLoopIterator2 + 17: botWidowShotTime + 18: botWidowTeleportTime + 19: isNanoed + 20: abilityHUD + 21: lucioDashActive + 22: lucioDashIcon + 23: anaEntityID + 24: abilities + 25: money + 26: heroTalentText + 27: damageBoost + 28: playerHealth + 29: abilityCountdown + 30: hpPool + 31: effects + 32: abilityProjectile + 33: abilityEnd + 34: abilityAvailable + 35: speedBoost + 36: damageMod + 38: soldierEspionage + 39: healBoost + 40: baseStats + 41: chainReactionOn + 42: chainReactionImmune + 43: abilityActive + 44: loopIterator + 45: secondWindActive + 46: isInMenu + 48: playerFacing + 49: isBoss + 53: deathPosition + 54: lastSecondWind + 55: vote + 94: workshopButtons + 95: extendedPlayerCollection + 96: getProperties + 97: buttonModification + 98: currActionID + 99: destroyButtonID + 100: lastMenuButtonID + 101: buttons + 102: newButton + 103: menuOriginalFacing + 104: menuFrame + 105: filterPosition + 106: lastSavedPosition + 107: closestBodyPosition + 108: fullBodyPosition + 109: previousPositionIntersection + 110: activeWall + 111: closestWall + 112: x + 113: intersectionLength + 114: thickness + 115: botCancelPathFinding + 116: botLoopIterator1 + 117: botTempArray + 118: botTargetPlayer + 119: botTargetPosition + 120: botClosestNodeIdToTarget + 121: botClosestNodeIdToBot + 122: botPreviousNodeId + 123: botNextNodeId + 124: botNextNodePosition + 125: botCurrentDistanceToTarget + 126: botShortestDistanceToTarget + 127: botIsPathFinding +} + +subroutines +{ + 0: BotBastionArtilleryDamage + 2: BotBastionRespawn + 3: GateProgressBarColor + 4: BotZenyattaRespawn + 5: BotWidowRespawn + 6: BotBallRespawn + 8: BotOrisaRespawn + 9: BotLandingFromSky + 10: BotEchoRespawn + 11: BotEchoDetachPlayer + 12: BotEchoFlyToPlayer + 13: BotEchoFlyToPortal + 14: GameLogicSetBotProperties + 15: DisablePlayer + 16: BotAppearFromUnderground + 17: BotReinRespawn + 18: PlayerInit + 19: BotInit + 20: PlayerRespawn + 21: BotRespawn + 22: BotWidowBadStatus + 24: Refund + 25: EnablePlayer + 26: GateRepair + 27: CancelMomentum + 28: UpdatePlayerStats + 114: createMenuButton + 115: destroyMenuButton + 116: modifyMenuButton + 117: getButtonProperties + 118: createCursor + 122: doButtonUpdate + 124: BotStartPathFinding + 125: BotGetClosestNodeIdToTarget + 126: BotGetNextNodeIdAndPosition + 127: BotResetPathFinding +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("MAP: HAVANA") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Havana); + } + + actions + { + Global.nodePositions = Array(Vector(147.588, 6.425, -46.749), Vector(136.181, 6.425, -57.159), Vector(130.189, 6.425, -63.781), + Vector(123.305, 6.425, -57.983), Vector(125.678, 6.504, -46.633), Vector(114.485, 7.471, -46.699), Vector(138.743, 6.425, + -32.974), Vector(126.498, 6.425, -39.920), Vector(124.572, 10.434, -34.300), Vector(138.605, 5.359, -18.647), Vector(119.009, + 2.331, -31.024), Vector(121.138, 5.228, -19.933), Vector(126.722, 6.425, -29.505), Vector(102.762, 3.157, -33.609), Vector( + 76.030, 7.418, -74.087), Vector(83.720, 9.425, -33.744), Vector(97.439, 7.238, -42.379), Vector(86.252, 12.416, -47.261), + Vector(65.178, 11.425, -73.187), Vector(97.466, 7.269, -50.596), Vector(113.039, 7.424, -37.337), Vector(106.179, 7.450, + -46.143), Vector(90.086, 7.411, -44.653), Vector(78.752, 7.418, -62.140), Vector(82.124, 7.428, -44.229), Vector(90.675, 7.231, + -51.234), Vector(85.717, 4.692, -63.446), Vector(90.830, 4.330, -70.697), Vector(102.425, 2.387, -72.817), Vector(81.443, + 4.425, -81.648), Vector(70.743, 6.418, -81.495), Vector(69.738, 6.419, -96.344), Vector(127.586, 12.643, -63.344), Vector( + 118.911, 13.468, -58.008), Vector(102.885, 1.092, -56.579), Vector(100.009, 2.967, -67.139), Vector(106.703, 0.465, -44.628), + Vector(81.695, 7.418, -52.140), Vector(126.979, 12.393, -55.079), Vector(153.720, 18.578, -21.745), Vector(155.301, 18.619, + -17.595), Vector(133.043, 10.425, -26.625), Vector(114.646, 7.278, -57.336), Vector(95.160, 3.688, -81.194), Vector(78.456, + 5.418, -93.581), Vector(75.455, 5.418, -101.492), Vector(148.071, 9.432, -32.123), Vector(146.706, 9.425, -27.858), Vector( + 144.273, 9.445, -63.119), Vector(144.278, 9.454, -58.447)); + Global.nodeConnections = Array(Array(1, 6, 4, 7), Array(2, 1, 4, 6, 7, 0, 49), Array(1, 3), Array(2, 4, 42), Array(3, 1, 5, 7, 6, + 1, 0), Array(4, 7, 20, 21, 19, 16, 42), Array(7, 1, 4, 1, 9, 12, 0, 46), Array(4, 5, 6, 1, 1, 12, 0), Array(7, 41), Array(6, + 11), Array(11, 13), Array(9, 10, 13), Array(6, 7, 10), Array(10, 16, 36), Array(18, 23, 30), Array(17, 24), Array(13, 19, 22, + 21, 25, 5), Array(15, 22, 25, 23), Array(14), Array(16, 21, 22, 26, 27, 35, 25, 5), Array(5, 13, 10), Array(19, 16, 5, 13, 22, + 34), Array(16, 19, 21, 24, 25), Array(14, 25, 26, 37), Array(22, 15, 37), Array(23, 22, 19, 16, 26, 27, 35, 37), Array(25, 19, + 27, 35, 29), Array(19, 26, 25, 29, 35, 43), Array(35, 34, 43), Array(27, 26, 30, 43, 44), Array(29, 14, 31), Array(30, 29, 45), + Array(33, 38, 1, 48), Array(32, 38, 42), Array(35, 36, 28), Array(28, 19, 25, 27, 26, 34), Array(13, 34), Array(25, 23, 24), + Array(5, 4, 1, 6, 1, 32, 33, 0), Array(40), Array(39), Array(6, 8, 47, 46), Array(3, 5, 34), Array(28, 27, 29, 44), Array(29, + 43, 45), Array(44, 31), Array(6, 47), Array(46, 41), Array(49, 32), Array(1, 0, 6, 48)); + Global.distanceMatrix = Array(Array(0, 1, 2, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, + 4, 5, 4, 4, 5, 5, 5, 0, 0, 4, 3, 5, 6, 7, 2, 3, 3, 2), Array(1, 0, 1, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, + 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 3, 4, 4, 4, 5, 5, 4, 0, 0, 4, 3, 5, 6, 7, 2, 3, 2, 1), Array(2, 1, 0, 1, 2, 3, 2, 2, 6, 3, 4, 4, + 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 4, 6, 7, 8, 4, 5, 3, 4, 4, 6, 5, 0, 0, 5, 2, 5, 6, 7, 3, 4, 3, 2), Array(2, 2, + 1, 0, 1, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, 5, 6, 2, 3, 3, 5, 6, 0, 0, 5, 1, 4, + 5, 6, 3, 4, 4, 3), Array(1, 1, 2, 1, 0, 1, 1, 1, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, + 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, 2, 3, 3, 2), Array(2, 2, 3, 2, 1, 0, 2, 1, 6, 3, 2, 3, 2, 2, 4, 4, 1, 5, 5, 1, 1, 1, 2, 3, + 3, 2, 2, 2, 3, 3, 4, 5, 5, 6, 2, 2, 3, 3, 6, 0, 0, 5, 1, 3, 4, 5, 3, 4, 4, 3), Array(1, 1, 2, 2, 1, 2, 0, 1, 4, 1, 2, 2, 1, 3, + 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 4, 5, 4, 4, 4, 5, 5, 0, 0, 3, 3, 5, 6, 7, 1, 2, 3, 2), Array(1, 1, 2, 2, + 1, 1, 1, 0, 5, 2, 2, 3, 1, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, + 2, 3, 3, 2), Array(2, 2, 3, 3, 2, 2, 2, 1, 0, 3, 3, 4, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, + 5, 5, 6, 0, 0, 1, 3, 5, 6, 7, 2, 2, 4, 3), Array(2, 2, 3, 3, 2, 3, 1, 2, 5, 0, 2, 1, 2, 2, 6, 6, 3, 7, 7, 4, 4, 4, 4, 5, 5, 4, + 5, 5, 5, 6, 7, 8, 5, 6, 4, 5, 3, 5, 6, 0, 0, 4, 4, 6, 7, 8, 2, 3, 4, 3), Array(4, 4, 5, 5, 4, 3, 3, 4, 7, 2, 0, 1, 4, 1, 5, 5, + 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 7, 8, 3, 4, 2, 4, 8, 0, 0, 6, 4, 5, 6, 7, 4, 5, 6, 5), Array(3, 3, 4, 4, 3, 3, + 2, 3, 6, 1, 1, 0, 3, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 6, 7, 3, 4, 2, 4, 7, 0, 0, 5, 4, 5, 6, 7, 3, 4, + 5, 4), Array(2, 2, 3, 3, 2, 2, 1, 1, 5, 2, 1, 2, 0, 2, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, 3, 5, + 6, 0, 0, 4, 3, 5, 6, 7, 2, 3, 4, 3), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 3, 1, 2, 4, 0, 4, 4, 1, 5, 5, 2, 3, 2, 2, 3, 3, 2, 3, 3, + 3, 4, 5, 6, 7, 8, 2, 3, 1, 3, 8, 0, 0, 7, 3, 4, 5, 6, 5, 6, 6, 5), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 5, 6, 6, 4, 0, 4, 3, 5, + 1, 3, 5, 4, 3, 1, 3, 2, 2, 3, 4, 2, 1, 2, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 3, 3, 3, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, + 5, 10, 7, 5, 6, 6, 4, 3, 0, 3, 1, 4, 3, 5, 3, 2, 2, 1, 2, 3, 3, 4, 4, 4, 5, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 4, 5, 6, 7, 8, + 8, 7), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 3, 3, 0, 4, 4, 1, 2, 1, 1, 2, 2, 1, 2, 2, 3, 3, 4, 5, 6, 7, 2, 2, 2, 2, + 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 1, 2, 0, 3, 2, 4, 2, 1, 1, 2, 1, 2, 2, + 3, 3, 3, 4, 8, 9, 3, 2, 4, 2, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 6, 7, 7, 5, 1, 5, 4, 6, + 0, 4, 6, 5, 4, 2, 4, 3, 3, 4, 5, 3, 2, 3, 10, 11, 5, 4, 6, 3, 11, 0, 0, 10, 6, 4, 4, 4, 8, 9, 9, 8), Array(3, 3, 4, 3, 2, 1, 3, + 2, 7, 4, 3, 4, 3, 2, 3, 3, 1, 4, 4, 0, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 3, 4, 6, 7, 2, 1, 3, 2, 7, 0, 0, 6, 2, 2, 3, 4, 4, 5, 5, + 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 3, 1, 2, 3, 1, 5, 5, 2, 6, 6, 2, 0, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 6, 7, 3, 3, 2, 4, 7, + 0, 0, 6, 2, 4, 5, 6, 4, 5, 5, 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 4, 3, 1, 4, 5, 1, 2, 0, 1, 3, 2, 2, 2, 2, 2, + 3, 4, 5, 6, 7, 1, 2, 2, 3, 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 3, 2, 1, 3, 4, + 1, 3, 1, 0, 2, 1, 1, 2, 2, 3, 3, 4, 5, 7, 8, 2, 2, 3, 2, 8, 0, 0, 7, 3, 3, 4, 5, 5, 6, 6, 5), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, + 6, 4, 5, 5, 3, 1, 3, 2, 4, 2, 2, 4, 3, 2, 0, 2, 1, 1, 2, 3, 2, 2, 3, 8, 9, 3, 2, 4, 1, 9, 0, 0, 8, 4, 3, 3, 4, 6, 7, 7, 6), + Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 3, 1, 2, 2, 4, 2, 4, 2, 1, 2, 0, 2, 3, 3, 4, 4, 4, 5, 8, 9, 3, 3, 4, 1, 9, 0, + 0, 8, 4, 4, 5, 6, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 2, 3, 1, 4, 3, 1, 3, 2, 1, 1, 2, 0, 1, 1, 2, 2, + 3, 4, 7, 8, 2, 1, 3, 1, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, + 3, 2, 2, 2, 3, 1, 0, 1, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 2, 2, 3, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, + 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 0, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 1, 2, 3, 5, 6, 6, 5), Array( + 5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 4, 5, 3, 6, 5, 2, 4, 3, 3, 3, 4, 2, 2, 2, 0, 2, 3, 4, 8, 9, 1, 1, 2, 3, 9, 0, 0, 8, + 4, 1, 2, 3, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 2, 5, 3, 6, 3, 2, 4, 3, 3, 3, 4, 2, 1, 1, 2, 0, 1, 2, + 8, 9, 3, 2, 4, 3, 9, 0, 0, 8, 4, 1, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 1, 5, 4, 6, 2, 3, 5, 4, + 4, 2, 4, 3, 2, 2, 3, 1, 0, 1, 9, 10, 4, 3, 5, 3, 10, 0, 0, 9, 5, 2, 2, 2, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, + 7, 6, 5, 2, 6, 4, 7, 3, 3, 5, 4, 4, 3, 5, 3, 2, 2, 3, 1, 1, 0, 9, 10, 4, 3, 5, 4, 10, 0, 0, 9, 5, 2, 2, 1, 7, 8, 8, 7), Array( + 2, 1, 2, 3, 2, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 4, 5, 6, 7, 0, 1, 3, 4, 4, 5, 1, 0, 0, 5, + 2, 5, 6, 7, 3, 4, 1, 2), Array(2, 2, 3, 2, 2, 2, 2, 3, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, + 1, 0, 2, 3, 3, 5, 1, 0, 0, 5, 1, 4, 5, 6, 3, 4, 2, 3), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 5, 3, 4, 5, 2, 4, 5, 3, 6, 5, 2, 4, 3, + 3, 3, 4, 2, 2, 2, 1, 3, 4, 5, 8, 9, 0, 1, 1, 3, 9, 0, 0, 8, 4, 2, 3, 4, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, + 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 1, 1, 2, 3, 4, 7, 8, 1, 0, 2, 2, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(5, 5, + 6, 5, 4, 3, 5, 4, 9, 4, 2, 3, 5, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 8, 9, 1, 2, 0, 4, 9, 0, 0, 8, 4, 3, + 4, 5, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 2, 2, 3, 3, 2, 4, 3, 2, 1, 1, 1, 2, 2, 3, 3, 3, 4, 8, 9, + 3, 2, 4, 0, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(1, 1, 2, 2, 1, 1, 1, 2, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, + 4, 3, 3, 3, 4, 4, 5, 6, 1, 1, 3, 3, 4, 4, 0, 0, 0, 4, 2, 4, 5, 6, 2, 3, 2, 2), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(2, 2, 3, 3, 2, 3, 1, 2, 1, 2, 3, 3, 2, + 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 0, 4, 6, 7, 8, 1, 1, 4, 3), Array(3, 3, 2, + 1, 2, 1, 3, 2, 7, 4, 3, 4, 3, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 6, 7, 1, 2, 2, 4, 7, 0, 0, 6, 0, 3, 4, + 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 3, 5, 3, 6, 4, 2, 4, 3, 3, 3, 4, 2, 2, 1, 1, 1, 2, 3, 8, 9, 2, + 2, 3, 3, 9, 0, 0, 8, 4, 0, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 3, 6, 4, 7, 4, 3, 5, 4, 4, 4, 5, + 3, 2, 2, 2, 1, 2, 2, 9, 10, 3, 3, 4, 4, 10, 0, 0, 9, 5, 1, 0, 1, 7, 8, 8, 7), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 7, 8, 7, 6, + 3, 7, 5, 8, 4, 4, 6, 5, 5, 4, 6, 4, 3, 3, 3, 2, 2, 1, 10, 11, 4, 4, 5, 5, 11, 0, 0, 10, 6, 2, 1, 0, 8, 9, 9, 8), Array(2, 2, 3, + 3, 2, 3, 1, 2, 3, 2, 3, 3, 2, 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 2, 4, 6, 7, + 8, 0, 1, 4, 3), Array(3, 3, 4, 4, 3, 4, 2, 3, 2, 3, 4, 4, 3, 5, 8, 8, 5, 9, 9, 5, 5, 5, 6, 7, 7, 6, 6, 6, 7, 7, 8, 9, 6, 7, 6, + 6, 6, 7, 7, 0, 0, 1, 5, 7, 8, 9, 1, 0, 5, 4), Array(2, 2, 3, 4, 3, 3, 2, 3, 6, 3, 4, 4, 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, + 5, 5, 5, 5, 6, 7, 8, 1, 2, 4, 5, 5, 6, 2, 0, 0, 5, 3, 6, 7, 8, 3, 4, 0, 1), Array(1, 1, 2, 3, 2, 3, 1, 2, 5, 2, 3, 3, 2, 4, 7, + 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 2, 3, 5, 5, 5, 6, 3, 0, 0, 4, 4, 6, 7, 8, 2, 3, 1)); + } +} + +rule("SUBROUTINE: BOT - RESET PATH FINDING") +{ + event + { + Subroutine; + BotResetPathFinding; + } + + actions + { + Event Player.botTargetPlayer = -1; + Event Player.botTargetPosition = -1; + Event Player.botPreviousNodeId = -1; + Event Player.botClosestNodeIdToTarget = -1; + Event Player.botNextNodeId = -1; + Event Player.botNextNodePosition = -1; + Event Player.botIsPathFinding = False; + Event Player.botCancelPathFinding = False; + Stop Throttle In Direction(Event Player); + } +} + +rule("SUBROUTINE: BOT - START PATH FINDING") +{ + event + { + Subroutine; + BotStartPathFinding; + } + + actions + { + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Event Player.botIsPathFinding = True; + } +} + +rule("SUBROUTINE: BOT - GET NEXT NODE ID AND POSITION") +{ + event + { + Subroutine; + BotGetNextNodeIdAndPosition; + } + + actions + { + "BOT JUST START FOLLOW PATH OR LOST NEXT NODE" + If(Event Player.botPreviousNodeId == -1); + Event Player.botClosestNodeIdToBot = Index Of Array Value(Global.nodePositions, Sorted Array(Filtered Array(Global.nodePositions, + Is In Line of Sight(Position Of(Event Player) + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS) == True), + Distance Between(Position Of(Event Player), Current Array Element))[0]); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + "NEXT NODE IS TARGET (DISTANCE TO TARGET NODE = 1)" + If(Global.distanceMatrix[Event Player.botClosestNodeIdToBot][Event Player.botClosestNodeIdToTarget] == 1); + Event Player.botNextNodeId = Event Player.botClosestNodeIdToTarget; + "CHECK CONNECTIONS OF REACHED NODE" + Else; + Event Player.botShortestDistanceToTarget = 999; + Event Player.botCurrentDistanceToTarget = Event Player.botShortestDistanceToTarget; + Event Player.botTempArray = Global.nodeConnections[Event Player.botClosestNodeIdToBot]; + For Player Variable(Event Player, botLoopIterator1, 0, Count Of(Event Player.botTempArray), 1); + Event Player.botCurrentDistanceToTarget = Global.distanceMatrix[Event Player.botTempArray[Event Player.botLoopIterator1]][Event Player.botClosestNodeIdToTarget]; + If(Event Player.botCurrentDistanceToTarget < Event Player.botShortestDistanceToTarget); + Event Player.botShortestDistanceToTarget = Event Player.botCurrentDistanceToTarget; + Event Player.botNextNodeId = Event Player.botTempArray[Event Player.botLoopIterator1]; + End; + End; + End; + "NEXT NODE IS HIGHER THAN BOT AND BOT DIDN'T REACH CLOSEST NODE" + If(Y Component Of(Position Of(Event Player)) - Y Component Of(Global.nodePositions[Event Player.botNextNodeId]) + < -3 && Event Player.botPreviousNodeId != Event Player.botClosestNodeIdToBot); + Event Player.botPreviousNodeId = Event Player.botClosestNodeIdToBot; + Event Player.botNextNodeId = Event Player.botClosestNodeIdToBot; + "BOT CAN SEE TARGET POSITION AND NEXT NODE IS TARGET" + Else If( + Global.distanceMatrix[Event Player.botClosestNodeIdToBot][Event Player.botClosestNodeIdToTarget] == 1 && Is In Line of Sight( + Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.botTargetPosition + Vector(0, 2, 0), Barriers Do Not Block LOS)); + Event Player.botNextNodePosition = Event Player.botTargetPosition; + Abort; + "BOT CAN'T SEE NEXT NODE AND PREV NODE != REACHED NODE" + Else If(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), + Global.nodePositions[Event Player.botNextNodeId] + Vector(0, 2, 0), Barriers Do Not Block LOS) + == False && Event Player.botPreviousNodeId != Event Player.botClosestNodeIdToBot); + Event Player.botPreviousNodeId = Event Player.botClosestNodeIdToBot; + Event Player.botNextNodeId = Event Player.botClosestNodeIdToBot; + End; + Event Player.botNextNodePosition = Global.nodePositions[Event Player.botNextNodeId]; + } +} + +rule("SUBROUTINE: BOT - GET CLOSEST NODE ID AND POSITION TO TARGET") +{ + event + { + Subroutine; + BotGetClosestNodeIdToTarget; + } + + actions + { + Event Player.botTargetPosition = Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) + : Event Player.botTargetPosition; + Event Player.botClosestNodeIdToTarget = Index Of Array Value(Global.nodePositions, Sorted Array(Filtered Array( + Global.nodePositions, Is In Line of Sight(Event Player.botTargetPosition + Vector(0, 2, 0), Current Array Element, + Barriers Do Not Block LOS) == True), Distance Between(Event Player.botTargetPosition, Current Array Element))[0]); + } +} + +rule("BOT: PATH FINDING - START") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + (Event Player.botTargetPosition != -1 || Event Player.botTargetPlayer != -1) == True; + } + + actions + { + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - CANCEL") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.botIsPathFinding == True; + Event Player.botCancelPathFinding == True; + } + + actions + { + Start Rule(BotResetPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - LOST THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.botIsPathFinding == True; + (Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.botNextNodePosition + Vector(0, 2.500, 0), + Barriers Do Not Block LOS) == False && Speed Of In Direction(Event Player, Throttle Of(Event Player)) < 2) == True; + } + + actions + { + Wait(0.500, Abort When False); + "RESET PREV NODE ID TO INFORM BOT THAT IT LOST NEXT NODE" + Event Player.botPreviousNodeId = -1; + "TRY FIND NEW NEXT NODE" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodeId), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +rule("BOT: PATH FINDING - REACHED THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.botIsPathFinding == True; + Event Player.botClosestNodeIdToTarget >= 0; + (Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.botNextNodePosition), 0, Z Component Of(Event Player.botNextNodePosition))) < 0.850) == True; + } + + actions + { + Event Player.botPreviousNodeId = Event Player.botNextNodeId; + Event Player.botClosestNodeIdToBot = Event Player.botNextNodeId; + "BOT'S TARGET IS PLAYER" + If(Event Player.botTargetPlayer != -1); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + Event Player.botCurrentDistanceToTarget = Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of( + Position Of(Event Player))), Vector(X Component Of(Event Player.botTargetPosition), 0, Z Component Of( + Event Player.botTargetPosition))); + "BOT REACHED THE TARGET NODE OR TARGET POSITION" + If(Event Player.botNextNodeId == Event Player.botClosestNodeIdToTarget || Event Player.botCurrentDistanceToTarget <= 0.850); + "BOT DIDN'T REACH TARGET POSITION" + If(Event Player.botCurrentDistanceToTarget > 0.850); + Event Player.botNextNodePosition = Event Player.botTargetPosition; + Skip(6); + "BOT REACHED TARGET" + Else; + Call Subroutine(BotResetPathFinding); + Abort; + End; + End; + "CONTINUE FOLLOW PATH" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: GAME MODE INIT - WORKSHOP SETTINGS") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.isDebug = False; + Global.isDebugAINavigation = False; + Global.gateMaxHealth[0] = Workshop Setting Integer(Custom String("Defend The Castle Extended"), Custom String("GATE MAX HEALTH"), + 500, 100, 1000, 0); + Global.moneyMultiplier[0] = Workshop Setting Real(Custom String("Defend The Castle Extended"), Custom String( + "Money Multiplicator"), 1, 0.500, 2, 0); + Global.selfNanoWorkshopSetting = Workshop Setting Toggle(Custom String("Ana Self Nano"), Custom String( + "Ana can nano herself even if there are other players (only if no player targeted)"), False, 0); + } +} + +rule("GLOBAL: GAME MODE INIT - COMMON PROPERTIES") +{ + event + { + Ongoing - Global; + } + + actions + { + Create In-World Text(All Players(Team 1), Custom String( + "Defend The Castle Extended d143\r\nby ShuriZma#2349\r\nOriginal mode by HUKUTA94#2589\r\nDiscord: dc.shuri.gg\r\n{0}", + Custom String( + "Special Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents &\nJosbird for teaching me about Menus{0}", + Custom String(" \nPS: SHINGEN PLS COME BACK"))), Vector(165, 12, -46.500), 1.200, Clip Against Surfaces, Visible To, Color( + White), Default Visibility); + Global.gateRepairPosition = Vector(153, 8, -46.500); + Global.gatePosition = Vector(148.800, 6, -46.400); + Global.ballSpawnPositions = Array(Vector(104, 7, -46), Vector(106, 2, -31)); + Global.sniperPositions = Array(Vector(154, 18, -22.600), Vector(86, 12, -46.600), Vector(80.880, 11.300, -71.600), Vector(98, 9, + -19)); + Global.zenSpawnPositions = Array(Vector(79.500, 5, -100), Vector(90, 4, -88), Vector(65, 11, -70), Vector(85, 4, -68), Vector(96, + 2, -73), Vector(84, 7, -47), Vector(95, 9, -34), Vector(108, 1.700, -28), Vector(113, 7, -37), Vector(123, 5, -19), Vector(144, + 5, -19), Vector(123, 6, -39), Vector(123, 6, -61), Vector(129, 6, -30.500), Vector(135, 6, -63)); + Global.playerSpawnPositions = Array(Vector(160, 11, -53), Vector(158, 11, -53), Vector(160, 11, -39), Vector(158, 11, -39)); + Global.bigBossSpawnPositions = Array(Vector(78, 4, -84), Vector(95, 4, -82)); + Global.bastionTargetPositions = Array(Vector(131, 12, -62), Vector(115, 7, -46), Objective Position(2), Vector(136, 10, -27)); + Global.spawnPositionMaxId = 2; + Global.botOrisaTargetPosition = Vector(104, 7, -46); + Global.botEchoRespawnPosition = Vector(130, 23, -44); + Global.botEchoTeleportPositions = Array(Vector(88, 23, -79), Vector(108, 18, -27)); + Global.defaultHeroBotsPool = Array(Hero(Zenyatta), Hero(Widowmaker), Null, Hero(Bastion), Hero(Echo), Hero(Bastion)); + Global.zenRespawnTime = 10; + Global.gameLogicCountOfUniqueHeroes = 5; + Global.lastBoss = Array(Null, Null, Null, Null); + Create Effect(All Players(Team 1), Ring, Color(Sky Blue), Vector(186, 11, -46.500), 9, Visible To Position and Radius); + Create Effect(All Players(Team 1), Ring, Color(Yellow), Vector(159, 11, -46.500), 2, Visible To Position and Radius); + } +} + +disabled rule("=== TEAM UPGRADES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: TEAM UPGRADES - INIT") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.upgradeMaxAmmoMaxValue[0] = 150; + Global.upgradeMaxAmmoMaxValue[1] = 300; + Global.upgradeMaxAmmoMaxValue[2] = 500; + Global.upgradeCriticalDamageMaxValue[0] = 10; + Global.upgradeCriticalDamageMaxValue[1] = 5; + Global.upgradeCriticalDamageMaxValue[2] = 10; + Global.upgradePlayerMaxHealthMaxValue[0] = 3000; + Global.upgradePlayerMaxHealthMaxValue[1] = 7000; + Global.upgradePlayerMaxHealthMaxValue[2] = 12000; + Global.upgradeGateMaxHealthMaxValue[0] = Round To Integer(Global.gateMaxHealth[0] + Global.gateMaxHealth[0] * 0.500, Up) > 1000 ? 1000 : Round To Integer(Global.gateMaxHealth[0] + Global.gateMaxHealth[0] * 0.500, Up); + Global.upgradeGateMaxHealthMaxValue[1] = Round To Integer(Global.upgradeGateMaxHealthMaxValue[0] + Global.upgradeGateMaxHealthMaxValue[0] * 0.500, Up); + Global.upgradeGateMaxHealthMaxValue[2] = Round To Integer(Global.upgradeGateMaxHealthMaxValue[1] + Global.upgradeGateMaxHealthMaxValue[1] * 0.500, Up); + Abort If(Global.isDebug == False); + Global.upgradeMaxAmmoMaxValue[0] = 1; + Global.upgradeCriticalDamageMaxValue[0] = 1; + Global.upgradePlayerMaxHealthMaxValue[0] = 1; + Global.upgradeGateMaxHealthMaxValue[0] = 1; + Global.upgradeMaxAmmoMaxValue[1] = 1; + Global.upgradeCriticalDamageMaxValue[1] = 1; + Global.upgradePlayerMaxHealthMaxValue[1] = 1; + Global.upgradeGateMaxHealthMaxValue[1] = 1; + Global.upgradeMaxAmmoMaxValue[2] = 1; + Global.upgradeCriticalDamageMaxValue[2] = 1; + Global.upgradePlayerMaxHealthMaxValue[2] = 1; + Global.upgradeGateMaxHealthMaxValue[2] = 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[0]) == True; + } + + actions + { + Play Effect(All Players(Team 1), Good Explosion, Color(Green), Global.gatePosition, 5); + Play Effect(All Players(Team 1), Buff Impact Sound, Color(Green), Global.gatePosition, 100); + Global.gateMaxHealth[0] = Round To Integer(Global.gateMaxHealth[0] + Global.gateMaxHealth[0] * 0.500, Up); + Global.gateHealth = Global.gateMaxHealth[0]; + Destroy HUD Text(Global.upgradeGateMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X GATE REPAIR"), Custom String("REPAIR GATE {0}/{1} HP", Global.upgradeGateMaxHealthValue, Global.upgradeGateMaxHealthMaxValue[1]), + Left, 12, Color(Blue), Color(Blue), Color(Blue), Visible To and String, Default Visibility); + Global.upgradeGateMaxHealthHudId[1] = Last Text ID; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1]) == True; + } + + actions + { + Play Effect(All Players(Team 1), Good Explosion, Color(Green), Global.gatePosition, 5); + Play Effect(All Players(Team 1), Buff Impact Sound, Color(Green), Global.gatePosition, 100); + Destroy HUD Text(Global.upgradeGateMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X AUTO-REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.upgradeGateMaxHealthValue, Global.upgradeGateMaxHealthMaxValue[2]), Left, 12, + Color(Blue), Color(Blue), Color(Blue), Visible To and String, Default Visibility); + Global.upgradeGateMaxHealthHudId[2] = Last Text ID; + Global.gateHealth = Global.gateMaxHealth[0]; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 3 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2]) == True; + } + + actions + { + Play Effect(All Players(Team 1), Good Explosion, Color(Green), Global.gatePosition, 5); + Play Effect(All Players(Team 1), Buff Impact Sound, Color(Green), Global.gatePosition, 100); + Destroy HUD Text(Global.upgradeGateMaxHealthHudId[2]); + Global.gateHealth = Global.gateMaxHealth[0]; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - PLAYER'S MAX HEALTH - DEALT HEALING") +{ + event + { + Player Received Healing; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Global.upgradePlayerMaxHealthValue < Global.upgradePlayerMaxHealthMaxValue[2]; + } + + actions + { + Global.upgradePlayerMaxHealthValue += Event Healing; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[0]) == True; + } + + actions + { + Destroy HUD Text(Global.upgradePlayerMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("Up You Go: You respawn twice as fast"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.upgradePlayerMaxHealthValue, Down), + Global.upgradePlayerMaxHealthMaxValue[1]), Left, 13, Color(Blue), Color(Blue), Color(Blue), Visible To and String, + Default Visibility); + Global.upgradePlayerMaxHealthHudId[1] = Last Text ID; + For Global Variable(loopIterator, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator]), 1); + Play Effect(All Players(Team 1), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator]), 100); + End; + Global.maxHealthDone = 50; + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[0]) == True; + } + + actions + { + Call Subroutine(UpdatePlayerStats); + } +} + +rule("GLOBAL: UPGRADE - PERK UP YOU GO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[1]) == True; + } + + actions + { + Destroy HUD Text(Global.upgradePlayerMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +100%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.upgradePlayerMaxHealthValue, Down), + Global.upgradePlayerMaxHealthMaxValue[2]), Left, 13, Color(Blue), Color(Blue), Color(Blue), Visible To and String, + Default Visibility); + Global.upgradePlayerMaxHealthHudId[2] = Last Text ID; + Set Respawn Max Time(All Players(Team 1), 5); + Heal(All Players(Team 1), Null, 9999); + For Global Variable(loopIterator, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator]), 1); + Play Effect(All Players(Team 1), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator]), 100); + End; + Global.perk[2] = 1; + Create HUD Text(All Players(Team 1), Null, Custom String("Up You Go"), Null, Left, 917, Color(White), Color(Green), Color( + White), Visible To and String, Default Visibility); + All Players(Team 1).abilityHUD[17] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[2]) == True; + } + + actions + { + Destroy HUD Text(Global.upgradePlayerMaxHealthHudId[2]); + For Global Variable(loopIterator, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator]), 1); + Play Effect(All Players(Team 1), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator]), 100); + End; + Global.maxHealthDone = 150; + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[2]) == True; + } + + actions + { + Call Subroutine(UpdatePlayerStats); + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Hero Of(Victim) == Hero(Widowmaker); + Global.upgradeCriticalDamageValue < Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.upgradeCriticalDamageValue += 1; + } +} + +rule("GLOBAL: UPGRADE - CRITICAL DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.upgradeCriticalDamageValue >= Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Destroy HUD Text(Global.upgradeCriticalDamageHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("Sharpshooter: 40% more damage at >15m"), Custom String( + "KILL ECHO {0}/{1}", Global.upgradePerkSharpshooterValue, Global.upgradeCriticalDamageMaxValue[1]), Left, 14, Color(Blue), + Color(Blue), Color(Blue), Visible To and String, Default Visibility); + Global.upgradeCriticalDamageHudId[1] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - PERK SHARPSHOOTER - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Echo); + Global.upgradePerkSharpshooterValue < Global.upgradeCriticalDamageMaxValue[1]; + Global.upgradeCriticalDamageValue >= Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.upgradePerkSharpshooterValue += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK SHARPSHOOTER - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.upgradePerkSharpshooterValue >= Global.upgradeCriticalDamageMaxValue[1]; + } + + actions + { + Destroy HUD Text(Global.upgradeCriticalDamageHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("-10% BOSS HEALTH"), Custom String("KILL Bosses {0}/{1}", + Global.upgradeBossHealthValue, Global.upgradeCriticalDamageMaxValue[2]), Left, 14, Color(Blue), Color(Blue), Color(Blue), + Visible To and String, Default Visibility); + Global.upgradeCriticalDamageHudId[2] = Last Text ID; + Global.perk[0] = 1; + Create HUD Text(All Players(Team 1), Null, Custom String("Sharpshooter"), Null, Left, 918, Color(White), Color(Green), Color( + White), Visible To and String, Default Visibility); + All Players(Team 1).abilityHUD[18] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - -10% BOSS HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2]; + } + + actions + { + Destroy HUD Text(Global.upgradeCriticalDamageHudId[2]); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - MAX AMMO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[0]) == True; + } + + actions + { + Destroy HUD Text(Global.upgradeMaxAmmoHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("+50% DAMAGE"), Custom String("KILL ENEMIES: {0}/{1}", + Global.upgradeMaxAmmoValue, Global.upgradeMaxAmmoMaxValue[1]), Left, 15, Color(Blue), Color(Blue), Color(Blue), + Visible To and String, Default Visibility); + Global.upgradeMaxAmmoHudId[1] = Last Text ID; + For Global Variable(loopIterator, 0, Count Of(All Players(Team 1)), 1); + Set Max Ammo(All Players(Team 1)[Global.loopIterator], 0, Max Ammo(All Players(Team 1)[Global.loopIterator], 0) * 2); + Set Max Ammo(All Players(Team 1)[Global.loopIterator], 1, Max Ammo(All Players(Team 1)[Global.loopIterator], 1) * 2); + Set Ammo(All Players(Team 1)[Global.loopIterator], 0, Max Ammo(All Players(Team 1)[Global.loopIterator], 0)); + Set Ammo(All Players(Team 1)[Global.loopIterator], 1, Max Ammo(All Players(Team 1)[Global.loopIterator], 1)); + End; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - +50% DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Destroy HUD Text(Global.upgradeMaxAmmoHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("Bulletstorm: Your weapon can hold unlimited ammo"), + Custom String("KILL ENEMIES: {0}/{1}", Global.upgradeMaxAmmoValue, Global.upgradeMaxAmmoMaxValue[2]), Left, 15, Color(Blue), + Color(Blue), Color(Blue), Visible To and String, Default Visibility); + Global.upgradeMaxAmmoHudId[2] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - +50% DAMAGE - DONE") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Call Subroutine(UpdatePlayerStats); + } +} + +rule("GLOBAL: UPGRADE - PERK BULLETSTORM - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[2]) == True; + } + + actions + { + Destroy HUD Text(Global.upgradeMaxAmmoHudId[2]); + Global.perk[1] = 1; + Create HUD Text(All Players(Team 1), Null, Custom String("Bulletstorm"), Null, Left, 919, Color(White), Color(Green), Color( + White), Visible To and String, Default Visibility); + All Players(Team 1).abilityHUD[19] = Last Text ID; + Global.challengeCount += 1; + } +} + +disabled rule("=== GAME PHASES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: ASSEMBLING PHASE - MAKE CHALLENGE HUDS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Assembling Heroes == True; + } + + actions + { + If(Global.isDebug); + Set Match Time(1); + Else; + Disable Inspector Recording; + Set Match Time(10); + End; + Create In-World Text(All Players(Team 1), Custom String("{0}{1}\nREPAIR\n {2}", Custom String("{0}{1}{2}", Hero Icon String(Hero( + Torbjörn)), Hero Icon String(Hero(Brigitte)), Hero Icon String(Hero(Reinhardt))), Hero Icon String(Hero(Symmetra)), + Ability Icon String(Hero(Reinhardt), Button(Primary Fire))), Global.gatePosition + Vector(0, 1.400, 0), 1.200, Do Not Clip, + Visible To, Color(White), Default Visibility); + Create HUD Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[1] == 0), Null, Custom String( + "HOLD {0} - Reload to open the shop", Input Binding String(Button(Reload))), Null, Top, 1000, Color(White), Color( + Yellow), Color(White), Visible To and String, Default Visibility); + Wait Until(Is Game In Progress == True, 9999); + Create HUD Text(All Players(Team 1), Null, Custom String("TEAM CHALLENGES {0}/12", Global.challengeCount), Null, Left, 11, Color( + White), Color(Red), Color(White), Visible To and String, Default Visibility); + "UPGRADE - GATE'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String( + "GATE'S MAX HEALTH: {0} HP", Round To Integer(Global.gateMaxHealth[0] + Global.gateMaxHealth[0] * 0.750, Up)), Custom String("REPAIR GATE {0}/{1} HP", + Global.upgradeGateMaxHealthValue, Global.upgradeGateMaxHealthMaxValue[0]), Left, 12, Color(Blue), Color(Blue), Color(Blue), + Visible To and String, Default Visibility); + Global.upgradeGateMaxHealthHudId[0] = Last Text ID; + "UPGRADE - PLAYER'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +50%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.upgradePlayerMaxHealthValue, Down), + Global.upgradePlayerMaxHealthMaxValue[0]), Left, 13, Color(Blue), Color(Blue), Color(Blue), Visible To and String, + Default Visibility); + Global.upgradePlayerMaxHealthHudId[0] = Last Text ID; + "UPGRADE - CRITICAL DAMAGE" + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("CRITICAL DAMAGE 150%"), Custom String( + "KILL WIDOW WITH HEADSHOT: {0}/{1}", Global.upgradeCriticalDamageValue, Global.upgradeCriticalDamageMaxValue[0]), Left, 14, + Color(Blue), Color(Blue), Color(Blue), Visible To and String, Default Visibility); + Global.upgradeCriticalDamageHudId[0] = Last Text ID; + "UPGRADE - MAX AMMO" + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("MAX AMMO 200%"), Custom String("KILL ENEMIES: {0}/{1}", + Global.upgradeMaxAmmoValue, Global.upgradeMaxAmmoMaxValue[0]), Left, 15, Color(Blue), Color(Blue), Color(Blue), + Visible To and String, Default Visibility); + Global.upgradeMaxAmmoHudId[0] = Last Text ID; + } +} + +rule("GLOBAL: SETUP PHASE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + If(Global.isDebug); + Set Match Time(1); + Else; + Pause Match Time; + Create HUD Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[1] == 0), Null, Custom String( + "PRESS {0} - INTERACT TO VOTE FOR START | {1}/{2}", Input Binding String(Button(Interact)), Count Of(Filtered Array( + All Players(Team 1), Current Array Element.vote[0] == 1)), Count Of(All Players(Team 1))), Null, Top, 50, Color(White), + Color(Red), Color(White), Visible To and String, Default Visibility); + Global.globalHUDs[0] = Last Text ID; + Set Match Time(10); + While(Count Of(Filtered Array(All Players(Team 1), Current Array Element.vote[0] == 1)) <= Count Of(All Players(Team 1)) / 2); + Filtered Array(All Players(Team 1), Is Button Held(Current Array Element, Button(Interact))).vote[0] = 1; + Wait(0.100, Ignore Condition); + End; + Destroy HUD Text(Global.globalHUDs[0]); + Unpause Match Time; + End; + Set Objective Description(All Players(All Teams), Custom String("DEFEND GATE"), Visible To and String); + } +} + +rule("GLOBAL: GAME IN PROGRESS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + } + + actions + { + Set Match Time(3599); + Pause Match Time; + Disable Built-In Game Mode Scoring; + Disable Built-In Game Mode Announcer; + Disable Built-In Game Mode Completion; + Disable Game Mode HUD(All Players(All Teams)); + Disable Game Mode In-World UI(All Players(All Teams)); + Global.gateHealth = Global.gateMaxHealth[0]; + Global.gateHealthChase = Global.gateHealth; + Global.gateProgressBarColorComponent = 255; + Global.gateProgressBarColorCurrent = Color(White); + Create Progress Bar HUD Text(All Players(Team 1), Global.gateHealthChase * 100 / Global.gateMaxHealth[0], Custom String( + "GATE {0}/{1}", Global.gateHealth, Global.gateMaxHealth[0]), Top, 1, Global.gateProgressBarColorCurrent, Color(White), + Visible To Values and Color, Default Visibility); + Create HUD Text(All Players(Team 1), Null, Custom String("SURVIVED TIME: {0}:{1}", Global.timeMinutes, + Global.timeSeconds < 10 ? Custom String("0{0}", Global.timeSeconds) : Global.timeSeconds), Null, Top, 2, Color(White), Color(White), + Color(White), Visible To and String, Default Visibility); + } +} + +disabled rule("=== GAME - MAIN LOGIC ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: DEFEAT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.isDebug == False; + Global.gateHealth <= 0; + } + + actions + { + Declare Team Victory(Team 2); + } +} + +rule("GLOBAL: TIMER - MAIN GAME LOOP") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + } + + actions + { + Wait(1, Ignore Condition); + Global.timeSeconds += 1; + If(Global.timeSeconds == 60); + Global.timeSeconds = 0; + Global.timeMinutes += 1; + Global.time5Minutes = Round To Integer(Global.timeMinutes / 5, Down); + Global.time10Minutes = Round To Integer(Global.timeMinutes / 10, Down); + Global.spawnPositionMaxId += 1; + Else If(Global.timeSeconds == 30); + Global.spawnPositionMaxId += 1; + End; + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GAME LOGIC - SET BOT PROPERTIES") +{ + event + { + Subroutine; + GameLogicSetBotProperties; + } + + actions + { + Abort If(Event Player.botIsOrisaChild == True); + If(Global.timeMinutes >= 10); + If(Filtered Array(Global.lastBoss, Current Array Element == Hero Of(Event Player)) == False); + If(Global.activeBoss == False); + Global.activeBoss = Event Player; + Event Player.isBoss[0] = 1; + End; + End; + End; + End; + "PROPERTIES BY DEFAULT" + Set Gravity(Event Player, 100); + Set Damage Dealt(Event Player, 100); + Set Respawn Max Time(Event Player, 10); + Start Scaling Player(Event Player, 1, False); + "INDIVIDUAL HERO'S PROPERTIES" + If(Hero Of(Event Player) == Hero(Zenyatta)); + If(Event Player.isBoss[0] == 1); + Set Move Speed(Event Player, 30); + Set Max Health(Event Player, 10 * (100 + 10 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 1.500, False); + Else; + If(20 + 3 * Number Of Players(Team 1) + 3 * Global.timeMinutes > 75); + Set Move Speed(Event Player, 75); + Else; + Set Move Speed(Event Player, 20 + 3 * Count Of(All Players(Team 1)) + 3 * Global.timeMinutes); + End; + Set Max Health(Event Player, 100 + 10 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + If(Event Player.isBoss[0] == 1); + Set Move Speed(Event Player, 20); + Set Max Health(Event Player, 5 * (70 + 10 * Count Of(All Players(Team 1)) + + 10 * Global.timeMinutes + 25 * Global.time5Minutes + 30 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else If(Event Player.isBoss[1] == 1); + Set Move Speed(Event Player, 50); + Set Max Health(Event Player, 40 + 7 * Count Of(All Players(Team 1)) + + 5 * Global.timeMinutes + 20 * Global.time5Minutes + 15 * Global.time10Minutes); + Start Scaling Player(Event Player, 0.500, False); + Else; + If(30 + Global.timeMinutes + 2.500 * Global.time5Minutes > 40); + Set Move Speed(Event Player, 40); + Else; + Set Move Speed(Event Player, 30 + Global.timeMinutes + 2.500 * Global.time5Minutes); + End; + Set Ultimate Charge(Event Player, 0); + Set Max Health(Event Player, 70 + 10 * Count Of(All Players(Team 1)) + + 10 * Global.timeMinutes + 25 * Global.time5Minutes + 30 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + If(Event Player.isBoss[0] == 1); + Set Damage Dealt(Event Player, 2 * (55 + 15 * Count Of(All Players(Team 1)) + + 25 * Global.time5Minutes + 30 * Global.time10Minutes)); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 5 * (50 + 25 * Count Of(All Players(Team 1)) + + 5 * Global.timeMinutes + 15 * Global.time5Minutes + 25 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Event Player.botCounter = 0; + Set Damage Dealt(Event Player, 55 + 15 * Count Of(All Players(Team 1)) + 25 * Global.time5Minutes + 30 * Global.time10Minutes); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 50 + 25 * Count Of(All Players(Team 1)) + + 5 * Global.timeMinutes + 15 * Global.time5Minutes + 25 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Bastion)); + If(Event Player.isBoss[0] == 1); + Set Move Speed(Event Player, 50); + Set Damage Dealt(Event Player, 55 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Minutes + 5 * Global.time10Minutes); + Start Scaling Player(Event Player, 3, False); + Set Max Health(Event Player, 5 * (125 + 150 * Count Of(All Players(Team 1)) + + 20 * Global.timeMinutes + 35 * Global.time5Minutes + 45 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Else If(Event Player.isBoss[1] == 1); + Set Move Speed(Event Player, 100); + Set Damage Dealt(Event Player, 20 + 2 * Count Of(All Players(Team 1)) + 2 * Global.time5Minutes + 5 * Global.time10Minutes); + Set Max Health(Event Player, 60 + 60 * Count Of(All Players(Team 1)) + + 10 * Global.timeMinutes + 20 * Global.time5Minutes + 20 * Global.time10Minutes); + Else; + Set Move Speed(Event Player, 80); + Set Damage Dealt(Event Player, 55 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Minutes + 5 * Global.time10Minutes); + Start Scaling Player(Event Player, 2, False); + Set Max Health(Event Player, 125 + 150 * Count Of(All Players(Team 1)) + + 20 * Global.timeMinutes + 35 * Global.time5Minutes + 45 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Orisa)); + If(Event Player.isBoss[0] == 1); + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 5 * (200 + Count Of(All Players(Team 1)) * 70 + 50 * Global.time5Minutes + 75 * Global.time10Minutes) + * (Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Set Move Speed(Event Player, 20 + 5 * Global.time5Minutes); + Else; + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 200 + Count Of(All Players(Team 1)) * 70 + 50 * Global.time5Minutes + 75 * Global.time10Minutes); + Set Move Speed(Event Player, 80 + 5 * Global.time5Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Echo)); + If(Event Player.isBoss[0] == 1); + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 50 + 5 * Global.time5Minutes); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 5 * (70 + 25 * Count Of(All Players(Team 1)) + + 15 * Global.timeMinutes + 25 * Global.time5Minutes + 40 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 110 + 5 * Global.time5Minutes); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 70 + 25 * Count Of(All Players(Team 1)) + + 15 * Global.timeMinutes + 25 * Global.time5Minutes + 40 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + If(Event Player.isBoss[0] == 1); + Start Scaling Player(Event Player, 1.500, False); + Set Move Speed(Event Player, 50); + Set Damage Dealt(Event Player, 80 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Minutes + 8 * Global.time10Minutes); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 5 * (45 + 25 * Count Of(All Players(Team 1)) + + 15 * Global.timeMinutes + 25 * Global.time5Minutes + 40 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Else If(Event Player.isBoss[1] == 1); + Start Scaling Player(Event Player, 0.500, False); + Set Move Speed(Event Player, 100); + Set Damage Dealt(Event Player, 30 + 2 * Count Of(All Players(Team 1)) + 2 * Global.time5Minutes + 5 * Global.time10Minutes); + Set Max Health(Event Player, 20 + 10 * Count Of(All Players(Team 1)) + + 10 * Global.timeMinutes + 10 * Global.time5Minutes + 20 * Global.time10Minutes); + Else; + Set Move Speed(Event Player, 90); + Set Damage Dealt(Event Player, 80 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Minutes + 8 * Global.time10Minutes); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 45 + 25 * Count Of(All Players(Team 1)) + + 15 * Global.timeMinutes + 25 * Global.time5Minutes + 40 * Global.time10Minutes); + End; + End; + Wait(0.250, Ignore Condition); + "FILL HEALTH" + Heal(Event Player, Null, 100000); + } +} + +disabled rule("=== GATE ===") +{ + event + { + Ongoing - Global; + } +} + +rule("Subroutine: UPDATE PLAYER STATS") +{ + event + { + Subroutine; + UpdatePlayerStats; + } + + actions + { + Event Player.damageBoost[0] = (Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[1] ? 50 : 0) + + Event Player.abilities[13] * 5 + Event Player.damageBoost[1]; + Set Damage Dealt(Event Player, Event Player.baseStats[0] + Event Player.damageBoost); + Event Player.playerHealth = Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.baseStats[1] + Event Player.playerHealth); + Event Player.healBoost[0] = Event Player.healBoost[1] + Event Player.abilities[15] * 5; + Set Healing Dealt(Event Player, Event Player.baseStats[2] + Event Player.healBoost[0]); + Set Move Speed(Event Player, Event Player.baseStats[3] + Event Player.speedBoost); + } +} + +rule("Subroutine: GATE REPAIR") +{ + event + { + Subroutine; + GateRepair; + } + + actions + { + "UPGRADE - GATE'S MAX HEALTH" + If(Global.upgradeGateMaxHealthValue < Global.upgradeGateMaxHealthMaxValue[2]); + If(Global.gateMaxHealth[0] - Global.gateHealth > (Hero Of(Event Player) == Hero(Symmetra) ? 2 : 10) * ( + Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1] ? 2 : 1) * (Event Player.isNanoed == 1 ? 2 : 1)); + Global.upgradeGateMaxHealthValue += (Hero Of(Event Player) == Hero(Symmetra) ? 2 : 10) * ( + Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1] ? 2 : 1) * (Event Player.isNanoed == 1 ? 2 : 1); + Else; + Global.upgradeGateMaxHealthValue += Global.gateMaxHealth[0] - Global.gateHealth; + End; + End; + "HEAL GATE" + If(Global.gateMaxHealth[0] - Global.gateHealth > (Hero Of(Event Player) == Hero(Symmetra) ? 2 : 10) * ( + Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1] ? 2 : 1) * (Event Player.isNanoed == 1 ? 2 : 1)); + Global.gateHealth += (Hero Of(Event Player) == Hero(Symmetra) ? 2 : 10) * ( + Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1] ? 2 : 1) * (Event Player.isNanoed == 1 ? 2 : 1); + Else; + Global.gateHealth += Global.gateMaxHealth[0] - Global.gateHealth; + End; + "CHARGE ULTIMATE" + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + } +} + +rule("GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + ((Hero Of(Event Player) == Hero(Torbjörn) && Weapon(Event Player) == 2) || (Hero Of(Event Player) == Hero(Reinhardt) || Hero Of( + Event Player) == Hero(Brigitte) || Hero Being Duplicated(Event Player) == Hero(Reinhardt) || Hero Of(Event Player) == Hero( + Symmetra))) == True; + Is Firing Primary(Event Player) == True; + Global.gateHealth < Global.gateMaxHealth[0]; + Is In View Angle(Event Player, Global.gateRepairPosition, 30) == True; + Distance Between(Position Of(Event Player), Global.gatePosition) < (Hero Of(Event Player) == Hero(Brigitte) ? 5 : (Hero Of( + Event Player) == Hero(Symmetra) ? 12 : 3.500)); + } + + actions + { + If(Hero Of(Event Player) == Hero(Reinhardt)); + Wait(0.100, Ignore Condition); + End; + Call Subroutine(GateRepair); + If(Hero Of(Event Player) == Hero(Torbjörn)); + Wait(Is Using Ability 2(Event Player) == True ? 0.350 : 0.700, Ignore Condition); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Wait(0.850, Ignore Condition); + Else If(Hero Of(Event Player) == Hero(Symmetra)); + Wait(0.100, Ignore Condition); + Else; + Wait(0.500, Ignore Condition); + End; + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GATE PROGRESS BAR COLOR") +{ + event + { + Subroutine; + GateProgressBarColor; + } + + actions + { + Stop Chasing Global Variable(gateHealthChase); + Chase Global Variable Over Time(gateHealthChase, Global.gateHealth, 0.100, Destination and Duration); + "GATE WAS DAMAGED" + If(Global.gateHealth < Global.gateHealthEvent); + For Global Variable(loopIterator, 0, 3, 1); + Global.gateProgressBarColorCurrent = Color(Red); + Wait(0.100, Ignore Condition); + Global.gateProgressBarColorCurrent = Color(White); + Wait(0.100, Ignore Condition); + End; + "GATE WAS REPAIRED" + Else; + Global.gateProgressBarColorCurrent = Color(Green); + Wait(0.100, Ignore Condition); + Global.gateProgressBarColorCurrent = Color(Yellow); + Wait(0.100, Ignore Condition); + End; + Global.gateHealthEvent = Global.gateHealth; + Global.gateProgressBarColorComponent = Global.gateHealth * 255 / Global.gateMaxHealth[0]; + Global.gateProgressBarColorCurrent = Custom Color(255, Global.gateProgressBarColorComponent, Global.gateProgressBarColorComponent, + 255); + } +} + +disabled rule("=== COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("ALL: INIT") +{ + event + { + Player Joined Match; + All; + All; + } + + actions + { + "ALL (COMMON) INIT" + Event Player.isDead = True; + Disable Kill Feed(Event Player); + Disable Game Mode In-World UI(Event Player); + Disable Death Spectate Target HUD(Event Player); + "BOT INIT" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotInit); + "PLAYER INIT" + Else; + Call Subroutine(PlayerInit); + End; + } +} + +rule("SUBROUTINE: BOT - INIT") +{ + event + { + Subroutine; + BotInit; + } + + actions + { + "INIT VARS" + Event Player.hasBadStatus = False; + Event Player.isRespawning = False; + Event Player.botDoesUniqueBehaviour = False; + Event Player.botEventPosition = Vector(9999, 999, 9999); + "DISABLE ALL FOR BOT" + Disable Hero HUD(Event Player); + Disable Messages(Event Player); + Disable Text Chat(Event Player); + Disable Scoreboard(Event Player); + Disable Game Mode HUD(Event Player); + Disable Death Spectate All Players(Event Player); + Disable Voice Chat(Event Player, True, True, True); + "INIT AI NAVIGATION VARS" + Call Subroutine(BotResetPathFinding); + } +} + +rule("SUBROUTINE: PLAYER - INIT") +{ + event + { + Subroutine; + PlayerInit; + } + + actions + { + Call Subroutine(UpdatePlayerStats); + If(Is Game In Progress); + Disable Game Mode HUD(Event Player); + End; + } +} + +rule("ALL: RESPAWN") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + (Hero Of(Event Player) != Event Player.currentHero || Event Player.isDead == True) == True; + } + + actions + { + Event Player.isDead = False; + "BOT RESPAWN" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotRespawn); + If(Global.isDebugAINavigation); + Create Beam Effect(All Players(All Teams), Good Beam, Eye Position(Event Player), Event Player.botNextNodePosition, Color(Green), + Visible To Position and Radius); + End; + "PLAYER RESPAWN" + Else; + Call Subroutine(PlayerRespawn); + End; + "MUST BE AFTER ALL RESPAWN SUBROUTINES!" + Event Player.currentHero = Hero Of(Event Player); + } +} + +rule("SUBROUTINE: BOT - RESPAWN") +{ + event + { + Subroutine; + BotRespawn; + } + + actions + { + "RESET COMMON PROPERTIES" + Event Player.isRespawning = True; + Enable Nameplates(Event Player, All Players(Team 1)); + Call Subroutine(BotResetPathFinding); + Call Subroutine(GameLogicSetBotProperties); + "INDIVIDUAL HERO'S RESPAWN SCRIPTS" + If(Hero Of(Event Player) == Hero(Bastion)); + Call Subroutine(BotBastionRespawn); + Else If(Hero Of(Event Player) == Hero(Zenyatta)); + Call Subroutine(BotZenyattaRespawn); + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + Call Subroutine(BotWidowRespawn); + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Call Subroutine(BotBallRespawn); + Else If(Hero Of(Event Player) == Hero(Orisa)); + Call Subroutine(BotOrisaRespawn); + Else If(Hero Of(Event Player) == Hero(Echo)); + Call Subroutine(BotEchoRespawn); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Call Subroutine(BotReinRespawn); + End; + Event Player.isRespawning = False; + } +} + +rule("SUBROUTINE: PLAYER - RESPAWN") +{ + event + { + Subroutine; + PlayerRespawn; + } + + actions + { + "TEAM CHALLENGE - MAX AMMO" + If(Hero Of(Event Player) != Event Player.currentHero && Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[0]); + Set Max Ammo(Event Player, 0, Ammo(Event Player, 0) * 2); + Set Max Ammo(Event Player, 1, Ammo(Event Player, 1) * 2); + Set Ammo(Event Player, 0, Max Ammo(Event Player, 0)); + Set Ammo(Event Player, 1, Max Ammo(Event Player, 1)); + End; + "PLAYER RESPAWN" + Set Status(Event Player, Null, Phased Out, 3); + Set Facing(Event Player, Vector(-1, 0, 0), To World); + If(Ability Cooldown(Players On Hero(Hero(Mercy), Team 1), Button(Ability 2)) >= 30 * (Players On Hero(Hero(Mercy), Team 1) + .abilities[6] ? Players On Hero(Hero(Mercy), Team 1).abilities[6] * 0.250 : 1) - 1); + Wait(0.250, Ignore Condition); + Teleport(Event Player, Event Player.deathPosition); + Else; + Teleport(Event Player, Global.playerSpawnPositions[Slot Of(Event Player) == Count Of(Global.playerSpawnPositions) ? Random Integer( + 0, Count Of(Global.playerSpawnPositions) - 1) : Slot Of(Event Player)]); + End; + Call Subroutine(UpdatePlayerStats); + } +} + +rule("PLAYER: DEATH") +{ + event + { + Player Died; + Team 1; + All; + } + + actions + { + If(Hero Of(Event Player) == Hero(Roadhog)); + Event Player.abilities[8] -= 1; + Wait(Global.perk[2] ? 5 : 10, Ignore Condition); + Event Player.abilities[8] += 1; + End; + Event Player.deathPosition = Position Of(Event Player); + Event Player.isDead = True; + } +} + +rule("BOT: DEATH") +{ + event + { + Player Died; + Team 2; + All; + } + + actions + { + Event Player.deathPosition = Position Of(Event Player); + If(Event Player.isBoss[0] == 1); + If( + Global.upgradePerkSharpshooterValue >= Global.upgradeCriticalDamageMaxValue[1] && Global.upgradeBossHealthValue < Global.upgradeCriticalDamageMaxValue[2]); + Global.upgradeBossHealthValue += 1; + End; + Event Player.isBoss[0] = 0; + Global.activeBoss = Null; + Else If(Event Player.isBoss[1] == 1); + If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Destroy Effect(Event Player.botEffects[0]); + End; + Wait(1, Ignore Condition); + Start Forcing Player To Be Hero(Event Player, Random Integer(1, 100) > 50 ? Hero(Reinhardt) : (Random Integer(1, 100) > 33 ? Hero( + Wrecking Ball) : (Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Zenyatta))) > 0 ? Hero( + Wrecking Ball) : Hero(Bastion)))); + End; + Event Player.isDead = True; + Event Player.hasBadStatus = False; + Event Player.botDoesUniqueBehaviour = False; + Disable Nameplates(Event Player, All Players(Team 1)); + "BOT HAS 1 EFFECT IN VAR (NOT ARRAY)" + Skip If(!Entity Exists(Event Player.botEffects), 1); + Destroy Effect(Event Player.botEffects); + "BOT HAS MORE THEN 1 EFFECT IN VAR (ARRAY)" + Skip If(Count Of(Event Player.botEffects) == 0, 3); + For Player Variable(Event Player, botLoopIterator1, 0, Count Of(Event Player.botEffects), 1); + Destroy Effect(Event Player.botEffects[Event Player.botLoopIterator1]); + End; + } +} + +disabled rule("=== BOT COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BAD STATUS") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.hasBadStatus == False; + (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + Event Player.hasBadStatus = True; + "PROCESS BAD STATUS" + If(Hero Of(Event Player) == Hero(Widowmaker)); + Start Rule(BotWidowBadStatus, Do Nothing); + End; + Wait Until(!Has Status(Event Player, Knocked Down) && !Has Status(Event Player, Asleep) && !Has Status(Event Player, Frozen) + && !Has Status(Event Player, Stunned), 15); + Event Player.hasBadStatus = False; + } +} + +rule("SUBROUTINE: BOT - LANDING FROM SKY") +{ + event + { + Subroutine; + BotLandingFromSky; + } + + actions + { + Stop Throttle In Direction(Event Player); + "SET RESPAWN POSITION" + Event Player.botEventPosition = Random Value In Array(Global.bigBossSpawnPositions); + "CREATE EFFECTS" + Create Effect(All Players(Team 1), Light Shaft, Color(Red), Event Player.botEventPosition, 3, Visible To); + Event Player.botEffects[0] = Last Created Entity; + "RESPAWN IN LIGHT SHAFT EFFECT" + Teleport(Event Player, Event Player.botEventPosition + Vector(0, 25, 0)); + Wait(0.100, Ignore Condition); + "SLOW LANDING" + Set Gravity(Event Player, 50); + While(Is In Air(Event Player) == True); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(Orange), Position Of(Event Player) + Vector(0, -2.700, 0), 2); + Wait(0.250, Ignore Condition); + End; + Set Gravity(Event Player, 100); + Destroy Effect(Event Player.botEffects[0]); + "LANDING EFFECTS" + Play Effect(All Players(Team 1), Wrecking Ball Piledriver Impact Effect, Custom Color(105, 87, 46, 255), Position Of(Event Player), + 8); + Play Effect(All Players(Team 1), Doomfist Meteor Strike Impact Sound, Color(White), Position Of(Event Player), 150); + } +} + +rule("SUBROUTINE: BOT - APPEAR FROM UNDERGROUND") +{ + event + { + Subroutine; + BotAppearFromUnderground; + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1); + Wait(0.200, Ignore Condition); + Set Gravity(Event Player, 20); + Disable Movement Collision With Environment(Event Player, True); + Teleport(Event Player, Global.zenSpawnPositions[Random Integer(Min(Global.timeMinutes, Count Of(Global.zenSpawnPositions) - 10), + Min(Global.spawnPositionMaxId, Count Of(Global.zenSpawnPositions) - 4))] + Vector(0, -1.500, 0)); + Wait(0.100, Ignore Condition); + Play Effect(All Players(Team 1), Sigma Accretion Impact Effect, Custom Color(220, 175, 100, 255), Eye Position(Event Player), 3); + Play Effect(All Players(Team 1), Sigma Accretion Impact Sound, Color(Gray), Eye Position(Event Player), 50); + Apply Impulse(Event Player, Up, 3.500, To World, Cancel Contrary Motion); + Wait(0.400, Ignore Condition); + Clear Status(Event Player, Knocked Down); + Set Gravity(Event Player, 100); + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("=== PLAYER MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("PLAYER: HEALTH REGEN") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + actions + { + Stop Heal Over Time(Event Player.healOverTimeId); + Event Player.eventHealth = Health(Event Player); + Wait(4, Ignore Condition); + "TOOK DAMAGE, RESET REGENERATION TIMER" + Loop If(Is Alive(Event Player) && Event Player.eventHealth > Health(Event Player)); + Start Heal Over Time(Event Player, Null, 3, Max Health(Event Player) / 3); + Event Player.healOverTimeId = Last Heal Over Time ID; + } +} + +disabled rule("=== ZENYATTA ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ZEN - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Zenyatta; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + } + + actions + { + Set Ammo(Event Player, 0, 0); + Communicate(Event Player, Hello); + Wait(1.500, Ignore Condition); + Abort If(Is Dead(Event Player) == True); + Kill(Event Player, Null); + } +} + +rule("BOT: ZEN - DEATH") +{ + event + { + Player Died; + Team 2; + Zenyatta; + } + + actions + { + "EFFECT" + Play Effect(All Players(Team 1), Junkrat Frag Launcher Explosion Effect, Color(Red), Eye Position(Event Player), 2.500); + Play Effect(All Players(Team 1), Ashe Dynamite Explosion Sound, Color(Red), Eye Position(Event Player), 70); + "DAMAGE AND APPLY IMPULSE TO PLAYERS" + Event Player.botPlayersInRadius = Players Within Radius(Position Of(Event Player), 2.500, All Teams, Surfaces And Enemy Barriers); + For Player Variable(Event Player, botLoopIterator1, 0, Count Of(Event Player.botPlayersInRadius), 1); + Apply Impulse(Event Player.botPlayersInRadius[Event Player.botLoopIterator1], Direction Towards(Position Of(Event Player), + Eye Position(Event Player.botPlayersInRadius[Event Player.botLoopIterator1])), 5, To World, Incorporate Contrary Motion); + If(Team Of(Event Player.botPlayersInRadius[Event Player.botLoopIterator1]) == Team 1); + Damage(Event Player.botPlayersInRadius[Event Player.botLoopIterator1], Event Player, 50); + End; + End; + "DAMAGE GATE" + If(Distance Between(Position Of(Event Player), Global.gatePosition) < 3 && Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss[0] == 1); + Global.gateHealth -= 125; + Else; + Global.gateHealth -= 25 + 5 * Global.time5Minutes; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Respawn(Event Player); + Abort; + End; + "KILLED BY PLAYER" + Teleport(Event Player, Vector(0, -999, 0)); + Wait(2, Ignore Condition); + Respawn(Event Player); + Wait(2, Ignore Condition); + } +} + +rule("SUBROUTINE: ZEN - RESPAWN") +{ + event + { + Subroutine; + BotZenyattaRespawn; + } + + actions + { + Call Subroutine(BotAppearFromUnderground); + Event Player.botTargetPosition = Global.gatePosition; + Event Player.botIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WRECKING BALL ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BALL - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Set Ammo(Event Player, 0, 0); + Wait(1, Ignore Condition); + Set Ultimate Charge(Event Player, 100); + Start Holding Button(Event Player, Button(Ultimate)); + Wait Until(Is Using Ultimate(Event Player), 0.600); + Abort If(Is Dead(Event Player)); + Kill(Event Player, Null); + Play Effect(All Players(Team 1), Junkrat RIP Tire Explosion Effect, Color(Orange), Eye Position(Event Player), 6); + Play Effect(All Players(Team 1), DVa Self Destruct Explosion Sound, Color(White), Eye Position(Event Player), 250); + If(Distance Between(Position Of(Event Player), Global.gatePosition) < 3.500 && Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss[0] == 1); + Global.gateHealth -= 300; + Else If(Event Player.isBoss[1] == 1); + Global.gateHealth -= 50; + Else; + Global.gateHealth -= 150 + 10 * Global.time5Minutes; + End; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Damage(Players Within Radius(Eye Position(Event Player), 5, Team 1, Surfaces And All Barriers), Event Player, 100); + } +} + +rule("BOT: BALL - ALTERNATIVE FORM") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is In Alternate Form(Event Player) == False; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is In Alternate Form(Event Player), 10); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: BALL - DEATH") +{ + event + { + Player Died; + Team 2; + Wrecking Ball; + } + + actions + { + Stop Holding Button(Event Player, Button(Ability 1)); + Stop Holding Button(Event Player, Button(Ultimate)); + } +} + +rule("SUBROUTINE: BALL - RESPAWN") +{ + event + { + Subroutine; + BotBallRespawn; + } + + actions + { + "RESPAWN IN AIR" + Teleport(Event Player, Random Value In Array(Global.ballSpawnPositions) + Vector(0, 20, 0)); + Stop Holding Button(Event Player, Button(Ultimate)); + Wait(0.250, Ignore Condition); + "LANDING" + Start Holding Button(Event Player, Button(Crouch)); + Wait Until(Is On Ground(Event Player), 9999); + Stop Holding Button(Event Player, Button(Crouch)); + "LANDING IMPACT EFFECT" + Play Effect(All Players(Team 1), Sigma Accretion Impact Sound, Color(White), Event Player, 150); + Play Effect(All Players(Team 1), Doomfist Meteor Strike Impact Effect, Color(Gray), Position Of(Event Player), 10); + Create Effect(All Players(Team 1), Bad Aura, Color(Orange), Eye Position(Event Player), 1.500, Visible To Position and Radius); + Event Player.botEffects[0] = Last Created Entity; + "PATH FINDING TO GATE" + Event Player.botTargetPosition = Global.gatePosition; + Event Player.botIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +disabled rule("=== ECHO ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ECHO - FLY ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Is Using Ability 1(Event Player) == False; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), 0); + Press Button(Event Player, Button(Ability 1)); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - BEAM ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Is Using Ability 1(Event Player) == False; + Event Player.botDoesUniqueBehaviour == True; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - BAD STATUS - RESET BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.hasBadStatus == True; + } + + actions + { + If(Event Player.botDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + Wait Until(Event Player.hasBadStatus, 7); + } +} + +rule("BOT: ECHO - CAN'T SEE PORTAL - APPLY IMPULSE") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == True; + Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Wait(0.300, Abort When False); + Apply Impulse(Event Player, Vector(Random Integer(-1, 1), 1, Random Integer(-1, 1)), 20, To World, Incorporate Contrary Motion); + Wait(1, Ignore Condition); + If(!Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS)); + Event Player.botTargetPosition = Global.botEchoRespawnPosition; + Start Rule(BotStartPathFinding, Restart Rule); + Else; + Call Subroutine(BotResetPathFinding); + End; + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + } + + actions + { + If(Event Player.botDoesUniqueBehaviour == False); + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Current Array Element.isInMenu[0] == False && (Hero Of(Current Array Element) == Hero(Sombra) && Is Using Ability 1( + Current Array Element)) == False && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), + Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + End; + "TELEPORT PLAYER SO FAR" + If(Event Player.botDoesUniqueBehaviour && Distance Between(Position Of(Event Player.botEchoCapturedPlayer), + Global.botEchoRespawnPosition) < 4); + Play Effect(All Players(Team 1), Bad Pickup Effect, Color(White), Global.botEchoRespawnPosition, 1); + Teleport(Event Player.botEchoCapturedPlayer, Random Value In Array(Global.botEchoTeleportPositions)); + Set Status(Event Player.botEchoCapturedPlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + End; + "BEGIN TO FLY TO THE PORTAL WITH A PLAYER" + If(Event Player.botDoesUniqueBehaviour); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.botIsPathFinding); + Event Player.botTargetPlayer = Event Player.botEchoCapturedPlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - DEFEND PORTAL") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer == Null; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer), Barriers Do Not Block LOS) == True; + Event Player.botSeePlayer.isInMenu[0] == False; + } + + actions + { + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPlayer); + } +} + +rule("BOT: ECHO - PATH FINDING TO PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Event Player.botDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer), Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.botTargetPlayer = Event Player.botSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Call Subroutine(BotStartPathFinding); + } +} + +rule("BOT: ECHO - ATTACH PLAYER BY BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.hasBadStatus == False; + Event Player.botSeePlayer != Null; + Event Player.isRespawning == False; + Event Player.botEchoCapturedPlayer == Null; + Event Player.botDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer), Barriers Do Not Block LOS) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) < 3; + } + + actions + { + Event Player.botDoesUniqueBehaviour = True; + Event Player.botEchoCapturedPlayer = Event Player.botSeePlayer; + Set Status(Event Player.botEchoCapturedPlayer, Event Player, Stunned, 0.700); + Set Status(Event Player.botEchoCapturedPlayer, Event Player, Hacked, 10); + Attach Players(Event Player.botEchoCapturedPlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - PLAYER DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Is Dead(Event Player.botEchoCapturedPlayer) != Null; + } + + actions + { + If(Event Player.botDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - DEATH") +{ + event + { + Player Died; + Team 2; + Echo; + } + + actions + { + Call Subroutine(BotEchoDetachPlayer); + Stop Holding Button(Event Player, Button(Jump)); + Wait(5, Ignore Condition); + Teleport(Event Player, Vector(0, 999, 0)); + Start Forcing Player To Be Hero(Event Player, Hero(Orisa)); + } +} + +rule("SUBROUTINE: ECHO - RESPAWN") +{ + event + { + Subroutine; + BotEchoRespawn; + } + + actions + { + Event Player.botCounter = 0; + Event Player.botEffects = Empty Array; + Create Effect(All Players(Team 1), Good Aura, Color(Sky Blue), Global.botEchoRespawnPosition, Event Player.botCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, botEffects, Append To Array, Last Created Entity); + Create Effect(All Players(Team 1), Bad Aura, Color(Sky Blue), Global.botEchoRespawnPosition, Event Player.botCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, botEffects, Append To Array, Last Created Entity); + Create Effect(All Players(Team 1), Energy Sound, Color(White), Global.botEchoRespawnPosition, 200, Visible To); + Modify Player Variable(Event Player, botEffects, Append To Array, Last Created Entity); + Chase Player Variable Over Time(Event Player, botCounter, 3, 0.800, Destination and Duration); + Play Effect(All Players(Team 1), Junkrat RIP Tire Explosion Effect, Color(Sky Blue), Global.botEchoRespawnPosition, 12); + Play Effect(All Players(Team 1), Sombra EMP Explosion Sound, Null, Global.botEchoRespawnPosition, 100); + Wait(3, Ignore Condition); + Teleport(Event Player, Global.botEchoRespawnPosition); + Play Effect(All Players(Team 1), Good Explosion, Color(White), Global.botEchoRespawnPosition, 2.500); + Play Effect(All Players(Team 1), Debuff Impact Sound, Null, Global.botEchoRespawnPosition, 100); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PLAYER") +{ + event + { + Subroutine; + BotEchoFlyToPlayer; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Stop Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PORTAL") +{ + event + { + Subroutine; + BotEchoFlyToPortal; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - DETACH PLAYER") +{ + event + { + Subroutine; + BotEchoDetachPlayer; + } + + actions + { + Detach Players(Event Player.botEchoCapturedPlayer); + Clear Status(Event Player.botEchoCapturedPlayer, Hacked); + "IF PLAYER INSIDE THE WALL" + If(Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botEchoCapturedPlayer), Barriers Do Not Block LOS)); + Teleport(Event Player.botEchoCapturedPlayer, Position Of(Event Player)); + End; + Event Player.botDoesUniqueBehaviour = False; + Event Player.botEchoCapturedPlayer = Null; + } +} + +disabled rule("=== REINHARDT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: REIN - SET PLAYER AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + && Current Array Element.isInMenu[0] == False && (Hero Of(Current Array Element) == Hero(Sombra) && Is Using Ability 1( + Current Array Element)) == False), Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), + Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET CLOSEST PLAYER TO BOT AS TARGET AND FOLLOW HIM" + Event Player.botTargetPlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Current Array Element.isInMenu[0] == False && (Hero Of(Current Array Element) == Hero(Sombra) && Is Using Ability 1( + Current Array Element)) == False && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), + Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Position Of(Event Player.botTargetPlayer)), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - SET GATE AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + "BOT DOESN'T FOLLOW PLAYER" + Event Player.botTargetPlayer == -1; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET GATE AS TARGET" + Event Player.botTargetPosition = Global.gatePosition; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - TARGET DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botTargetPlayer != -1; + (Is Dead(Event Player.botTargetPlayer) || Event Player.botTargetPlayer.isInMenu[0] || (Hero Of(Event Player.botTargetPlayer) + == Hero(Sombra) && Is Using Ability 1(Event Player.botTargetPlayer))) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + } +} + +rule("BOT: REIN - ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) + : Global.gatePosition) < 4; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + "TARGET IS PLAYER" + Abort If(Event Player.botTargetPlayer != -1); + If(Event Player.isBoss[0] == 1); + "TARGET IS GATE" + Global.gateHealth -= 25 + 10 * Global.time10Minutes; + Else If(Event Player.isBoss[1] == 1); + Global.gateHealth -= 5; + Else; + Global.gateHealth -= 5 + 5 * Global.time5Minutes; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: REIN - STOP ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) + : Global.gatePosition) > 4; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + } +} + +rule("BOT: REIN - USE SHIELD") +{ + event + { + Player Took Damage; + Team 2; + Reinhardt; + } + + conditions + { + Event Player.isBoss[1] == False; + Distance Between(Position Of(Event Player), Position Of(Event Player.botTargetPlayer)) > 3; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Attacker)), 200, To World, + Direction and Turn Rate); + Start Holding Button(Event Player, Button(Secondary Fire)); + Wait Until(Distance Between(Position Of(Event Player), Position Of(Event Player.botTargetPlayer)) < 3, 3); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("BOT: REIN - CHARGE IN GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botTargetPlayer == -1; + Is Using Ability 1(Event Player) == False; + Is In Line of Sight(Eye Position(Event Player), Global.gatePosition, Barriers Do Not Block LOS) == True; + Is In View Angle(Event Player, Global.gatePosition, 7.500) == True; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is Using Ability 1(Event Player), 1); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: REIN - DEATH") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("SUBROUTINE: REIN - RESPAWN") +{ + event + { + Subroutine; + BotReinRespawn; + } + + actions + { + Call Subroutine(BotAppearFromUnderground); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WIDOW ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: WIDOW - SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.botSeePlayer == Null; + Event Player.hasBadStatus == False; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + && Current Array Element.isInMenu[0] == False && (Hero Of(Current Array Element) == Hero(Sombra) && Is Using Ability 1( + Current Array Element)) == False), Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), + Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Current Array Element.isInMenu[0] == False && (Hero Of(Current Array Element) == Hero(Sombra) && Is Using Ability 1( + Current Array Element)) == False && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), + Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Event Player.botWidowShotTime = Total Time Elapsed + (Global.timeMinutes >= 9 ? Random Real(2, 5) : Random Real(5, 10)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), 9999, To World, + Direction and Turn Rate); + } +} + +rule("BOT: WIDOW - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.botSeePlayer != Null; + Event Player.hasBadStatus == False; + Total Time Elapsed >= Event Player.botWidowShotTime; + } + + actions + { + Press Button(Event Player, Button(Primary Fire)); + Stop Facing(Event Player); + Event Player.botSeePlayer = Null; + } +} + +rule("BOT: WIDOW - Aim Sound") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Alive(Event Player) == True; + Is In Line of Sight(Eye Position(Players On Hero(Hero(Widowmaker), Team 2)), Eye Position(Event Player), Barriers Do Not Block LOS) + == True; + Is Alive(Players On Hero(Hero(Widowmaker), Team 2)) == True; + Players On Hero(Hero(Widowmaker), Team 2).botSeePlayer == True; + } + + actions + { + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 100); + Wait(1, Abort When False); + Loop If Condition Is True; + } +} + +rule("BOT: WIDOW - TELEPORT TO NEW POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.hasBadStatus == False; + Total Time Elapsed >= Event Player.botWidowTeleportTime; + } + + actions + { + Event Player.botWidowTeleportTime = Total Time Elapsed + 28; + Event Player.botWidowShotTime = Total Time Elapsed + (Global.timeMinutes >= 9 ? Random Real(1, 3) : Random Real(3, 6)); + Play Effect(All Players(Team 1), Bad Pickup Effect, Color(White), Event Player, 1); + Wait(0.100, Ignore Condition); + Teleport(Event Player, Filtered Array(Global.sniperPositions, Distance Between(Event Player.botEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.sniperPositions) - 2)]); + Wait(0.100, Ignore Condition); + Event Player.botEventPosition = Position Of(Event Player); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(Team 1), Debuff Impact Sound, Color(White), Event Player, 100); + } +} + +rule("BOT: WIDOW - DEATH") +{ + event + { + Player Died; + Team 2; + Widowmaker; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + Wait(0.250, Ignore Condition); + Destroy Effect(Event Player.botEffects[0]); + } +} + +rule("SUBROUTINE: WIDOW - RESPAWN") +{ + event + { + Subroutine; + BotWidowRespawn; + } + + actions + { + "RESPAWN ON RANDOM SNIPER POSITION" + Teleport(Event Player, Filtered Array(Global.sniperPositions, Distance Between(Event Player.botEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.sniperPositions) - 2)]); + Wait(0.100, Ignore Condition); + Event Player.botEventPosition = Position Of(Event Player); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(Team 1), Debuff Impact Sound, Color(White), Event Player, 100); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Wait(0.700, Ignore Condition); + Start Holding Button(Event Player, Button(Secondary Fire)); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.botEffects[0] = Last Created Entity; + Wait Until(Is Dead(Event Player), 99999); + Destroy Effect(Event Player.botEffects[0]); + } +} + +rule("SUBROUTINE: WIDOW - BAD STATUS") +{ + event + { + Subroutine; + BotWidowBadStatus; + } + + actions + { + Stop Facing(Event Player); + Destroy Effect(Event Player.botEffects[0]); + Wait Until(!Event Player.hasBadStatus, 15); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.botEffects[0] = Last Created Entity; + } +} + +disabled rule("=== BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BASTION - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Current Array Element.isInMenu[0] == False && (Hero Of(Current Array Element) == Hero(Sombra) && Is Using Ability 1( + Current Array Element)) == False && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), + Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + "SEE THE PLAYER" + If(Event Player.botSeePlayer != Null); + Stop Holding Button(Event Player, Button(Secondary Fire)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer) - Vector(0, 0.500, + 0)), 100, To World, Direction and Turn Rate); + "SELF REPAIRING" + Else If(!Is Firing Secondary(Event Player) && Health(Event Player) < Max Health(Event Player)); + Start Holding Button(Event Player, Button(Secondary Fire)); + End; + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - ARTILLERY") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.botDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.botSeePlayer), 30) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) > 18; + Distance Between(Eye Position(Event Player), Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Up * 99, Null, Event Player, False)) >= 35; + } + + actions + { + "TRYING TO CAPTURE TARGET" + Wait(0.800, Abort When False); + "CAPTURE TARGET" + Event Player.botDoesUniqueBehaviour = True; + Stop Throttle In Direction(Event Player); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Update Every Frame(Eye Position(Event Player)), + Update Every Frame(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 1000, All Living Players(Team 1), Event Player, True)), Color(Sky Blue), Visible To Position and Radius); + Event Player.botEffects[1] = Last Created Entity; + Wait(1.400, Ignore Condition); + Destroy Effect(Event Player.botEffects[1]); + Abort If(Is Dead(Event Player)); + Event Player.botEventPosition = Position Of(Event Player.botSeePlayer); + "SHOOT FROM ARTILLERY" + Event Player.botBastionArtilleryDidShotsCount = 0; + For Player Variable(Event Player, botLoopIterator1, 0, 4, 1); + Event Player.botBastionArtilleryDidShotsCount += 1; + Play Effect(All Players(Team 1), Wrecking Ball Minefield Explosion Sound, Color(White), Eye Position(Event Player), 250); + Play Effect(All Players(Team 1), Pharah Barrage Explosion Effect, Color(Orange), Eye Position(Event Player) + World Vector Of( + Vector(0, 1.400, -0.700), Event Player, Rotation), 2); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) + World Vector Of(Vector(0, 1.400, + -0.700), Event Player, Rotation), Eye Position(Event Player) + World Vector Of(Vector(Random Real(-1, 1), Random Integer(40, + 80), Random Real(0.500, 1.500)), Event Player, Rotation), Color(Orange), Visible To); + Event Player.botEffects[2] = Last Created Entity; + Wait(0.100, Ignore Condition); + Destroy Effect(Event Player.botEffects[2]); + Wait(0.400, Ignore Condition); + If(Is Dead(Event Player)); + Break; + End; + End; + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Wait(1.500, Ignore Condition); + Start Rule(BotBastionArtilleryDamage, Do Nothing); + Wait(4, Ignore Condition); + } +} + +rule("BOT: BASTION - PRIMARY FIRE") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Event Player.botDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.botSeePlayer), 40) == True; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Stop Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Bastion; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + For Player Variable(Event Player, botLoopIterator1, 0, 3, 1); + Play Effect(All Players(Team 1), Bastion Tank Cannon Explosion Effect, Color(White), Event Player, 1); + Play Effect(All Players(Team 1), Bastion Tank Cannon Explosion Sound, Color(White), Event Player, 100); + Wait(0.250, Ignore Condition); + End; + } +} + +rule("SUBROUTINE: BASTION - RESPAWN") +{ + event + { + Subroutine; + BotBastionRespawn; + } + + actions + { + Abort If(Event Player.botIsOrisaChild == True); + Call Subroutine(BotLandingFromSky); + Set Ammo(Event Player, 0, 0); + Wait Until(!Is Reloading(Event Player), 99999); + Event Player.botTargetPosition = Objective Position(2); + } +} + +rule("SUBROUTINE: BASTION - ARTILLERY DAMAGE") +{ + event + { + Subroutine; + BotBastionArtilleryDamage; + } + + actions + { + Event Player.botDoesUniqueBehaviour = False; + "EXPLOSIONS OF ARTILLERY" + For Player Variable(Event Player, botLoopIterator2, 0, Event Player.botBastionArtilleryDidShotsCount, 1); + Event Player.botEventPosition = Ray Cast Hit Position(Event Player.botEventPosition + Vector(0, 50, 0), + Event Player.botEventPosition + Vector(Random Integer(-4, 4), -15, Random Integer(-4, 4)), Null, Event Player, True); + Damage(Players Within Radius(Event Player.botEventPosition, 8, Team 1, Surfaces And Enemy Barriers), Event Player, 50); + Play Effect(All Players(Team 1), Bastion Tank Cannon Explosion Sound, Color(White), Event Player.botEventPosition, 150); + Play Effect(All Players(Team 1), Pharah Rocket Launcher Explosion Effect, Color(Orange), Event Player.botEventPosition, 5); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Event Player.botEventPosition, + Event Player.botEventPosition + Vector(0, 60, 0), Color(Orange), Visible To); + Event Player.botEffects[1] = Last Created Entity; + Wait(0.100, Ignore Condition); + Destroy Effect(Event Player.botEffects[1]); + Wait(0.400, Ignore Condition); + End; + } +} + +disabled rule("=== ORISA + BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ORISA-BASTION - REACHED TARGET POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botIsPathFinding == True; + Distance Between(Position Of(Event Player), Global.botOrisaTargetPosition) < 1.500; + } + + actions + { + Call Subroutine(BotResetPathFinding); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Vector(X Component Of(Global.gatePosition), -999, + Z Component Of(Global.gatePosition))), 80, To World, Direction and Turn Rate); + Start Facing(Global.botOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Barriers Do Not Block LOS) ? Global.gatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + Press Button(Event Player, Button(Ability 1)); + Wait Until(Y Component Of(Facing Direction Of(Event Player)) < -0.300, 99999); + Press Button(Event Player, Button(Ability 2)); + Wait(0.800, Ignore Condition); + Global.botOrisaChild.botDoesUniqueBehaviour = False; + Disallow Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ORISA-BASTION - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Event Player.botDoesUniqueBehaviour = True; + While(Is Alive(Event Player)); + Create Effect(All Players(Team 1), Bad Aura, Color(Purple), Eye Position(Event Player) - Vector(0, 0.700, 0) + Facing Direction Of( + Event Player) * 3.200, 1, Visible To Position and Radius); + Event Player.botEffects[3] = Last Created Entity; + Wait(1.500, Ignore Condition); + Destroy Effect(Event Player.botEffects[3]); + Abort If(Is Dead(Event Player)); + Press Button(Event Player, Button(Primary Fire)); + Press Button(Event Player, Button(Reload)); + Event Player.botRayCastHitPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Facing Direction Of(Event Player) * 999, All Players(Team 1), All Players(Team 2), True); + "ANTI-SHIELD BUG" + Event Player.botRayCastHitPosition = Event Player.botRayCastHitPosition + Direction Towards(Event Player.botRayCastHitPosition, + Eye Position(Event Player)) * 0.200; + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3, Event Player.botRayCastHitPosition, Color(Purple), Visible To Position and Radius); + Event Player.botEffects[4] = Last Created Entity; + Damage(Players Within Radius(Event Player.botRayCastHitPosition, 4, Team 1, Surfaces And All Barriers), Event Player, 0.040); + Play Effect(All Players(Team 1), Pharah Concussive Blast Effect, Color(Purple), Event Player.botRayCastHitPosition, 4); + Play Effect(All Players(Team 1), Pharah Concussive Blast Sound, Color(Purple), Event Player.botRayCastHitPosition, 250); + Play Effect(All Players(Team 1), Bad Explosion, Color(Purple), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 3.300, 2); + Play Effect(All Players(Team 1), Sombra EMP Explosion Sound, Color(Purple), Eye Position(Event Player), 170); + If(Distance Between(Event Player.botRayCastHitPosition, Global.gatePosition) < 4 && Is In Line of Sight( + Event Player.botRayCastHitPosition, Global.gatePosition, Enemy Barriers Block LOS)); + Global.gateHealth -= 80 + 10 * Global.time5Minutes; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Wait(0.150, Ignore Condition); + Destroy Effect(Event Player.botEffects[4]); + Wait(0.100, Ignore Condition); + Wait Until(!Is Reloading(Event Player), 2.500); + End; + } +} + +rule("BOT: ORISA-BASTION - CAN'T SEE THE TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Is In Line of Sight(Eye Position(Event Player), Global.gatePosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.botTargetPosition = Global.botOrisaTargetPosition; + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: ORISA-BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Orisa; + } + + actions + { + Allow Button(Event Player, Button(Ability 2)); + Kill(Global.botOrisaChild, Null); + Detach Players(Global.botOrisaChild); + Clear Status(Global.botOrisaChild, Phased Out); + Set Damage Dealt(Global.botOrisaChild, 100); + Global.botOrisaChild.botIsOrisaChild = False; + Global.botOrisaChild = Null; + Global.botOrisaParent = Null; + Start Forcing Player To Be Hero(Event Player, Hero(Widowmaker)); + } +} + +rule("SUBROUTINE: ORISA - RESPAWN") +{ + event + { + Subroutine; + BotOrisaRespawn; + } + + actions + { + Global.botOrisaParent = Event Player; + "WAITING FOR ANY BASTION TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero(Bastion) && Current Array Element.isBoss[0] == False && Current Array Element.isBoss[1] == False), + 99999); + "SETUP BASTION AS CHILD" + Global.botOrisaChild = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Bastion) && Current Array Element.isBoss[0] == False && Current Array Element.isBoss[1] == False)[0]; + Global.botOrisaChild.botIsOrisaChild = True; + Global.botOrisaChild.botDoesUniqueBehaviour = True; + Wait(2, Ignore Condition); + Respawn(Global.botOrisaChild); + Start Scaling Player(Global.botOrisaChild, 1.800, False); + Set Damage Dealt(Global.botOrisaChild, 2000); + Set Status(Global.botOrisaChild, Null, Phased Out, 9999); + Disable Nameplates(Global.botOrisaChild, All Players(All Teams)); + Set Facing(Global.botOrisaChild, Vector(X Component Of(Facing Direction Of(Event Player)), 9999, Z Component Of( + Facing Direction Of(Event Player))), To World); + Start Holding Button(Global.botOrisaChild, Button(Ability 1)); + Wait Until(Is In Alternate Form(Global.botOrisaChild), 5); + Stop Holding Button(Global.botOrisaChild, Button(Ability 1)); + Teleport(Global.botOrisaChild, Position Of(Event Player)); + Attach Players(Global.botOrisaChild, Global.botOrisaParent, Vector(0, 1.800, 0.230)); + Call Subroutine(BotLandingFromSky); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + Event Player.botTargetPosition = Global.botOrisaTargetPosition; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 0 - ZENS, REINS, BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 0; + } + + actions + { + "CREATE BOTS - ZEN" + While(Count Of(All Players(Team 2)) < 13); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "BALL" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "REPLACE DEAD ZEN TO REIN" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) != 3); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 1 - WIDOW") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 1; + } + + actions + { + Global.isNewWaveGameLogicProcessing = True; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Global.isNewWaveGameLogicProcessing = False; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 3 - BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 3; + } + + actions + { + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 6 - BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 6; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Zenyatta))) > 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(1, Ignore Condition); + If(Count Of(All Players(Team 2)) < 11); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Last Created Entity.isBoss[1] = True; + End; + End; + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 9 - ECHO, +1 BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 9; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) > 0); + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Widowmaker)), 99999); + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Widowmaker))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Echo))) == 0); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + Wait Until(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Zenyatta))) == 0, 99999); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + } +} + +rule("Ana Nano Variable") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + } + + actions + { + Player Closest To Reticle(Event Player, Team 1).isNanoed = 1; + } +} + +rule("isNanoed") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isNanoed == True; + } + + actions + { + If(Is Dead(Event Player)); + Event Player.isNanoed = 0; + End; + Wait(8, Ignore Condition); + Event Player.isNanoed = 0; + } +} + +rule("money on kill") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + actions + { + If(Global.upgradeMaxAmmoValue < Global.upgradeMaxAmmoMaxValue[2]); + Global.upgradeMaxAmmoValue += Victim.isBoss[0] == 1 ? 10 : 1; + End; + If(Hero Of(Victim) == Hero(Zenyatta)); + All Players(Team 1).money[0] += 10 * (Victim.isBoss[0] ? 3 : 1) * Global.moneyMultiplier[0]; + Global.startMoney += 10 * (Victim.isBoss[0] ? 3 : 1) * Global.moneyMultiplier[0]; + Else If(Hero Of(Victim) == Hero(Reinhardt)); + All Players(Team 1).money[0] += 20 * (Victim.isBoss[0] ? 3 : 1) * Global.moneyMultiplier[0]; + Global.startMoney += 20 * (Victim.isBoss[0] ? 3 : 1) * Global.moneyMultiplier[0]; + Else If(Hero Of(Victim) == Hero(Wrecking Ball)); + All Players(Team 1).money[0] += 30 * (Victim.isBoss[0] ? 3 : 1) * Global.moneyMultiplier[0]; + Global.startMoney += 30 * (Victim.isBoss[0] ? 3 : 1) * Global.moneyMultiplier[0]; + Else If(Hero Of(Victim) == Hero(Widowmaker)); + All Players(Team 1).money[0] += 50 * (Victim.isBoss[0] ? 3 : 1) * Global.moneyMultiplier[0]; + Global.startMoney += 50 * (Victim.isBoss[0] ? 3 : 1) * Global.moneyMultiplier[0]; + Else If(Hero Of(Victim) == Hero(Bastion)); + All Players(Team 1).money[0] += 70 * (Victim.isBoss[0] ? 3 : 1) * Global.moneyMultiplier[0]; + Global.startMoney += 70 * (Victim.isBoss[0] ? 3 : 1) * Global.moneyMultiplier[0]; + Else If(Hero Of(Victim) == Hero(Echo)); + All Players(Team 1).money[0] += 90 * (Victim.isBoss[0] ? 3 : 1) * Global.moneyMultiplier[0]; + Global.startMoney += 90 * (Victim.isBoss[0] ? 3 : 1) * Global.moneyMultiplier[0]; + Else If(Hero Of(Victim) == Hero(Orisa)); + All Players(Team 1).money[0] += 120 * (Victim.isBoss[0] ? 3 : 1) * Global.moneyMultiplier[0]; + Global.startMoney += 120 * (Victim.isBoss[0] ? 3 : 1) * Global.moneyMultiplier[0]; + } +} + +rule("Abilities and Hero Talents by Shingen and LemonAid") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.baseStats[0] = 100; + Event Player.baseStats[1] = 100; + Event Player.baseStats[2] = 100; + Event Player.baseStats[3] = 100; + Event Player.damageBoost[0] = 0; + Event Player.damageBoost[1] = 0; + Event Player.playerHealth = 0; + Event Player.healBoost = 0; + Event Player.speedBoost = 0; + Event Player.money[0] = 2400 + Global.startMoney; + If(Custom String("{0}", Event Player) == Custom String("ShuriZma")); + Create HUD Text(Event Player, Null, Custom String("Serverload: {0}, AVG {1}, Peak {2}", Server Load, Server Load Average, + Server Load Peak), Null, Right, -10000, Color(White), Color(Red), Color(White), Visible To and String, + Default Visibility); + Create HUD Text(Event Player, Null, Custom String("{0}{1}{2}", Custom String("damage: {0}\nhealth: {1}\nhealing: {2}\n", + Event Player.baseStats[0], Event Player.baseStats[1], Event Player.baseStats[2]), Custom String( + "speed: {0}\ndamageBoost[0]: {1}\ndamageBoost[1]: {2}\n", Event Player.baseStats[3], Event Player.damageBoost[0], + Event Player.damageBoost[1]), Custom String("playerHealth: {0}\nhealBoost: {1}\n{2}", Event Player.playerHealth, + Event Player.healBoost, Custom String("speedBoost: {0}\nkills: {1}", Event Player.speedBoost, Event Player.baseStats[4]))), + Null, Right, -10000, Color(White), Color(Red), Color(White), Visible To and String, Default Visibility); + End; + } +} + +rule("Team 1 (Ability): Quick Fix") +{ + event + { + Player Earned Elimination; + Team 1; + All; + } + + conditions + { + Event Player.abilities[3] == True; + } + + actions + { + If(Event Player.baseStats[5] != Event Player.abilities[3] * 20 && Event Player.baseStats[4] == True); + Event Player.speedBoost -= Event Player.baseStats[5]; + End; + + Heal(Event Player, Null, Event Player.abilities[3] * 50); + If(Event Player.baseStats[4] != True || Event Player.baseStats[5] != Event Player.abilities[3] * 20); + Event Player.baseStats[5] = Event Player.abilities[3] * 20; + Event Player.baseStats[4] = True; + Event Player.speedBoost += Event Player.baseStats[5]; + Call Subroutine(UpdatePlayerStats); + End; + Wait(5, Restart When True); + Event Player.speedBoost -= Event Player.baseStats[5]; + Event Player.baseStats[4] = False; + Call Subroutine(UpdatePlayerStats); + } +} + +rule("Team 1 (Ability): Heavyweight") +{ + event + { + Player Dealt Knockback; + Team 1; + All; + } + + conditions + { + Event Player.abilities[4] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage / (100 / (Event Player.abilities[4] * 25))); + } +} + +rule("Team 1 (Ability): Charged") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[5] == True; + Ultimate Charge Percent(Event Player) < Event Player.abilities[5] * 20; + } + + actions + { + Set Ultimate Charge(Event Player, Event Player.abilities[5] * 20); + If(Is Duplicating(Event Player)); + Wait(0.100, Ignore Condition); + Set Ultimate Charge(Event Player, Event Player.abilities[5] * 20); + End; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Team 1 (Ability): Haste Primary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Primary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Primary Fire), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Primary Fire))); + } +} + +rule("Team 1 (Ability): Haste Secondary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Secondary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Secondary Fire), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Secondary Fire))); + } +} + +rule("Team 1 (Ability): Haste Ability 1") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 1)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 1))); + } +} + +rule("Team 1 (Ability): Haste Ability 2") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 2)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 2))); + } +} + +rule("Team 1 (Ability): Haste Jump") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Jump)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Jump), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, Button( + Jump))); + } +} + +rule("Team 1 (Ability): Haste Crouch") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Crouch)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Crouch), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, Button( + Crouch))); + } +} + +rule("Team 1 (Ability): Heavy Impact") +{ + event + { + Player Took Damage; + Team 2; + All; + } + + conditions + { + Attacker.abilities[7] == True; + } + + actions + { + Abort If(Random Real(-0.020, 1) > Event Damage / Max Health(Event Player)); + Set Status(Event Player, Attacker, Stunned, 1 * Attacker.abilities[7]); + Wait(5, Ignore Condition); + } +} + +rule("Team 1 (Ability): Resilience") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[11] == True; + Normalized Health(Event Player) < Event Player.abilities[11] * 0.300; + } + + actions + { + Set Damage Received(Event Player, 70); + Wait Until(!(Event Player.abilities[11] && Normalized Health(Event Player) < Event Player.abilities[11] * 0.300), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Auto Repair") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.automaticRepair == True; + Global.gateHealth < Global.gateMaxHealth[0]; + } + + actions + { + If(Global.gateMaxHealth[0] - Global.gateHealth > 5 * Global.automaticRepair * ( + Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 2 : 1)); + Global.gateHealth += 5 * Global.automaticRepair * ( + Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 2 : 1); + Global.upgradeGateMaxHealthValue += 5 * Global.automaticRepair; + Else; + Global.gateHealth += Global.gateMaxHealth[0] - Global.gateHealth; + Global.upgradeGateMaxHealthValue += Global.gateMaxHealth[0] - Global.gateHealth; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(5, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + } + + actions + { + If(Hero Of(Event Player) == Hero(Ana)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Ana), Button(Ability 1)), Custom String( + "Sleep Paralysis: Slept enemies will take a lot of damage when they wake up")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Ana), Button(Ability 2)), Custom String( + "Multinade: Ana throws multiple Biotic Grenades")); + Else If(Hero Of(Event Player) == Hero(Ashe)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Ashe), Button(Ability 2)), Custom String( + "Black Gunpowder: Coach gun stuns and sets enemies on fire")); + Event Player.heroTalentText[2] = Array(Icon String(Fire), Custom String( + "Dancing Flames: Eliminated enemies exlpode and burn others nearby")); + Else If(Hero Of(Event Player) == Hero(Baptiste)); + Event Player.heroTalentText[1] = Array(Icon String(Poison), Custom String( + "Corrode: Regenerative Burst will damage and poison enemies")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Aerial Ace: Exo-boots allow for gliding and deal bonus damage while gliding")); + Else If(Hero Of(Event Player) == Hero(Bastion)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Fusillade: Automatically fire a tactical grenade every so often in sentry form")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ability 1)), Custom String( + "Trickshot: Landing tactical grenade on an enemy deals more damage and heals")); + Else If(Hero Of(Event Player) == Hero(Brigitte)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Brigitte), Button(Ability 1)), Custom String( + "Endeavor: Gain a boost in damage, armour and speed when your barrier breaks")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Brigitte), Button(Ultimate)), Custom String( + "Whiplash: Endpoint of whip shot generates a stunning shockwave")); + Else If(Hero Of(Event Player) == Hero(Cassidy)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Cassidy), Button(Ability 2)), Custom String( + "Standoff: Enemies cannot move once their skull is locked during deadeye")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Cassidy), Button(Ultimate)), Custom String( + "Flashpoint: Magnetic Grenade will heavily stun enemies if it sticks")); + Else If(Hero Of(Event Player) == Hero(D.Va)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(D.Va), Button(Secondary Fire)), Custom String( + "Voltage Grid: Defense matrix damages and roots enemies")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(D.Va), Button(Ability 1)), Custom String( + "Shooting Star: Boosters set enemies on fire")); + Else If(Hero Of(Event Player) == Hero(Doomfist)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Jump)), Custom String( + "Punch Card: Rocket Punch deals triple damage at full charge")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Doomfist), Button(Ultimate)), Custom String( + "Fissure: Seismic Slam leaves a large fire pool behind")); + Else If(Hero Of(Event Player) == Hero(Echo)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Glass Bombs: Sticky Bombs deal double damage to enemies under half health")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Focusing Optics: Focusing Beam boost starts at 90% hp instead of 50%")); + Else If(Hero Of(Event Player) == Hero(Genji)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Genji), Button(Ability 1)), Custom String( + "Venomous Strike: Swift Strike deals bleed damage; heal for bleed damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Genji), Button(Ultimate)), Custom String( + "Dragon's Breath: Dragonblade fires explosive spirit charges with every swing")); + Else If(Hero Of(Event Player) == Hero(Hanzo)); + Event Player.heroTalentText[1] = Array(Icon String(Bolt), Custom String( + "Firebolt: Charging an arrow for more than 2s turns it into an explosive bolt")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Hanzo), Button(Ability 2)), Custom String( + "Stormbreak: Storm arrows have no cooldown for a short duration when earning a kill")); + Else If(Hero Of(Event Player) == Hero(Junkrat)); + Event Player.heroTalentText[1] = Array(Icon String(Fire), Custom String("Pyromania: All explosive attacks deal fire damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Junkrat), Button(Ability 2)), Custom String( + "Trigger Happy: Gain +1 Concussion Mine every 4s, up to 5 max")); + Else If(Hero Of(Event Player) == Hero(Junker Queen)); + Event Player.heroTalentText[1] = Array(Icon String(Fire), Custom String( + "Shout Louder: Commanding Shout wounds enemies in the area")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Junkrat), Button(Ability 2)), Custom String( + "Grace Period: Gracie deals extra damage upon pulling an enemy back")); + Else If(Hero Of(Event Player) == Hero(Kiriko)); + Event Player.heroTalentText[1] = Array(Icon String(Fire), Custom String( + "Shinobi Tactics: Healing with abilities creates energy explosions around the target")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Junkrat), Button(Ability 2)), Custom String( + "Recession: Protection Suzu damages for 20% of health and freezes enemies")); + Else If(Hero Of(Event Player) == Hero(Lúcio)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Lúcio), Button(Secondary Fire)), Custom String( + "Power Skating: Soundwave deals more damage and knockback based on movement speed")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Lúcio), Button(Ability 1)), Custom String( + "Reverse Amp: Amp It Up inflicts the opposite song effect to enemies")); + Else If(Hero Of(Event Player) == Hero(Mei)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Mei), Button(Ultimate)), Custom String( + "Cold Snap: Instantly freeze nearby enemies once Cryo-Freeze breaks")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Mei), Button(Ability 2)), Custom String( + "Polar Vortex: Mei throws 3 blizzard drones instead of 1 at increased damage")); + Else If(Hero Of(Event Player) == Hero(Mercy)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Mercy), Button(Ability 2)), Custom String( + "Wings of Grand: Guardian Angel damages and knocks enemies down in its path")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Mercy), Button(Ultimate)), Custom String( + "Holy light missiles: Unleash blasts of holy light missiles during valkyrie")); + Else If(Hero Of(Event Player) == Hero(Moira)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Moira), Button(Secondary Fire)), Custom String( + "Flourish: Fading through allies heals and through enemies damages them")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Moira), Button(Ability 2)), Custom String( + "Catalyst: Holding primary during coalescence costs energy and speed, but boosts effectiveness")); + Else If(Hero Of(Event Player) == Hero(Orisa)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Orisa), Button(Ability 1)), Custom String( + "Steel Pinwheel: Javelin spin deals a large sweep attack when it ends")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Orisa), Button(Secondary Fire)), Custom String( + "Flaming Harpoon: Energy Javelin stuns for longer and burns enemies")); + Else If(Hero Of(Event Player) == Hero(Pharah)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ability 2)), Custom String( + "Head Trauma: Concussive Blast deals damage and tazes enemies below half health")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Pharah), Button(Ability 1)), Custom String( + "Weaponized Storm: Every 6th rocket flies faster and detonates several clusters")); + Else If(Hero Of(Event Player) == Hero(Ramattra)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Ramattra), Button(Ability 1)), Custom String( + "Vile Dominance: Move faster and root enemies with every punch in nemesis form")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Ramattra), Button(Ultimate)), Custom String( + "Nether Sector: Heal and gain bonus ultimate charge for every enemy grounded with vortex")); + Else If(Hero Of(Event Player) == Hero(Reaper)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Reaper), Button(Ability 1)), Custom String( + "Wraith Wrath: Shooting is enabled during wraith form with increased damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Reaper), Button(Ultimate)), Custom String( + "Gloom: Wraith form instantly tazes all enemies in sight")); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Reinhardt), Button(Ability 2)), Custom String( + "Fire Blast: Fire Strike explodes as it deals damage, igniting enemies")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Reinhardt), Button(Ultimate)), Custom String( + "Epicenter: Earth shatter travels in all directions")); + Else If(Hero Of(Event Player) == Hero(Roadhog)); + Event Player.heroTalentText[1] = Array(Icon String(Poison), Custom String( + "Stench: Constantly inflict toxic damage to nearby enemeis")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Roadhog), Button(Ability 1)), Custom String( + "Chainsnap: Chain Hook deals 4x more damage; resets upon eliminations")); + Else If(Hero Of(Event Player) == Hero(Sigma)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Sigma), Button(Ability 1)), Custom String( + "Accretion Disk: Accretion flies straight and has increased damage and stun")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Sigma), Button(Ultimate)), Custom String( + "String Theory: When kinetic grasp ends, fire a blast that scales based on the amount of damage collected")); + Else If(Hero Of(Event Player) == Hero(Sojourn)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Sigma), Button(Ability 1)), Custom String( + "Thunderous kicks: Kickslide Jump initiates a powerful energy blast")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Sigma), Button(Ultimate)), Custom String( + "Matter Splatter: Critical railgun hits are explosive")); + Else If(Hero Of(Event Player) == Hero(Soldier: 76)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ultimate)), Custom String( + "Triple Threat: Helix Rockets fires two adjacent mini rockets")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Soldier: 76), Button(Ability 1)), Custom String( + "Espionage: Allies in biotic field revive faster and become harder to hit")); + Else If(Hero Of(Event Player) == Hero(Sombra)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Sombra), Button(Secondary Fire)), Custom String( + "Going Viral: Cancelling stealth will trigger a small hack explosion")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Sombra), Button(Ultimate)), Custom String( + "Cyberattack: Using translocator will damage and hack nearby enemies")); + Else If(Hero Of(Event Player) == Hero(Symmetra)); + Event Player.heroTalentText[1] = Array(Icon String(Bolt), Custom String( + "Sentry Paragon: Each sentry turret deals 50% more damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ultimate)), Custom String( + "Shield Generator: Gain increased damage and speed, and grant all players shields with kills")); + Else If(Hero Of(Event Player) == Hero(Torbjörn)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Torbjörn), Button(Ability 2)), Custom String( + "Heatwaves: Unleash waves of fire when overload or molten core is active")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Torbjörn), Button(Ultimate)), Custom String( + "melting point: Every turret kill boosts its damage to 200% for a short duration")); + Else If(Hero Of(Event Player) == Hero(Tracer)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Tracer), Button(Ability 2)), Custom String( + "Vortex: Recall drags and roots nearby enemies to its activation point")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Tracer), Button(Ultimate)), Custom String( + "Chain Reaction: Pulse Bomb explosions can chain onto other enemies")); + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Widowmaker), Button(Ultimate)), Custom String( + "Baiser de Soie: Scoped critical hits instantly kill enemies below 30% hp")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Widowmaker), Button(Ability 2)), Custom String( + "Felt More Alive: Gain low gravity and deal 40% more damage when scoping airbourne")); + Else If(Hero Of(Event Player) == Hero(Winston)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Winston), Button(Ability 2)), Custom String( + "Lightning Strikes Twice: Direct zap hits will trigger twice")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Winston), Button(Ultimate)), Custom String( + "Quake: Jump Pack landing force is much more powerful and stuns enemies")); + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ultimate)), Custom String( + "Mirror Ball: Reflect 100% of received damage to nearby enemies")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ability 2)), Custom String( + "Distortion: Adaptive shields triggers explosions and tazes nearby enemies")); + Else If(Hero Of(Event Player) == Hero(Zarya)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Zarya), Button(Ability 1)), Custom String( + "Combusta-Bubble: Barriers explode when they expire")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Power Surge: Personal barrier grants energy upon activation")); + Else If(Hero Of(Event Player) == Hero(Zenyatta)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Stress Relief: Fully charged orb volleys deal 50% more damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Zenyatta), Button(Ultimate)), Custom String( + "Perfect Balance: Transcendence damages enemies in the area of effect")); + End; + } +} + +rule("Subroutine: Cancel player momentum") +{ + event + { + Subroutine; + CancelMomentum; + } + + actions + { + Apply Impulse(Event Player, -1 * Direction From Angles(Horizontal Angle From Direction(Velocity Of(Event Player)), 0), 0.001, + To World, Cancel Contrary Motion XYZ); + } +} + +rule("Ana: Sleep Paralysis") +{ + event + { + Player Dealt Damage; + Team 1; + Ana; + } + + actions + { + Abort If(!Event Player.abilities[8]); + Abort If(Event Ability != Button(Ability 1)); + Play Effect(All Players(All Teams), Good Explosion, Color(Black), Victim, 2); + Wait(0.500, Ignore Condition); + Wait Until(!Has Status(Victim, Asleep), 5); + Play Effect(All Players(All Teams), Explosion Sound, Color(Black), Eye Position(Victim), 150); + Play Effect(All Players(All Teams), Good Explosion, Color(Black), Victim, 6); + Play Effect(All Players(All Teams), Ring Explosion, Color(Black), Victim, 12); + Damage(Players Within Radius(Victim, 6, Team 2, Surfaces), Event Player, 150); + Set Status(Players Within Radius(Eye Position(Victim), 6, Team 2, Surfaces), Null, Hacked, 1.500); + } +} + +rule("Ana: Multinade") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + For Player Variable(Event Player, loopIterator, 0, 4, 1); + Wait(0.030, Ignore Condition); + Set Ability Cooldown(Event Player, Button(Ability 2), False); + Cancel Primary Action(Event Player); + Wait(0.050, Ignore Condition); + Press Button(Event Player, Button(Ability 2)); + End; + Wait(2, Ignore Condition); + } +} + +rule("Ashe: Taunt") +{ + event + { + Player Dealt Knockback; + Team 1; + Ashe; + } + + conditions + { + Event Player.abilities[8] == True; + Event Ability == Button(Ability 1); + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 3, Event Damage * 2.500); + Set Status(Victim, Null, Burning, 3); + Set Status(Victim, Null, Stunned, 3); + } +} + +rule("Ashe: Dancing Flames") +{ + event + { + Player Earned Elimination; + Team 1; + Ashe; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Victim.deathPosition, 120); + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim.deathPosition, 5); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Yellow), Victim.deathPosition, 5); + Start Damage Over Time(Players Within Radius(Victim.deathPosition, 5, Team 2, Surfaces), Event Player, 3, 15); + Set Status(Players Within Radius(Victim.deathPosition, 5, Team 2, Surfaces), Event Player, Burning, 3); + Damage(Players Within Radius(Victim.deathPosition, 5, Team 2, Surfaces), Event Player, 30); + } +} + +rule("Baptiste: Corrode") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + For Player Variable(Event Player, loopIterator, 0, 3, 1); + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 10, Team 2, Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Team 2, Surfaces), Event Player, 5, 30); + Wait(0.200, Ignore Condition); + End; + } +} + +rule("Baptiste: Aerial Ace - Jump") +{ + event + { + Ongoing - Each Player; + All; + Baptiste; + } + + conditions + { + Event Player.abilities[12] == True; + Is Crouching(Event Player) == True; + Has Status(Event Player, Hacked) == False; + } + + actions + { + Wait Until(!Is Crouching(Event Player), 9999); + Wait Until(Is Jumping(Event Player), 1); + Event Player.abilityAvailable = True; + Wait(0.250, Ignore Condition); + Event Player.damageBoost[1] += 30; + Call Subroutine(UpdatePlayerStats); + Wait Until(Is On Ground(Event Player), 99999); + Event Player.abilityAvailable = False; + Event Player.damageBoost[1] -= 30; + Call Subroutine(UpdatePlayerStats); + } +} + +rule("Baptiste: Aerial Ace - Slower fall") +{ + event + { + Ongoing - Each Player; + All; + Baptiste; + } + + conditions + { + Event Player.abilities[12] == True; + Event Player.abilityAvailable == True; + Is Alive(Event Player) == True; + Is Button Held(Event Player, Button(Jump)) == True; + (Has Status(Event Player, Stunned) && Has Status(Event Player, Hacked)) == False; + Altitude Of(Event Player) >= 1; + Vertical Speed Of(Event Player) < 0; + } + + actions + { + Set Gravity(Event Player, 7.500); + Wait(0.333, Ignore Condition); + Play Effect(All Players(Team Of(Event Player)), Ring Explosion, Color(Orange), Position Of(Event Player), 2); + Loop If Condition Is True; + Set Gravity(Event Player, 100); + } +} + +rule("Bastion: Fusillade") +{ + event + { + Ongoing - Each Player; + All; + Bastion; + } + + conditions + { + Event Player.abilities[8] == True; + Is Firing Primary(Event Player) == True; + Is In Alternate Form(Event Player) == True; + } + + actions + { + Wait(1.500, Abort When False); + Cancel Primary Action(Event Player); + Set Ability Cooldown(Event Player, Button(Secondary Fire), 0); + Wait(0.100, Ignore Condition); + Press Button(Event Player, Button(Secondary Fire)); + Loop If Condition Is True; + } +} + +rule("Bastion: Trickshot") +{ + event + { + Player Dealt Damage; + All; + Bastion; + } + + actions + { + Abort If(!Event Player.abilities[12]); + Abort If(Event Ability != Button(Secondary Fire)); + Abort If(Event Damage > 30); + Wait(0.500, Ignore Condition); + Set Ability Cooldown(Event Player, Button(Secondary Fire), Ability Cooldown(Event Player, Button(Secondary Fire)) - 3); + Damage(Players Within Radius(Victim, 5, Team 2, Surfaces), Event Player, 30); + Heal(Event Player, Event Player, 50); + } +} + +rule("Brigitte: Endeavor") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Event Player.abilities[8] == True; + Ability Cooldown(Event Player, Button(Secondary Fire)) >= 0.100; + } + + actions + { + Create Effect(All Players(All Teams), Echo Cloning Effect, Team 1, Event Player, 0.400, Visible To Position and Radius); + Event Player.effects[1] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Eye Position(Event Player), 15); + Heal(Players Within Radius(Event Player, 15, Team 1, Off), Event Player, 200); + Event Player.damageBoost[1] += 150; + Event Player.speedBoost += 75; + Call Subroutine(UpdatePlayerStats); + Add Health Pool To Player(Event Player, Armor, Max Health(Event Player) / 3, False, True); + Event Player.hpPool[1] = Last Created Health Pool; + Wait Until(!Event Player.abilities[8] || Is Dead(Event Player), 6); + Event Player.damageBoost[1] -= 150; + Event Player.speedBoost -= 75; + Call Subroutine(UpdatePlayerStats); + Remove Health Pool From Player(Event Player.hpPool[1]); + Destroy Effect(Event Player.effects[1]); + } +} + +rule("Brigitte: Whiplash") +{ + event + { + Player Dealt Knockback; + Team 1; + Brigitte; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Green), Victim, 100); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Victim, 2.500); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Orange), Victim, 2.500); + Damage(Players Within Radius(Victim, 2.500, Team 2, Surfaces), Event Player, 100); + Set Status(Players Within Radius(Victim, 2.500, Team 2, Surfaces), Event Player, Stunned, 1.500); + } +} + +rule("Cassidy: Standoff") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Wait(0.200, Ignore Condition); + Event Player.abilityCountdown = False; + Chase Player Variable At Rate(Event Player, abilityCountdown, 9999, 100, Destination and Rate); + Wait(0.500, Ignore Condition); + Chase Player Variable At Rate(Event Player, abilityCountdown, 9999, 275, Destination and Rate); + Wait(0.500, Ignore Condition); + Chase Player Variable At Rate(Event Player, abilityCountdown, 9999, 550, Destination and Rate); + } +} + +rule("Cassidy: Standoff - Set root") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Wait(0.200, Ignore Condition); + For Player Variable(Event Player, loopIterator, 0, 5, 1); + Wait(1, Abort When False); + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 15); + Set Status(Filtered Array(Players in View Angle(Event Player, Team 2, 103), Health(Current Array Element) + <= Event Player.abilityCountdown && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS)), + Event Player, Rooted, 2); + End; + Stop Chasing Player Variable(Event Player, abilityCountdown); + } +} + +rule("Cassidy: Flashpoint") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + actions + { + Abort If(!Event Player.abilities[12]); + Abort If(Event Ability != Button(Ability 2)); + If(Event Damage <= 5); + Wait(1.250, Ignore Condition); + Damage(Players Within Radius(Victim, 6, Team 2, Surfaces), Event Player, 35); + Set Status(Players Within Radius(Victim, 6, Team 2, Surfaces), Event Player, Stunned, 1); + End; + } +} + +rule("D.Va: Voltage Grid") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 2, 0.150); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 5, 0.150); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 8, 0.150); + Wait(0.300, Ignore Condition); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Team 2, Off), Event Player, + 20); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Team 2, Off), Event Player, + 20); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Team 2, Off), Event Player, + 20); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Team 2, Off), + Event Player, Rooted, 0.400); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Team 2, Off), + Event Player, Rooted, 0.400); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Team 2, Off), + Event Player, Rooted, 0.400); + Loop If Condition Is True; + } +} + +rule("D.Va: Shooting Star") +{ + event + { + Player Dealt Knockback; + Team 1; + D.Va; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, 30); + Set Status(Victim, Null, Burning, 3); + Start Damage Over Time(Victim, Event Player, 3, 35); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 1); + } +} + +rule("Doomfist: Punch Card") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Event Player.abilities[8] == True; + Is Firing Secondary(Event Player) == True; + } + + actions + { + Wait(1, Abort When False); + Event Player.damageBoost[1] += 200; + Call Subroutine(UpdatePlayerStats); + Wait Until(Ability Cooldown(Event Player, Button(Secondary Fire)) > 0.100, 1); + Event Player.damageBoost[1] -= 200; + Call Subroutine(UpdatePlayerStats); + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Wait(1.250, Abort When False); + Wait Until(Is On Ground(Event Player), 10); + Abort If(!Is On Ground(Event Player)); + Event Player.abilityProjectile = Position Of(Event Player); + Event Player.abilityActive = True; + Wait Until(Is Dead(Event Player), 5); + Event Player.abilityActive = False; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Event Player.abilityActive == True; + Event Player.abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player.abilityProjectile, 8, Visible To Position and Radius); + Event Player.effects[1] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(Orange), Event Player.abilityProjectile, 8, Visible To Position and Radius); + Event Player.effects[2] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player.abilityProjectile, 16); + While(Event Player.abilityActive && Event Player.abilities[12]); + Damage(Players Within Radius(Event Player.abilityProjectile, 8, Team 2, Off), Event Player, 20); + Wait(0.235, Ignore Condition); + End; + Destroy Effect(Event Player.effects[1]); + Destroy Effect(Event Player.effects[2]); + } +} + +rule("Echo: Silver Lining") +{ + event + { + Player Dealt Damage; + Team 1; + Echo; + } + + actions + { + Abort If(!Event Player.abilities[8]); + Abort If(Event Ability != Button(Secondary Fire)); + Abort If(Is Duplicating(Event Player)); + Abort If(Normalized Health(Victim) > 0.500); + Damage(Victim, Event Player, Event Damage); + } +} + +rule("Echo: Focusing Optics") +{ + event + { + Player Dealt Damage; + Team 1; + Echo; + } + + actions + { + Abort If(!Event Player.abilities[12]); + Abort If(Event Ability != Button(Ability 2)); + Abort If(Is Duplicating(Event Player)); + Abort If(Normalized Health(Victim) <= 0.500); + Abort If(Normalized Health(Victim) > 0.900); + Damage(Victim, Event Player, Event Damage * 3); + Play Effect(All Players(All Teams), Bad Explosion, Color(Violet), Victim, 0.500); + } +} + +rule("Genji: Venomous Strike") +{ + event + { + Player Dealt Damage; + Team 1; + Genji; + } + + actions + { + Abort If(!Event Player.abilities[8]); + Abort If(Event Ability != Button(Ability 1)); + Start Heal Over Time(Event Player, Event Player, 3, 15); + Start Damage Over Time(Victim, Event Player, 3, 15); + Heal(Event Player, Event Player, 5); + Wait(0.250, Restart When True); + Wait(2, Ignore Condition); + } +} + +rule("Genji: Dragon's Breath") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ultimate(Event Player) == True; + Is Firing Primary(Event Player) == True; + } + + actions + { + Create Effect(All Players(All Teams), Good Aura, Color(Lime Green), Event Player.abilityProjectile, 1, + Visible To Position and Radius); + Event Player.effects[1] = Last Created Entity; + Event Player.abilityProjectile = Eye Position(Event Player); + Chase Player Variable At Rate(Event Player, abilityProjectile, Event Player.abilityEnd, 80, Destination and Rate); + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Team 2), All Players(Team 1), True); + Wait Until(!Event Player.abilities[12] || Event Player.abilityEnd == Event Player.abilityProjectile, 1); + Destroy Effect(Event Player.effects[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Green), Event Player.abilityProjectile, 100); + Play Effect(All Players(All Teams), Bad Explosion, Color(Lime Green), Event Player.abilityProjectile, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Green), Event Player.abilityProjectile, 5); + Damage(Players Within Radius(Event Player.abilityProjectile, 5, Team 2, Surfaces), Event Player, 150); + Stop Chasing Player Variable(Event Player, abilityCountdown); + } +} + +rule("Hanzo: Firebolt") +{ + event + { + Ongoing - Each Player; + Team 1; + Hanzo; + } + + conditions + { + Event Player.abilities[8] == True; + Is Firing Primary(Event Player) == True; + } + + actions + { + For Player Variable(Event Player, loopIterator, 0, 1, 1); + Wait(1, Abort When False); + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 100); + End; + Play Effect(All Players(All Teams), Bad Explosion, Color(Sky Blue), Eye Position(Event Player) + Vector(0, -0.250, False) + + Facing Direction Of(Event Player), 1); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Team 1), Event Player, 100); + While(Is Firing Primary(Event Player)); + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Eye Position(Event Player) + Vector(0, -0.250, False) + + Facing Direction Of(Event Player) * 0.700, 0.001); + End; + Abort If(Has Status(Event Player, Stunned) || Is Dead(Event Player) || Is Button Held(Event Player, Button(Secondary Fire)) + || Has Status(Event Player, Asleep)); + Event Player.abilityProjectile = Eye Position(Event Player) + Facing Direction Of(Event Player) * Vector(False, False, 2); + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 200, All Living Players(All Teams), Event Player, False); + Set Projectile Speed(Event Player, 150); + Chase Player Variable At Rate(Event Player, abilityProjectile, Event Player.abilityEnd, 165, Destination and Rate); + While(Event Player.abilityProjectile != Event Player.abilityEnd); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Orange), Event Player.abilityProjectile, 3.500); + Play Effect(All Players(All Teams), Explosion Sound, Color(Team 1), Event Player.abilityProjectile, 35); + Wait(0.072, Ignore Condition); + End; + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Event Player.abilityProjectile, 4); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Team 1), Event Player.abilityProjectile, 150); + Damage(Players Within Radius(Event Player.abilityProjectile, 4, Team 2, Surfaces), Event Player, 175); + Set Projectile Speed(Event Player, 100); + Stop Chasing Player Variable(Event Player, abilityProjectile); + } +} + +rule("Hanzo: Stormbreak") +{ + event + { + Player Dealt Final Blow; + Team 1; + Hanzo; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Event Player.abilityCountdown = 4; + Chase Player Variable At Rate(Event Player, abilityCountdown, 0, 1, Destination and Rate); + } +} + +rule("Hanzo: Stormbreak - Boost") +{ + event + { + Ongoing - Each Player; + Team 1; + Hanzo; + } + + conditions + { + Event Player.abilities[12] == True; + Event Player.abilityCountdown > 0; + } + + actions + { + Create Effect(All Players(All Teams), Winston Primal Rage Effect, Color(Team 1), Event Player, 1, Visible To Position and Radius); + Event Player.effects[1] = Last Created Entity; + Wait Until(Is Dead(Event Player) || !Event Player.abilityCountdown || !Event Player.abilities[12], 99999); + Event Player.abilityCountdown = False; + Destroy Effect(Event Player.effects[1]); + Stop Chasing Player Variable(Event Player, abilityCountdown); + } +} + +rule("Hanzo: Stormbreak - Reset Cooldowns For Storm Arrows") +{ + event + { + Ongoing - Each Player; + Team 1; + Hanzo; + } + + conditions + { + Event Player.abilityCountdown > 0; + Ability Cooldown(Event Player, Button(Ability 2)) > 0; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), False); + } +} + +rule("Junker Queen: Shout Very Loudly") +{ + event + { + Ongoing - Each Player; + Team 1; + Junker Queen; + } + + conditions + { + Event Player.abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Start Damage Over Time(Remove From Array(Players Within Radius(Event Player, 15, Team 2, Surfaces), Event Player), Event Player, 5, + 8); + Start Heal Over Time(Event Player, Event Player, 5, 8 * Count Of(Players Within Radius(Event Player, 15, Team 2, Surfaces))); + } +} + +rule("Junker Queen: Grace Period") +{ + event + { + Player Dealt Knockback; + Team 1; + Junker Queen; + } + + conditions + { + Event Player.abilities[12] == True; + Event Ability == Button(Secondary Fire); + Is Meleeing(Event Player) == False; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 2.500, 20); + Start Heal Over Time(Event Player, Event Player, 2.500, 20); + Heal(Event Player, Event Player, 60); + Damage(Victim, Event Player, 40); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 0.250); + } +} + +rule("Junkrat: Pyromania") +{ + event + { + Player Dealt Knockback; + Team 1; + Junkrat; + } + + actions + { + Abort If(!Event Player.abilities[8]); + Abort If(Event Ability == Button(Melee)); + Abort If(Victim == Event Player); + Start Damage Over Time(Victim, Event Player, 2, 20); + Set Status(Victim, Null, Burning, 2); + } +} + +rule("Junkrat: Trigger Happy") +{ + event + { + Ongoing - Each Player; + Team 1; + Junkrat; + } + + conditions + { + Event Player.abilities[12] == True; + Ability Charge(Event Player, Button(Ability 1)) < 5; + } + + actions + { + Wait(4, Abort When False); + Set Ability Charge(Event Player, Button(Ability 1), Ability Charge(Event Player, Button(Ability 1)) + 1); + Loop If Condition Is True; + } +} + +rule("Kiriko: Shinobi Tactics") +{ + event + { + Player Dealt Healing; + Team 1; + Kiriko; + } + + actions + { + Abort If(!Event Player.abilities[8]); + Abort If(Event Ability == Null); + Damage(Players Within Radius(Healee, 6, Team 2, Surfaces), Event Player, Event Healing * 2); + } +} + +rule("Kiriko: Recession") +{ + event + { + Player Dealt Knockback; + Team 1; + Kiriko; + } + + conditions + { + Event Player.abilities[12] == True; + Event Ability == Button(Ability 2); + } + + actions + { + Damage(Victim, Event Player, 75); + Set Status(Victim, Event Player, Frozen, 1.500); + Play Effect(All Players(All Teams), Good Explosion, Color(Gray), Victim, 1); + } +} + +rule("Lucio: Power Skating - Damage") +{ + event + { + Player Dealt Knockback; + Team 1; + Lúcio; + } + + conditions + { + Event Player.abilities[8] == True; + Event Ability == Button(Secondary Fire); + } + + actions + { + Damage(Victim, Event Player, Speed Of(Event Player) * 5); + Apply Impulse(Victim, Facing Direction Of(Event Player), Speed Of(Event Player) * 1.500, To World, Cancel Contrary Motion); + Apply Impulse(Victim, Up, 4, To World, Incorporate Contrary Motion); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Victim, 0.010); + } +} + +rule("Lucio: Reverse Amp") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + If(Is Using Ability 1(Event Player)); + Set Status(Players Within Radius(Event Player, 12, Team 2, Surfaces), Event Player, Rooted, 0.750); + Else; + Damage(Players Within Radius(Event Player, 12, Team 2, Surfaces), Event Player, 30); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Mei: Cold Snap") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Event Player.abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Wait(0.500, Abort When False); + Wait Until(!Is Using Ability 1(Event Player), 99999); + Damage(Players Within Radius(Eye Position(Event Player), 10, Team 2, Surfaces), Event Player, 35); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Team 2, Surfaces), Event Player, Frozen, 2); + Play Effect(All Players(All Teams), Ring Explosion, Color(Sky Blue), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player) + Vector(0, 1, False), 20); + } +} + +rule("Mei: Polar Vortex") +{ + event + { + Ongoing - Each Player; + All; + Mei; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ultimate(Event Player) == True; + } + + actions + { + Event Player.damageBoost[1] += 75; + Call Subroutine(UpdatePlayerStats); + For Player Variable(Event Player, loopIterator, 0, 3, 1); + Wait(0.016, Ignore Condition); + Set Ultimate Charge(Event Player, 100); + Press Button(Event Player, Button(Ultimate)); + Wait(0.510, Ignore Condition); + End; + Event Player.damageBoost[1] -= 75; + Call Subroutine(UpdatePlayerStats); + Set Ultimate Charge(Event Player, 0); + Wait(1, Ignore Condition); + } +} + +rule("Mercy: Wings of Grand") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + conditions + { + Event Player.abilities[8] == True; + Is Alive(Event Player) == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + If(Speed Of(Event Player) > 10); + Damage(Filtered Array(Players Within Radius(Event Player, 4, Team 2, Surfaces), !Has Status(Current Array Element, Knocked Down)), + Event Player, 35); + Set Status(Players Within Radius(Event Player, 4, Team 2, Surfaces), Event Player, Knocked Down, 0.800); + Apply Impulse(Players Within Radius(Event Player, 4, Team 2, Surfaces), Normalize(Velocity Of(Event Player)) + Direction Towards( + Event Player, Throttle Of(Event Player)) + Up * 1.100, 7.500, To World, Cancel Contrary Motion); + Play Effect(All Players(All Teams), Bad Explosion, Color(Yellow), Position Of(Event Player), 0.150); + End; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Mercy: Holy Light Missiles") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ultimate(Event Player) == True; + } + + actions + { + Create Effect(All Players(All Teams), Orb, Color(Yellow), Event Player.abilityProjectile, 1, Visible To Position and Radius); + Event Player.effects[1] = Last Created Entity; + Event Player.abilityProjectile = Eye Position(Event Player); + Chase Player Variable At Rate(Event Player, abilityProjectile, Event Player.abilityEnd, 100, Destination and Rate); + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Team 2), All Players(Team 1), True); + Wait Until(!Event Player.abilities[12] || Event Player.abilityEnd == Event Player.abilityProjectile, 1); + Destroy Effect(Event Player.effects[1]); + Stop Chasing Player Variable(Event Player, abilityCountdown); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Green), Event Player.abilityProjectile, 100); + Play Effect(All Players(All Teams), Bad Explosion, Color(Yellow), Event Player.abilityProjectile, 6); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player.abilityProjectile, 6); + Damage(Players Within Radius(Event Player.abilityProjectile, 6, Team 2, Surfaces), Event Player, 150); + Heal(Players Within Radius(Event Player.abilityProjectile, 6, Team 1, Surfaces), Event Player, 150); + Wait(1.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Moira: Flourish") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Start Damage Over Time(Players Within Radius(Event Player, 3, Team 2, Surfaces), Event Player, 2, 25); + Start Heal Over Time(Players Within Radius(Event Player, 3, Team 1, Surfaces), Event Player, 2, 40); + Play Effect(All Players(All Teams), Ring Explosion, Color(Black), Position Of(Event Player), 6); + Wait(0.200, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Moira: Catalyst") +{ + event + { + Ongoing - Each Player; + All; + Moira; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ultimate(Event Player) == True; + Is Button Held(Event Player, Button(Primary Fire)) == True; + Ability Resource(Event Player, Button(Primary Fire)) > 8; + } + + actions + { + Event Player.damageBoost[1] += 300; + Event Player.healBoost[1] += 300; + Event Player.speedBoost -= 40; + Call Subroutine(UpdatePlayerStats); + Wait Until(!Is Button Held(Event Player, Button(Primary Fire)) || !Event Player.abilities[12] || !Is Using Ultimate(Event Player), + 8); + Event Player.damageBoost[1] -= 300; + Event Player.speedBoost += 40; + Event Player.healBoost[1] -= 300; + Call Subroutine(UpdatePlayerStats); + Wait(0.250, Ignore Condition); + } +} + +rule("Moira: Catalyst") +{ + event + { + Ongoing - Each Player; + All; + Moira; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ultimate(Event Player) == True; + Is Button Held(Event Player, Button(Primary Fire)) == True; + Ability Resource(Event Player, Button(Primary Fire)) > 8; + } + + actions + { + Set Ability Resource(Event Player, Button(Primary Fire), Ability Resource(Event Player, Button(Primary Fire)) - 15); + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Eye Position(Event Player), 10); + Damage(Players Within Radius(Eye Position(Event Player), 5, Team 2, Surfaces), Event Player, 35); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Orisa: Melting Point") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Event Player.abilities[8] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Wait Until(!Is Using Ability 2(Event Player), 99999); + Damage(Players Within Radius(Event Player, 12, Team 2, Surfaces), Event Player, 70); + Play Effect(All Players(All Teams), Ring Explosion, Color(Lime Green), Position Of(Event Player), 24); + Apply Impulse(Players Within Radius(Event Player, 12, Team 2, Surfaces), Up, 8, To World, Cancel Contrary Motion); + Set Status(Players Within Radius(Event Player, 12, Team 2, Surfaces), Event Player, Rooted, 1.500); + } +} + +rule("Orisa: Flaming Harpoon") +{ + event + { + Player Dealt Knockback; + Team 1; + Orisa; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Event Player.abilities[12] == True; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 3, 20); + Set Status(Victim, Null, Burning, 3); + Set Status(Victim, Event Player, Stunned, 1); + } +} + +rule("Pharah: Head Trauma") +{ + event + { + Player Dealt Knockback; + Team 1; + Pharah; + } + + conditions + { + Event Player.abilities[8] == True; + Event Ability == Button(Ability 2); + Victim != Event Player; + } + + actions + { + Damage(Victim, Event Player, 60); + Play Effect(All Players(All Teams), Good Explosion, Color(Gray), Victim, 1); + Abort If(Normalized Health(Victim) > 0.500); + Set Status(Victim, Null, Hacked, 1); + } +} + +rule("Pharah: Weaponized Storm") +{ + event + { + Ongoing - Each Player; + All; + Pharah; + } + + conditions + { + Event Player.abilities[12] == True; + Is Firing Primary(Event Player) == True; + Ammo(Event Player, False) % 6 == False; + } + + actions + { + Set Projectile Speed(Event Player, 125); + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 100, All Living Players(All Teams), Event Player, True); + Event Player.abilityProjectile = Eye Position(Event Player); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Event Player.abilityProjectile, 1, Visible To Position and Radius); + Event Player.effects[7] = Last Created Entity; + Chase Player Variable At Rate(Event Player, abilityProjectile, Event Player.abilityEnd, 35, Destination and Rate); + Wait Until(!Event Player.abilities[12] || Event Player.abilityProjectile == Event Player.abilityEnd, 99999); + Destroy Effect(Event Player.effects[7]); + For Player Variable(Event Player, loopIterator, 0, 6, 1); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Orange), Event Player.abilityProjectile + Vector(Random Real(-1.500, + 1.500), Random Real(-0.500, 0.500), Random Real(-1.500, 1.500)), 1); + Play Effect(All Players(All Teams), Explosion Sound, Color(Team 1), Event Player.abilityProjectile, 25); + Damage(Players Within Radius(Event Player.abilityProjectile, 4, Team 2, Surfaces), Event Player, 20); + Wait(0.100, Ignore Condition); + End; + Set Projectile Speed(Event Player, 100); + Stop Chasing Player Variable(Event Player, abilityProjectile); + } +} + +rule("Ramattra: Vile Dominance") +{ + event + { + Ongoing - Each Player; + Team 1; + Ramattra; + } + + conditions + { + Event Player.abilities[8] == True; + Health Of Type(Event Player, Armor) >= 100; + } + + actions + { + Event Player.speedBoost += 30; + Event Player.abilityActive = True; + Call Subroutine(UpdatePlayerStats); + Wait Until((Ability Cooldown(Event Player, Button(Ability 1)) > 0.100 && !Is Using Ultimate(Event Player)) + || !Event Player.abilities[8], 9999); + Event Player.speedBoost -= 30; + Event Player.abilityActive = False; + Call Subroutine(UpdatePlayerStats); + } +} + +rule("Ramattra: Vile Dominance") +{ + event + { + Player Dealt Damage; + Team 1; + Ramattra; + } + + actions + { + Abort If(!Event Player.abilityActive); + Abort If(Event Ability == Null); + Abort If(Event Ability == Button(Ability 2)); + Abort If(Event Ability == Button(Ultimate)); + Set Status(Victim, Event Player, Rooted, 0.750); + } +} + +rule("Ramattra: Nether Sector") +{ + event + { + Player Dealt Damage; + Team 1; + Ramattra; + } + + actions + { + Abort If(!Event Player.abilities[12]); + Abort If(!Is On Ground(Event Player)); + Abort If(Event Ability != Button(Ability 2)); + Heal(Event Player, Event Player, 20); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 1); + Wait(0.100, Ignore Condition); + } +} + +rule("Reaper: Wraith Wrath") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Wait(0.100, Abort When False); + Cancel Primary Action(Event Player); + Create Effect(All Players(All Teams), Reaper Wraith Form Effect, Color(Team 1), Event Player, True, + Visible To Position and Radius); + Event Player.effects[1] = Last Created Entity; + Event Player.damageBoost[1] += 30; + Event Player.speedBoost += 50; + Call Subroutine(UpdatePlayerStats); + Disallow Button(Event Player, Button(Ability 1)); + Set Status(Event Player, Null, Phased Out, 3); + Wait Until(Is Dead(Event Player) || !Event Player.abilities[8], 3); + Allow Button(Event Player, Button(Ability 1)); + Set Ability Cooldown(Event Player, Button(Ability 1), 8); + Event Player.damageBoost[1] -= 30; + Event Player.speedBoost -= 50; + Call Subroutine(UpdatePlayerStats); + Destroy Effect(Event Player.effects[1]); + } +} + +rule("Reaper: Loom") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players in View Angle(Event Player, Team 2, 45), Is In Line of Sight(Event Player, Current Array Element, + Barriers Do Not Block LOS)), Event Player, Hacked, 2); + Damage(Filtered Array(Players in View Angle(Event Player, Team 2, 45), Is In Line of Sight(Current Array Element, Event Player, + Barriers Do Not Block LOS)), Event Player, 35); + } +} + +rule("Reinhardt: Fire Blast") +{ + event + { + Player Dealt Damage; + Team 1; + Reinhardt; + } + + actions + { + Abort If(!Event Player.abilities[8]); + Abort If(Event Ability != Button(Ability 2)); + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Start Damage Over Time(Players Within Radius(Victim, 5, Team 2, Surfaces), Event Player, 5, 20); + Set Status(Players Within Radius(Victim, 5, Team 2, Surfaces), Event Player, Burning, 5); + } +} + +rule("Reinhardt: Epicenter") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ultimate(Event Player) == True; + Is On Ground(Event Player) == True; + } + + actions + { + Set Status(Players Within Radius(Event Player, 20, Team 2, Surfaces), Event Player, Knocked Down, 2.500); + For Player Variable(Event Player, loopIterator, 0, 3, 1); + Wait(0.032, Ignore Condition); + Damage(Players Within Radius(Event Player, Event Player.loopIterator * 10, Team 2, Surfaces), Event Player, 50); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), Event Player.loopIterator * 20); + End; + Wait(5, Ignore Condition); + } +} + +rule("Roadhog: Stench") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.abilities[8] == True; + Is Alive(Event Player) == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Violet), Event Player, 8, Visible To Position and Radius); + Event Player.effects[1] = Last Created Entity; + Wait Until(!Event Player.abilities[8] || Is Dead(Event Player), 99999); + Destroy Effect(Event Player.effects[1]); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Stench effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Distance Between(Event Player, Closest Player To(Event Player, Team 2)) <= 8; + Event Player.abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 8, Team 2, Surfaces), Event Player, 9); + Wait(0.400, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Chainsnap") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.abilities[12] == True; + Is Alive(Event Player) == True; + } + + actions + { + Start Damage Modification(Is Using Ability 1(Event Player) ? All Players(Team 2) : Empty Array, Event Player, 400, + Receivers Damagers and Damage Percent); + Event Player.damageMod = Last Damage Modification ID; + Wait Until(!Event Player.abilities[12] || Is Dead(Event Player), 99999); + Stop Damage Modification(Event Player.damageMod); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Chainsnap - Reset cooldown") +{ + event + { + Player Earned Elimination; + Team 1; + Roadhog; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ability 1(Event Player), 3); + Set Ability Cooldown(Event Player, Button(Ability 1), False); + } +} + +rule("Sigma: Accretion Disk") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Event Player.abilities[8] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Set Projectile Speed(Event Player, 150); + Set Projectile Gravity(Event Player, 0); + Wait Until(!Event Player.abilities[8] || !Is Using Ability 2(Event Player), 5); + Set Projectile Speed(Event Player, 100); + Set Projectile Gravity(Event Player, 100); + } +} + +rule("Sigma: Accretion Disk") +{ + event + { + Player Dealt Knockback; + Team 1; + Sigma; + } + + actions + { + Abort If(!Event Player.abilities[8]); + Abort If(Event Ability != Button(Ability 2)); + Abort If(Victim == Event Player); + Set Status(Victim, Event Player, Knocked Down, 1.500); + Damage(Victim, Event Player, Event Damage * 0.750); + } +} + +rule("Sigma: String Theory") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Wait(1.800, Abort When False); + Event Player.abilityProjectile = Eye Position(Event Player); + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 50, All Players(Team 2), Event Player, True); + Chase Player Variable At Rate(Event Player, abilityProjectile, Event Player.abilityEnd, 40, Destination and Rate); + Create Effect(All Players(All Teams), Sphere, Color(Violet), Event Player.abilityProjectile, 0.600, + Visible To Position and Radius); + Event Player.effects[1] = Last Created Entity; + Create Effect(All Players(All Teams), Good Aura, Color(Violet), Event Player.abilityProjectile, 0.600, + Visible To Position and Radius); + Event Player.effects[2] = Last Created Entity; + Wait(0.250, Ignore Condition); + Event Player.abilityCountdown = Health Of Type(Event Player, Shields); + Wait Until(!Event Player.abilities[12] || Event Player.abilityProjectile == Event Player.abilityEnd, 5); + Stop Chasing Player Variable(Event Player, abilityProjectile); + Destroy Effect(Event Player.effects[1]); + Destroy Effect(Event Player.effects[2]); + Damage(Players Within Radius(Event Player.abilityProjectile, Min(10, 1.500 + Event Player.abilityCountdown * 0.017), Team 2, Off), + Event Player, Min(200, 100 + Event Player.abilityCountdown / 5)); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(Violet), Event Player.abilityProjectile, 150); + Play Effect(All Players(All Teams), Bad Explosion, Color(Violet), Event Player.abilityProjectile, Min(10, + 1.500 + Event Player.abilityCountdown * 0.017)); + Play Effect(All Players(All Teams), Good Explosion, Color(Purple), Event Player.abilityProjectile, Min(10, + 1.500 + Event Player.abilityCountdown * 0.017)); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Event Player.abilityProjectile, Min(20, + 3 + Event Player.abilityCountdown * 0.017)); + } +} + +rule("Sojourn: Thunderout Kicks") +{ + event + { + Ongoing - Each Player; + Team 1; + Sojourn; + } + + conditions + { + Event Player.abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Event Player.abilityActive = 1 + Total Time Elapsed; + Wait Until(Ability Cooldown(Event Player, Button(Ability 1)) > 1 || Is Button Held(Event Player, Button(Jump)), 1); + Abort If(Event Player.abilityActive < Total Time Elapsed); + Play Effect(All Players(All Teams), Ring Explosion, Color(Turquoise), Position Of(Event Player), 12); + Damage(Players Within Radius(Event Player, 6, Team 2, Surfaces), Event Player, 75); + } +} + +rule("Sojourn: Matter Splatter") +{ + event + { + Player Dealt Damage; + Team 1; + Sojourn; + } + + actions + { + Abort If(!Event Player.abilities[12]); + Abort If(Event Ability != Button(Secondary Fire)); + Abort If(!Event Was Critical Hit); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Victim), 3.500); + Damage(Remove From Array(Players Within Radius(Victim, 3.500, Team 2, Surfaces), Victim), Event Player, Event Damage); + } +} + +rule("Soldier76: Triple Threat") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Event Player.abilities[8] == True; + Is Firing Secondary(Event Player) == True; + } + + actions + { + Event Player.abilityCountdown = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position(Event Player), + Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, All Living Players(Team 2), Null, False) + + World Vector Of(Vector(-2, False, False), Event Player, Rotation), All Living Players(Team 2), Null, False); + Event Player.abilityProjectile = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, All Living Players(Team 2), Null, False) + + World Vector Of(Vector(2, False, False), Event Player, Rotation), All Living Players(Team 2), Null, False); + Event Player.abilityAvailable = Eye Position(Event Player) + World Vector Of(Vector(False, -0.250, False), Event Player, Rotation); + Event Player.abilityEnd = Eye Position(Event Player) + World Vector Of(Vector(False, -0.250, False), Event Player, Rotation); + Chase Player Variable At Rate(Event Player, abilityAvailable, Event Player.abilityProjectile, 60, Destination and Rate); + Chase Player Variable At Rate(Event Player, abilityEnd, Event Player.abilityCountdown, 60, Destination and Rate); + } +} + +rule("Soldier76: Triple Threat - First Rocket") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Event Player.abilityProjectile != Event Player.abilityAvailable; + Event Player.abilities[8] == True; + Ability Cooldown(Event Player, Button(Secondary Fire)) > 0.100; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Aqua), Event Player.abilityAvailable, 0.400); + Wait(0.064, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.abilityAvailable, 2.500); + Stop Chasing Player Variable(Event Player, abilityAvailable); + Wait(0.016, Ignore Condition); + Damage(Players Within Radius(Event Player.abilityAvailable, 2.500, Team 2, Surfaces), Event Player, 80); + Stop Chasing Player Variable(Event Player, abilityAvailable); + Event Player.abilityAvailable = False; + Event Player.abilityProjectile = False; + Wait(0.016, Ignore Condition); + } +} + +rule("Soldier76: Triple Threat - Second Rocket") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Event Player.abilityCountdown != Event Player.abilityEnd; + Event Player.abilities[8] == True; + Ability Cooldown(Event Player, Button(Secondary Fire)) > 0.100; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Aqua), Event Player.abilityEnd, 0.400); + Wait(0.064, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.abilityEnd, 2.500); + Stop Chasing Player Variable(Event Player, abilityEnd); + Damage(Players Within Radius(Event Player.abilityEnd, 2.500, Team 2, Surfaces), Event Player, 80); + Event Player.abilityEnd = False; + Event Player.abilityCountdown = False; + } +} + +rule("Soldier76: Triple Threat - Init rocket") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Event Player.abilityProjectile = Event Player.abilityAvailable; + Event Player.abilityCountdown = Event Player.abilityEnd; + } +} + +rule("Soldier76: Espionage") +{ + event + { + Player Dealt Healing; + Team 1; + Soldier: 76; + } + + actions + { + Abort If(!Event Player.abilities[12]); + Abort If(Event Ability != Button(Ability 2)); + If(!Healee.soldierEspionage); + Healee.soldierEspionage = True; + End; + } +} + +rule("Soldier76: Espionage - Allies effect") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.soldierEspionage == True; + } + + actions + { + Event Player.soldierEspionage = False; + Wait(0.400, Ignore Condition); + } +} + +rule("Sombra: Going Viral") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Wait(0.500, Abort When False); + Wait Until(!Is Using Ability 1(Event Player), 20); + Create Effect(All Players(All Teams), Sphere, Color(Purple), Event Player, 24 * Total Time Elapsed % 12, + Visible To Position and Radius); + Event Player.effects[1] = Last Created Entity; + Set Ability Cooldown(Event Player, Button(Secondary Fire), 0); + Set Status(Event Player, Event Player, Invincible, 0.750); + Wait(0.500, Ignore Condition); + Damage(Players Within Radius(Event Player, 12, Team 2, Surfaces), Event Player, 50); + Set Status(Players Within Radius(Event Player, 12, Team 2, Surfaces), Event Player, Hacked, 8); + Destroy Effect(Event Player.effects[1]); + } +} + +rule("Sombra: Cyberattack") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Wait Until(!Is Using Ability 2(Event Player), 99999); + Abort If(Is Button Held(Event Player, Button(Interact)) || Ability Cooldown(Event Player, Button(Ability 2)) >= 2.800); + Abort If(Is Dead(Event Player)); + Wait(0.250, Ignore Condition); + Damage(Players Within Radius(Event Player, 8, Team 2, Surfaces), Event Player, 80); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Eye Position(Event Player), 20000); + Play Effect(All Players(All Teams), Good Explosion, Color(Purple), Eye Position(Event Player), 8); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Eye Position(Event Player), 16); + Set Status(Players Within Radius(Eye Position(Event Player), 8, Team 2, Surfaces), Event Player, Hacked, 3); + } +} + +rule("Symmetra: Sentry Paragon") +{ + event + { + Ongoing - Each Player; + Team 1; + Symmetra; + } + + conditions + { + Event Player.abilities[8] == True; + Is Alive(Event Player) == True; + } + + actions + { + Wait(0.500, Abort When False); + Start Damage Modification(All Players(Team 2), Event Player, 66.667, Receivers Damagers and Damage Percent); + Event Player.damageMod = Last Damage Modification ID; + Event Player.damageBoost[1] += 50; + Call Subroutine(UpdatePlayerStats); + Wait Until(!Event Player.abilities[8] || Is Dead(Event Player), 99999); + Event Player.damageBoost[1] -= 50; + Call Subroutine(UpdatePlayerStats); + Stop Damage Modification(Event Player.damageMod); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Symmetra: Shield Generator") +{ + event + { + Player Dealt Final Blow; + Team 1; + Symmetra; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Event Player.damageBoost[1] += 30; + Event Player.speedBoost += 30; + Call Subroutine(UpdatePlayerStats); + Add Health Pool To Player(All Players(Team 1), Shields, Min(200, Max Health(Event Player) * 0.250), False, False); + Event Player.hpPool[6] = Last Created Health Pool; + Create Effect(All Players(All Teams), Ana Nano Boosted Effect, Color(Team 1), Event Player, 1, Visible To Position and Radius); + Event Player.effects[1] = Last Created Entity; + Wait Until(!Event Player.abilities[12] || Is Dead(Event Player), 10); + Destroy Effect(Event Player.effects[1]); + Remove Health Pool From Player(Event Player.hpPool[6]); + Event Player.damageBoost[1] -= 30; + Event Player.speedBoost -= 30; + Call Subroutine(UpdatePlayerStats); + } +} + +rule("Torbjorn: Heatwave") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Event Player.abilities[8] == True; + (Is Using Ability 2(Event Player) || Is Using Ultimate(Event Player)) == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 11); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 12); + Start Damage Over Time(Remove From Array(Players Within Radius(Event Player, 6, Team 2, Surfaces), Event Player), Event Player, 3, + 20); + Set Status(Remove From Array(Players Within Radius(Event Player, 6, Team 2, Surfaces), Event Player), Event Player, Burning, 3); + Damage(Players Within Radius(Event Player, 6, Team 2, Surfaces), Event Player, 15); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Torbjorn: Melting Point") +{ + event + { + Player Earned Elimination; + Team 1; + Torbjörn; + } + + conditions + { + Event Player.abilities[12] == True; + Event Ability == Button(Ability 1); + } + + actions + { + Event Player.abilityCountdown += 6; + Chase Player Variable At Rate(Event Player, abilityCountdown, 0, 1, Destination and Rate); + } +} + +rule("Torbjorn: Melting Point - Boost") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Event Player.abilities[12] == True; + Event Player.abilityCountdown > 0; + } + + actions + { + Start Damage Modification(All Players(Team 2), Event Player, 33, Receivers Damagers and Damage Percent); + Event Player.damageMod = Last Damage Modification ID; + Event Player.damageBoost[1] += 300; + Call Subroutine(UpdatePlayerStats); + Wait Until(Is Dead(Event Player) || !Event Player.abilityCountdown || !Event Player.abilities[12], 99999); + Event Player.abilityCountdown = False; + Stop Damage Modification(Event Player.damageMod); + Event Player.damageBoost[1] -= 300; + Call Subroutine(UpdatePlayerStats); + Stop Chasing Player Variable(Event Player, abilityCountdown); + } +} + +rule("Tracer: Vortex") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Heal(Players Within Radius(Event Player, 10, Team 2, Surfaces), Event Player, 1); + Damage(Players Within Radius(Event Player, 10, Team 2, Surfaces), Event Player, 25); + Play Effect(All Players(All Teams), Ring Explosion, Color(Red), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Yellow), Position Of(Event Player), 18); + Play Effect(All Players(All Teams), Ring Explosion, Color(Green), Position Of(Event Player), 16); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player), 14); + Set Environment Credit Player(Players Within Radius(Event Player, 10, Team 2, Surfaces), Event Player); + } +} + +rule("Tracer: Vortex 2") +{ + event + { + Player Received Healing; + Team 2; + All; + } + + actions + { + Abort If(!Healer.abilities[8]); + Abort If(!Is Using Ability 2(Healer)); + Disable Movement Collision With Players(Event Player); + Apply Impulse(Event Player, Up, 3, To World, Cancel Contrary Motion); + Set Gravity(Event Player, False); + Wait(0.050, Ignore Condition); + Apply Impulse(Event Player, Direction Towards(Event Player, Healer), Distance Between(Event Player, Healer) * 3.400, To World, + Cancel Contrary Motion); + Set Status(Event Player, Null, Rooted, 1); + Wait(0.230, Ignore Condition); + Set Gravity(Event Player, 100); + Enable Movement Collision With Players(Event Player); + Call Subroutine(CancelMomentum); + } +} + +rule("Tracer: Chain Reaction") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is True For Any(Filtered Array(All Living Players(Team 2), Current Array Element.chainReactionOn), Distance Between(Event Player, + Current Array Element) <= 7) == True; + Event Player.chainReactionImmune == False; + Event Player.chainReactionOn == False; + Is Alive(Event Player) == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Event Player.chainReactionOn = True; + } +} + +rule("Tracer: Chain Reaction 2") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Event Player.chainReactionOn == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Aqua), Event Player, 3); + Damage(Event Player, Players On Hero(Hero(Tracer), Team 1), 200); + Wait(0.500, Ignore Condition); + Event Player.chainReactionImmune = True; + Event Player.chainReactionOn = False; + Wait(2, Ignore Condition); + Event Player.chainReactionImmune = False; + } +} + +rule("Tracer: Chain Reaction 3") +{ + event + { + Player Dealt Damage; + Team 1; + Tracer; + } + + actions + { + Abort If(!Event Player.abilities[12]); + Abort If(Event Ability != Button(Ultimate)); + Abort If(Event Damage <= 20); + Victim.chainReactionOn = True; + } +} + +rule("Widowmaker: Baiser De Soie") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + actions + { + Abort If(!Event Player.abilities[8]); + Abort If(Event Ability != Button(Primary Fire)); + Abort If(!Is Firing Secondary(Event Player)); + Abort If(!Event Was Critical Hit); + Abort If(Normalized Health(Victim) > 0.300); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Violet), Victim, 3); + Damage(Victim, Event Player, 10000); + Damage(Players Within Radius(Victim, 3, Team 2, Surfaces), Event Player, Event Damage); + } +} + +rule("Widowmaker: Felt More Alive") +{ + event + { + Ongoing - Each Player; + Team 1; + Widowmaker; + } + + conditions + { + Event Player.abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is In Air(Event Player) == True; + } + + actions + { + Set Gravity(Event Player, 20); + Event Player.damageBoost[1] += 40; + Call Subroutine(UpdatePlayerStats); + Wait Until(!Is Firing Secondary(Event Player) || !Event Player.abilities[12] || !Is In Air(Event Player), 99999); + Set Gravity(Event Player, 100); + Event Player.damageBoost[1] -= 40; + Call Subroutine(UpdatePlayerStats); + } +} + +rule("Winston: Lightning Strikes Twice") +{ + event + { + Player Dealt Damage; + Team 1; + Winston; + } + + actions + { + Abort If(!Event Player.abilities[8]); + Abort If(Event Ability != Button(Secondary Fire)); + Wait(1, Ignore Condition); + Abort If(Is Dead(Victim)); + Damage(Victim, Event Player, Event Damage); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Victim, 50); + Play Effect(All Players(All Teams), Bad Explosion, Color(Blue), Victim, 1); + } +} + +rule("Winston: Quake") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Wait Until(Is On Ground(Event Player), 99999); + Abort If(Is Dead(Event Player)); + Damage(Players Within Radius(Event Player, 7.500, Team 2, Surfaces And All Barriers), Event Player, 30); + Play Effect(All Players(All Teams), Ring Explosion, Color(White), Position Of(Event Player), 15); + Play Effect(All Players(All Teams), Ring Explosion, Color(Gray), Position Of(Event Player), 14); + Set Status(Players Within Radius(Event Player, 7.500, Team 2, Surfaces And All Barriers), Event Player, Stunned, 1); + } +} + +rule("Wrecking Ball: Mirror Ball") +{ + event + { + Player Took Damage; + Team 1; + Wrecking Ball; + } + + actions + { + Abort If(!Event Player.abilities[8]); + Damage(Players Within Radius(Event Player, 4, Team 2, Surfaces), Event Player, Event Damage * 0.600); + } +} + +rule("Wrecking Ball: Distort") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + For Player Variable(Event Player, loopIterator, False, 4, 1); + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 10, Team 2, Surfaces), Event Player, 25); + Set Status(Players Within Radius(Event Player, 10, Team 2, Surfaces), Event Player, Hacked, 2); + Wait(0.100, Ignore Condition); + End; + } +} + +rule("Zarya: Combusta-bubble - Detect Barrier Target") +{ + event + { + Ongoing - Each Player; + Team 1; + Zarya; + } + + conditions + { + Event Player.abilities[8] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Wait(0.025, Ignore Condition); + Event Player.abilityEnd = First Of(Filtered Array(Players Within Radius(Event Player, 30, Team 1, Surfaces), Has Status( + Current Array Element, Invincible) && Is Alive(Current Array Element) && Is In View Angle(Event Player, Current Array Element, + 103))); + Wait Until(!Is Using Ability 2(Event Player), 2); + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.abilityEnd, 120); + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Eye Position(Event Player.abilityEnd), 6); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Yellow), Eye Position(Event Player.abilityEnd), 6); + Damage(Players Within Radius(Eye Position(Event Player.abilityEnd), 6, Team 2, Surfaces), Event Player.abilityEnd, 100); + } +} + +rule("Zarya: Combusta-Bubble - Self bubble") +{ + event + { + Ongoing - Each Player; + Team 1; + Zarya; + } + + conditions + { + Event Player.abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Wait(0.100, Abort When False); + Wait Until(!Is Using Ability 1(Event Player), 2); + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player, 120); + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Eye Position(Event Player), 6); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Yellow), Eye Position(Event Player), 6); + Damage(Players Within Radius(Event Player, 6, Team 2, Surfaces), Event Player, 100); + } +} + +rule("Zarya: Power Surge") +{ + event + { + Ongoing - Each Player; + Team 1; + Zarya; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Abort If(!Has Status(Event Player, Invincible)); + Damage(Event Player, Null, 10000); + Wait(0.100, Ignore Condition); + Set Ability Cooldown(Event Player, Button(Ability 1), False); + Press Button(Event Player, Button(Ability 1)); + Wait(3, Ignore Condition); + } +} + +rule("Zenyatta: Stress Relief") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + conditions + { + Event Player.abilities[8] == True; + Is Firing Secondary(Event Player) == True; + } + + actions + { + Wait(2, Abort When False); + Play Effect(Event Player, Explosion Sound, Color(Black), Event Player, 150); + Event Player.damageBoost[1] += 50; + Call Subroutine(UpdatePlayerStats); + Wait(0.750, Ignore Condition); + Event Player.damageBoost[1] -= 50; + Call Subroutine(UpdatePlayerStats); + } +} + +rule("Zenyatta: Perfect Balance") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Start Damage Over Time(Players Within Radius(Event Player, 12, Team 2, Surfaces), Event Player, 1, 100); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player, 24); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Team 1 (perk): Bulletstorm") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.perk[1] == True; + (Ammo(Event Player, 0) < Max Ammo(Event Player, 0) || Ammo(Event Player, 1) < Max Ammo(Event Player, 1)) == True; + } + + actions + { + Set Ammo(Event Player, 0, 1000); + Set Ammo(Event Player, 1, 1000); + } +} + +rule("Team 1 Challenges") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + If(Global.perk[2] == 1); + Create HUD Text(Event Player, Null, Custom String("Up You Go"), Null, Left, 917, Color(White), Color(Green), Color(White), + Visible To and String, Default Visibility); + Event Player.abilityHUD[17] = Last Text ID; + End; + If(Global.perk[0] == 1); + Create HUD Text(Event Player, Null, Custom String("Sharpshooter"), Null, Left, 918, Color(White), Color(Green), Color(White), + Visible To and String, Default Visibility); + Event Player.abilityHUD[18] = Last Text ID; + End; + If(Global.perk[1] == 1); + Create HUD Text(Event Player, Null, Custom String("Bulletstorm"), Null, Left, 919, Color(White), Color(Green), Color(White), + Visible To and String, Default Visibility); + Event Player.abilityHUD[19] = Last Text ID; + End; + Call Subroutine(UpdatePlayerStats); + } +} + +rule("Stuff to do when Player leaves") +{ + event + { + Player Left Match; + Team 1; + All; + } + + actions + { + Global.automaticRepair -= Event Player.abilities[16]; + } +} + +rule("Refund") +{ + event + { + Subroutine; + Refund; + } + + actions + { + "Refund Money" + Event Player.money[0] += Event Player.money[1]; + Event Player.money[1] = 0; + "Reset Headhunter" + Event Player.abilities[1] = 0; + "Reset Ambush" + Event Player.abilities[2] = 0; + "Reset QuickFix" + Event Player.abilities[3] = 0; + "Reset HeavyWeight" + Event Player.abilities[4] = 0; + "Reset Charged" + Event Player.abilities[5] = 0; + "Reset Haste" + Event Player.abilities[6] = 0; + "Reset HeavyImpact" + Event Player.abilities[7] = 0; + "Reset HeroTalent1" + Event Player.abilities[8] = 0; + "Reset SecondWind" + Event Player.abilities[9] = 0; + "Reset BindingHeal" + Event Player.abilities[10] = 0; + "Reset Resilience" + Event Player.abilities[11] = 0; + "Reset HeroTalent2" + Event Player.abilities[12] = 0; + "Reset Damage" + Event Player.abilities[13] = 0; + "Reset Health" + Event Player.abilities[14] = 0; + "Reset Healing" + Event Player.abilities[15] = 0; + "Reset automaticRepair" + Global.automaticRepair -= Event Player.abilities[16]; + Event Player.abilities[16] = 0; + Call Subroutine(UpdatePlayerStats); + } +} + +rule("Brig Shield Bash Stun") +{ + event + { + Player Dealt Knockback; + Team 1; + Brigitte; + } + + actions + { + Set Status(Victim, Null, Stunned, 1); + } +} + +rule("Lucio Dash HUD Creation") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + } + + actions + { + If(Event Player.lucioDashActive == False); + Event Player.lucioDashActive = True; + Create HUD Text(Event Player, Null, Custom String("{0} Slam on ground - Press: {1}", Ability Icon String(Hero(Wrecking Ball), + Button(Crouch)), Input Binding String(Button(Crouch))), Null, Left, 1000, Color(White), Color(Green), Color(White), + Visible To and String, Default Visibility); + Event Player.lucioDashIcon = Last Text ID; + End; + } +} + +rule("Lucio Dash Remove HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) != Hero(Lúcio); + Event Player.lucioDashActive == True; + } + + actions + { + Destroy HUD Text(Event Player.lucioDashIcon); + Event Player.lucioDashActive = False; + } +} + +rule("Lucio Dash") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + Event Player.lucioDashActive == True; + Is On Ground(Event Player) == False; + Is Button Held(Event Player, Button(Crouch)) == True; + } + + actions + { + Apply Impulse(Event Player, Down, 20, To World, Cancel Contrary Motion); + } +} + +rule("Ana Self-Nano") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + Ultimate Charge Percent(Event Player) == 100; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Abort If(Global.selfNanoWorkshopSetting == False && Number Of Players(Team 1) > 1); + Wait(0.100, Ignore Condition); + If(Is Using Ultimate(Event Player) == False); + Create Dummy Bot(Hero(Ana), Team Of(Event Player), -1, Position Of(Event Player) + Backward, Eye Position(Event Player)); + Event Player.anaEntityID = Last Created Entity; + Wait(0.100, Ignore Condition); + Set Ultimate Charge(Event Player.anaEntityID, 100); + Start Facing(Event Player.anaEntityID, Direction Towards(Eye Position(Event Player.anaEntityID), Position Of(Event Player) + Up), + 1000, To World, Direction and Turn Rate); + Set Invisible(Event Player.anaEntityID, All); + Set Status(Event Player.anaEntityID, Null, Phased Out, 9999); + Wait(0.150, Ignore Condition); + Press Button(Event Player.anaEntityID, Button(Ultimate)); + Set Ultimate Charge(Event Player, 0); + Wait(0.150, Ignore Condition); + Teleport(Event Player.anaEntityID, Position Of(First Of(Spawn Points(Team Of(Event Player))))); + Wait(10, Ignore Condition); + Destroy Dummy Bot(Team Of(Event Player), Slot Of(Event Player.anaEntityID)); + End; + } +} + +disabled rule("Map Editor Walls") +{ + event + { + Ongoing - Global; + } +} + +rule("Initial Global") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.allPositions = Empty Array; + Global.allDirections = Empty Array; + Global.firstPosition = Empty Array; + Global.secondPosition = Empty Array; + Global.firstPoint = Empty Array; + Global.secondPoint = Empty Array; + Global.second = Empty Array; + Global.z = Empty Array; + Global.wallId = Empty Array; + Global.beamType = Empty Array; + } +} + +rule("Initial Player") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.filterPosition = 0; + Event Player.lastSavedPosition = 0; + Event Player.closestBodyPosition = 0; + Event Player.fullBodyPosition = 0; + Event Player.previousPositionIntersection = 0; + Event Player.activeWall = Empty Array; + Event Player.closestWall = Empty Array; + } +} + +rule("Collision Logic") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Event Player.lastSavedPosition = (Eye Position(Event Player) + Position Of(Event Player)) / 2; + Wait(0.100, Ignore Condition); + Event Player.closestWall = Filtered Array(Global.allPositions, Distance Between(Global.allPositions[Current Array Index], + Event Player) <= Distance Between(Global.allPositions[Current Array Index], Global.firstPosition[Current Array Index]) + || Event Player.activeWall[Current Array Index] == 1 || (Dot Product(Direction Towards(Current Array Element, + Event Player.lastSavedPosition), Global.allDirections[Current Array Index]) > 0) != (Dot Product(Direction Towards( + Current Array Element, Event Player), Global.allDirections[Current Array Index]) > 0)); + For Player Variable(Event Player, x, 0, Count Of(Event Player.closestWall), 1); + Global.z = Index Of Array Value(Global.allPositions, Event Player.closestWall[Event Player.x]); + If(Global.wallId[Global.z] == 1 || Global.wallId[Global.z] == 3 || Global.wallId[Global.z] == 5); + If(Y Component Of(Global.firstPosition[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.firstPosition[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestBodyPosition = Global.firstPosition[Global.z]; + Else If(Y Component Of(Global.secondPosition[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.secondPosition[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestBodyPosition = Global.secondPosition[Global.z]; + Else; + Event Player.closestBodyPosition = Position Of(Event Player); + End; + Event Player.fullBodyPosition = Vector(X Component Of(Eye Position(Event Player)), Y Component Of( + Event Player.closestBodyPosition), Z Component Of(Eye Position(Event Player))); + Event Player.filterPosition = Event Player.fullBodyPosition + Global.allDirections[Global.z] * Dot Product( + Global.allPositions[Global.z] - Event Player.fullBodyPosition, Global.allDirections[Global.z]) / Dot Product( + Global.allDirections[Global.z], Global.allDirections[Global.z]); + If(Global.wallId[Global.z] == 1 || Global.wallId[Global.z] == 3); + If((Dot Product(Direction Towards(Global.allPositions[Global.z], Event Player.lastSavedPosition), Global.allDirections[Global.z]) + > 0) != (Dot Product(Direction Towards(Global.allPositions[Global.z], Event Player.fullBodyPosition), + Global.allDirections[Global.z]) > 0)); + Event Player.intersectionLength = Dot Product(Global.allPositions[Global.z] - Event Player.fullBodyPosition, + Global.allDirections[Global.z]) / Dot Product(Direction Towards(Event Player.lastSavedPosition, Event Player.fullBodyPosition), + Global.allDirections[Global.z]); + Event Player.previousPositionIntersection = Event Player.fullBodyPosition + Direction Towards(Event Player.lastSavedPosition, + Event Player.fullBodyPosition) * Vector(1, Empty Array, 1) * Event Player.intersectionLength; + If(Dot Product(Direction Towards(Global.firstPosition[Global.z], Vector(X Component Of(Global.secondPosition[Global.z]), + Y Component Of(Global.firstPosition[Global.z]), Z Component Of(Global.secondPosition[Global.z]))), Direction Towards( + Global.firstPosition[Global.z], Event Player.previousPositionIntersection)) >= 0 && Dot Product(Direction Towards( + Global.firstPosition[Global.z], Vector(X Component Of(Global.firstPosition[Global.z]), Y Component Of( + Global.secondPosition[Global.z]), Z Component Of(Global.firstPosition[Global.z]))), Direction Towards( + Global.firstPosition[Global.z], Event Player.previousPositionIntersection)) >= 0 && Dot Product(Direction Towards( + Global.secondPosition[Global.z], Vector(X Component Of(Global.secondPosition[Global.z]), Y Component Of( + Global.firstPosition[Global.z]), Z Component Of(Global.secondPosition[Global.z]))), Direction Towards( + Global.secondPosition[Global.z], Event Player.previousPositionIntersection)) >= 0 && Dot Product(Direction Towards( + Global.secondPosition[Global.z], Vector(X Component Of(Global.firstPosition[Global.z]), Y Component Of( + Global.secondPosition[Global.z]), Z Component Of(Global.firstPosition[Global.z]))), Direction Towards( + Global.secondPosition[Global.z], Event Player.previousPositionIntersection)) >= 0); + Cancel Primary Action(Event Player); + Teleport(Event Player, Event Player.previousPositionIntersection + Direction Towards(Event Player.previousPositionIntersection, + Event Player.lastSavedPosition) * Vector(1, Empty Array, 1) * 2); + End; + End; + End; + Event Player.thickness = 0; + If(Global.wallId[Global.z] == 5); + Event Player.thickness = 4; + Else; + Event Player.thickness = 1; + End; + If(Distance Between(Event Player.fullBodyPosition, Event Player.filterPosition) <= Event Player.thickness && Dot Product( + Direction Towards(Global.firstPosition[Global.z], Vector(X Component Of(Global.secondPosition[Global.z]), Y Component Of( + Global.firstPosition[Global.z]), Z Component Of(Global.secondPosition[Global.z]))), Direction Towards( + Global.firstPosition[Global.z], Event Player.filterPosition)) >= 0 && Dot Product(Direction Towards( + Global.firstPosition[Global.z], Vector(X Component Of(Global.firstPosition[Global.z]), Y Component Of( + Global.secondPosition[Global.z]), Z Component Of(Global.firstPosition[Global.z]))), Direction Towards( + Global.firstPosition[Global.z], Event Player.filterPosition)) >= 0 && Dot Product(Direction Towards( + Global.secondPosition[Global.z], Vector(X Component Of(Global.secondPosition[Global.z]), Y Component Of( + Global.firstPosition[Global.z]), Z Component Of(Global.secondPosition[Global.z]))), Direction Towards( + Global.secondPosition[Global.z], Event Player.filterPosition)) >= 0 && Dot Product(Direction Towards( + Global.secondPosition[Global.z], Vector(X Component Of(Global.firstPosition[Global.z]), Y Component Of( + Global.secondPosition[Global.z]), Z Component Of(Global.firstPosition[Global.z]))), Direction Towards( + Global.secondPosition[Global.z], Event Player.filterPosition)) >= 0); + If(!Global.isGrounded); + Set Gravity(Event Player, 100); + End; + If(Event Player.activeWall[Global.z] == False); + Event Player.activeWall[Global.z] = 1; + If((Global.wallId[Global.z] == 1 || Global.wallId[Global.z] == 3) && Global.isGrounded == False); + Set Gravity(Event Player, 100); + Else If(Global.wallId[Global.z] == 5); + Disable Movement Collision With Environment(Event Player, False); + End; + End; + If(Global.wallId[Global.z] == 1); + Apply Impulse(Event Player, Direction Towards(Event Player.filterPosition, Event Player.fullBodyPosition) * Vector(1, Empty Array, + 1), 0.001, To World, Cancel Contrary Motion); + Set Move Speed(Event Player, 100 - Dot Product(Direction Towards(Eye Position(Event Player), Eye Position(Event Player) + + World Vector Of(Throttle Of(Event Player), Event Player, Rotation)), Direction Towards(Event Player.filterPosition, + Event Player.fullBodyPosition) * -1) * 100); + Else If(Global.wallId[Global.z] == 3); + Apply Impulse(Event Player, Direction Towards(Event Player.filterPosition, Event Player.fullBodyPosition), Speed Of(Event Player), + To World, Cancel Contrary Motion); + End; + Else; + Event Player.activeWall[Global.z] = 0; + Set Move Speed(Event Player, 100); + End; + End; + End; + Loop; + } +} + +rule("Reset") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Count Of(Filtered Array(Event Player.activeWall, Current Array Element != 0)) == 0; + } + + actions + { + Enable Movement Collision With Environment(Event Player); + } +} + +rule("Wall Data") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.allPositions = Array(Vector(155.968, 12.470, -30.507), Vector(155.962, 12.472, -62.500), Vector(81.153, 6.453, -103.851), + Vector(69.148, 6.474, -104.548)); + Global.allDirections = Array(Vector(-1, 0, -0.002), Vector(1, 0, -0.001), Vector(0, 0, 1), Vector(0.001, 0, 1)); + Global.firstPosition = Array(Vector(155.971, 11.047, -31.771), Vector(155.964, 11.050, -61.229), Vector(79.761, 5.030, -103.852), + Vector(67.738, 5.022, -104.547)); + Global.secondPosition = Array(Vector(155.965, 13.894, -29.242), Vector(155.960, 13.894, -63.771), Vector(82.544, 7.876, -103.851), + Vector(70.558, 7.925, -104.550)); + Global.firstPoint = Array(Vector(155.971, 13.894, -31.771), Vector(155.964, 13.894, -61.229), Vector(79.761, 7.876, -103.852), + Vector(67.738, 7.925, -104.547)); + Global.secondPoint = Array(Vector(155.965, 11.047, -29.242), Vector(155.960, 11.050, -63.771), Vector(82.544, 5.030, -103.851), + Vector(70.558, 5.022, -104.550)); + Global.z = 3; + Global.beamType = Array(1, 1, 1, 1); + Global.showWalls = True; + Global.wallId = Array(5, 5, 5, 5); + } +} + +disabled rule("NEW SHOP") +{ + event + { + Ongoing - Global; + } +} + +rule("Setting Shop Position") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.shopCamPosition = 900 * Up; + Global.shopPositionAngle[1] = Direction From Angles(Horizontal Angle From Direction(Forward), Vertical Angle From Direction( + Forward) - 90); + Global.shopPositionAngle[0] = Cross Product(Global.shopPositionAngle[1], Forward); + Global.shopBasePosition = Global.shopCamPosition - 9 * Global.shopPositionAngle[1] + 142 * Forward; + } +} + +rule("Create Shop Buttons") +{ + event + { + Ongoing - Global; + } + + actions + { + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), + Global.shopBasePosition - 41 * Global.shopPositionAngle[1] + 90 * Global.shopPositionAngle[0], 2.500, Do Not Clip, Visible To, + Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), + Global.shopBasePosition - 41 * Global.shopPositionAngle[1] - 90 * Global.shopPositionAngle[0], 2.500, Do Not Clip, Visible To, + Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), Custom String("Refund"), + Global.shopBasePosition + 45 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 3, Do Not Clip, Visible To, + Color(Green), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), Custom String("[{0}] Leave", + Input Binding String(Button(Reload))), + Global.shopBasePosition + 45 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 3, Do Not Clip, + Visible To and String, Color(Green), Default Visibility); + Create In-World Text(Local Player.isInMenu[0] ? Local Player : Empty Array, Custom String("{0}$\n", Local Player.money[0]), + Global.shopBasePosition + 36.500 * Global.shopPositionAngle[1], 3, Do Not Clip, Visible To and String, Color(White), + Default Visibility); + Create In-World Text(Local Player.isInMenu[0] ? Local Player : Empty Array, Custom String("▲"), Update Every Frame( + Global.shopBasePosition - (4 + Vertical Facing Angle Of(Local Player)) + * Global.shopPositionAngle[1] + Horizontal Facing Angle Of(Local Player) * Global.shopPositionAngle[0]), 4, Do Not Clip, + Visible To Position and Color, Custom Color(245 + 10 * Sine From Radians(4 * Total Time Elapsed), 205 + 50 * Sine From Radians( + 4 * Total Time Elapsed), 200 * Sine From Radians(4 * Total Time Elapsed), 255), Default Visibility); + "Headhunter" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), + Local Player.abilities[1] ? Custom String("Headhunter II\n  800$") : Custom String("Headhunter I\n  800$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[1] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Ambush" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), + Local Player.abilities[2] ? Custom String("Ambush II\n 800$") : Custom String("Ambush I\n 800$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[2] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Quick Fix" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), + Local Player.abilities[3] ? Custom String("Quick Fix II\n  700$") : Custom String("Quick Fix I\n  700$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[3] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavyweight" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), + Local Player.abilities[4] ? Custom String("Heavyweight II\n  1000$") : Custom String("Heavyweight I\n  1000$"), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[4] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Charged" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), + Local Player.abilities[5] ? Custom String("Charged II\n  700$") : Custom String("Charged I\n  700$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[5] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Haste" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), + Local Player.abilities[6] ? Custom String("Haste II\n 700$") : Custom String("Haste I\n 700$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[6] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavy Impact" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), + Local Player.abilities[7] ? Custom String("Heavy Impact II\n  1000$") : Custom String("Heavy Impact I\n  1000$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[7] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 1" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), Custom String( + "Hero Talent 1\n  1200$"), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[8] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "Second Wind" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), + Local Player.abilities[9] ? Custom String("Second Wind II\n   900$") : Custom String("Second Wind I\n   900$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[9] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Binding Heal" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), + Local Player.abilities[10] ? Custom String("Binding Heal II\n   700$") : Custom String("Binding Heal I\n   700$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[10] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Resilience" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), + Local Player.abilities[11] ? Custom String("Resilience II\n  800$") : Custom String("Resilience I\n  800$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[11] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 2" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), Custom String( + "Hero Talent 2\n  1200$"), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[12] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "PlusDamage" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), Custom String("+5% Damage\n  400$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealth" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), Custom String( + "+5% Health\n 400$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), Custom String("+5% Healing\n  400$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To and String, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu[0]), Custom String( + "+{0} Auto-Repair\n    400$", Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Global.automaticRepair < 5 ? Color(Green) : Color(Gray), Default Visibility); + "Use Update Every Frame to avoid showing the String when the cursor is out of bounds, resulting in 0\r\n ROW 0" + Create In-World Text(Update Every Frame(Local Player.isInMenu[0] && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -33.750 ? Array(Custom String("Leave Buy Menu\n"), Custom String( + ""), Custom String(""), Custom String("Refund your money\n"))[Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) + / 45, Down)] : Custom String("")), Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, + Visible To and String, Color(White), Default Visibility); + "ROW 1" + Create In-World Text(Update Every Frame(Local Player.isInMenu[0] && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 22.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -11.250 ? Array(Custom String("Increase your damage by 5%\n"), + Local Player.abilities[9] ? Custom String( + "Second Wind II: 60% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds") + : Custom String( + "Second Wind I: 30% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds"), + Local Player.abilities[5] ? Custom String("Charged II: Ultimates cost 40% less\n") : Custom String( + "Charged I: Ultimates cost 20% less\n"), Local Player.abilities[1] ? Custom String( + "Headhunter II: Critical hits deal 60% more damage\n") : Custom String("Headhunter I: Critical hits deal 30% more damage\n")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), + Default Visibility); + "ROW 2" + Create In-World Text(Update Every Frame(Local Player.isInMenu[0] && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 36.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 11.250 ? Array(Custom String("Increase your health by 5%\n"), + Local Player.abilities[10] ? Custom String("Binding Heal II: Heal yourself for 50% the amount when healing allies\n") + : Custom String("Binding Heal I: Heal yourself for 25% the amount when healing allies\n"), + Local Player.abilities[6] ? Custom String( + " Haste II: Ability cooldown is reduced by 50%\nDoes not affect abilities with multiple charges") : Custom String( + " Haste I: Ability cooldown is reduced by 25%\nDoes not affect abilities with multiple charges"), + Local Player.abilities[2] ? Custom String("Ambush II: Deal 60% more damage when attacking enemies from behind or above\n") + : Custom String("Ambush I: Deal 30% more damage when attacking enemies from behind or above\n"))[Round To Integer(( + Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), + Default Visibility); + "ROW 3" + Create In-World Text(Update Every Frame(Local Player.isInMenu[0] && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 83.750) < 72.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 33.750 ? Array(Custom String("Increase your healing by 5%\n"), + Local Player.abilities[11] ? Custom String("Resilience II: Take 30% less damage while below 60% health\n") : Custom String( + "Resilience I: Take 30% less damage while below 30% health\n"), Local Player.abilities[7] ? Custom String( + "Heavy Impact II: Every hit has a chance to stun the enemy for 2 seconds\n") : Custom String( + "Heavy Impact I: Every hit has a chance to stun the enemy for 1 second\n"), Local Player.abilities[3] ? Custom String( + "Quick Fix II: Eliminations restore 100 HP and shortly increase speed by 40%\n") : Custom String( + "Quick Fix I: Eliminations restore 50 HP and shortly increase speed by 20%\n"))[Round To Integer((Horizontal Facing Angle Of( + Local Player) + 90) / 45, Down)] : Custom String("")), Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, + Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 4" + Create In-World Text(Update Every Frame(Local Player.isInMenu[0] && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 133) < 99.250 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 56.250 ? Array(Custom String( + "Increase your auto-repair by {0}/5s\n", Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Custom String("{0}", Local Player.heroTalentText[2][1]), Custom String("{0}", Local Player.heroTalentText[1][1]), + Local Player.abilities[4] ? Custom String( + "Heavyweight II: Your knock back attacks deal 50% more damage and knock back\n            You receive 33% less knock back") + : Custom String( + "Heavyweight I: Your knock back attacks deal 25% more damage and knock back\n            You receive 20% less knock back")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), + Default Visibility); + } +} + +rule("Toggle Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + !Is Dummy Bot(Event Player) == True; + Is Button Held(Event Player, Button(Reload)) == True; + !Is Communicating Any Emote(Event Player) == True; + } + + actions + { + If(Event Player.isInMenu[0] == False); + Wait Until(!Is Button Held(Event Player, Button(Reload)), 0.500); + If(!Is Button Held(Event Player, Button(Reload))); + Abort; + End; + End; + Event Player.isInMenu[0] = !Event Player.isInMenu[0]; + } +} + +rule("Open Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu[0] == True; + } + + actions + { + Event Player.playerFacing = Facing Direction Of(Event Player); + Start Camera(Event Player, Global.shopCamPosition, Global.shopCamPosition + Forward, 0); + Disable Hero HUD(Event Player); + Call Subroutine(DisablePlayer); + Set Aim Speed(Event Player, 200); + } +} + +rule("Close Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu[0] == False; + } + + actions + { + Stop Camera(Event Player); + Enable Hero HUD(Event Player); + Call Subroutine(EnablePlayer); + Set Aim Speed(Event Player, 100); + Set Facing(Event Player, Event Player.playerFacing, To World); + } +} + +rule("Subroutine: Disable Player") +{ + event + { + Subroutine; + DisablePlayer; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + Set Primary Fire Enabled(Event Player, False); + Set Secondary Fire Enabled(Event Player, False); + Set Ability 1 Enabled(Event Player, False); + Set Ability 2 Enabled(Event Player, False); + Set Melee Enabled(Event Player, False); + Set Jump Enabled(Event Player, False); + Set Crouch Enabled(Event Player, False); + Disallow Button(Event Player, Button(Ultimate)); + } +} + +rule("Subroutine: Enable Player") +{ + event + { + Subroutine; + EnablePlayer; + } + + actions + { + Stop Forcing Throttle(Event Player); + Set Primary Fire Enabled(Event Player, True); + Set Secondary Fire Enabled(Event Player, True); + Set Ability 1 Enabled(Event Player, True); + Set Ability 2 Enabled(Event Player, True); + Set Melee Enabled(Event Player, True); + Set Jump Enabled(Event Player, True); + Set Crouch Enabled(Event Player, True); + Allow Button(Event Player, Button(Ultimate)); + } +} + +rule("Buy Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu[0] == True; + Is Button Held(Event Player, Button(Primary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + Event Player.isInMenu[0] = !Event Player.isInMenu[0]; + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.money[1] != 0); + Call Subroutine(Refund); + Else; + Small Message(Local Player, Custom String("You don't have anything to refund!")); + End; + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Event Player.abilities[13] += 1; + Call Subroutine(UpdatePlayerStats); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[9] != 2); + If(Event Player.money[0] >= 900); + Event Player.money[0] -= 900; + Event Player.money[1] += 900; + Event Player.abilities[9] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[5] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[5] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[1] != 2); + If(Event Player.money[0] >= 800); + Event Player.money[0] -= 800; + Event Player.money[1] += 800; + Event Player.abilities[1] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Event Player.abilities[14] += 1; + Call Subroutine(UpdatePlayerStats); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[10] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[10] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[6] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[6] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[2] != 2); + If(Event Player.money[0] >= 800); + Event Player.money[0] -= 800; + Event Player.money[1] += 800; + Event Player.abilities[2] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Event Player.abilities[15] += 1; + Call Subroutine(UpdatePlayerStats); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[11] != 2); + If(Event Player.money[0] >= 800); + Event Player.money[0] -= 800; + Event Player.money[1] += 800; + Event Player.abilities[11] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[7] != 2); + If(Event Player.money[0] >= 1000); + Event Player.money[0] -= 1000; + Event Player.money[1] += 1000; + Event Player.abilities[7] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[3] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[3] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Global.automaticRepair != 5); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Global.automaticRepair += 1; + Event Player.abilities[16] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[12] != 1); + If(Event Player.money[0] >= 1200); + Event Player.money[0] -= 1200; + Event Player.money[1] += 1200; + Event Player.abilities[12] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[8] != 1); + If(Event Player.money[0] >= 1200); + Event Player.money[0] -= 1200; + Event Player.money[1] += 1200; + Event Player.abilities[8] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[4] != 2); + If(Event Player.money[0] >= 1000); + Event Player.money[0] -= 1000; + Event Player.money[1] += 1000; + Event Player.abilities[4] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + End; + } +} + +rule("Refund Single Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu[0] == True; + Is Button Held(Event Player, Button(Secondary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[13] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Event Player.abilities[13] -= 1; + Call Subroutine(UpdatePlayerStats); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[9] != 0); + Event Player.money[0] += 900; + Event Player.money[1] -= 900; + Event Player.abilities[9] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[5] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[5] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[1] != 0); + Event Player.money[0] += 800; + Event Player.money[1] -= 800; + Event Player.abilities[1] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[14] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Event Player.abilities[14] -= 1; + Call Subroutine(UpdatePlayerStats); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[10] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[10] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[6] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[6] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[2] != 0); + Event Player.money[0] += 800; + Event Player.money[1] -= 800; + Event Player.abilities[2] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[15] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Event Player.abilities[15] -= 1; + Call Subroutine(UpdatePlayerStats); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[11] != 0); + Event Player.money[0] += 800; + Event Player.money[1] -= 800; + Event Player.abilities[11] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[7] != 0); + Event Player.money[0] += 1000; + Event Player.money[1] -= 1000; + Event Player.abilities[7] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[3] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[3] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[16] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Global.automaticRepair -= 1; + Event Player.abilities[16] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[12] != 0); + Event Player.money[0] += 1200; + Event Player.money[1] -= 1200; + Event Player.abilities[12] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[8] != 0); + Event Player.money[0] += 1200; + Event Player.money[1] -= 1200; + Event Player.abilities[8] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[4] != 0); + Event Player.money[0] += 1000; + Event Player.money[1] -= 1000; + Event Player.abilities[4] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + End; + } +} + +rule("Create Player HUD") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Custom String("{0}{1}", + Event Player, Event Player.isInMenu[0] ? Custom String("(In Shop)") : Custom String("")), Custom String("{0}{1}", Is Alive( + Event Player) ? Custom String("{0} HP", Round To Integer(Health(Event Player), Up)) : Custom String("Dead"), Custom String( + ", {0}$", Event Player.money)), Left, Local Player == Event Player ? -1 : Slot Of(Event Player), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), + Visible To Sort Order String and Color, Default Visibility); + Create HUD Text(Event Player.damageBoost[0] != 0 ? Event Player : Null, Null, Custom String("+{0}% Damage", + Event Player.damageBoost[0]), Null, Left, 913, Color(Green), Color(Green), Color(Green), Visible To and String, + Default Visibility); + Create HUD Text(Event Player.abilities[9] ? Event Player : Null, Null, Custom String("Second Wind {0}", + Event Player.abilities[9] == 1 ? Custom String("I") : Custom String("II")), Null, Left, 908, Color(Green), Color(Green), Color( + Green), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[5] ? Event Player : Null, Null, Custom String("Charged {0}", + Event Player.abilities[5] == 1 ? Custom String("I") : Custom String("II")), Null, Left, 905, Color(Green), Color(Green), Color( + Green), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[1] ? Event Player : Null, Null, Custom String("Headhunter {0}", + Event Player.abilities[1] == 1 ? Custom String("I") : Custom String("II")), Null, Left, 901, Color(Green), Color(Green), Color( + Green), Visible To and String, Default Visibility); + Create HUD Text(Event Player.playerHealth != 0 ? Event Player : Null, Null, Custom String("+{0}% Health", + Event Player.playerHealth), Null, Left, 914, Color(Green), Color(Green), Color(Green), Visible To and String, + Default Visibility); + Create HUD Text(Event Player.abilities[10] ? Event Player : Null, Null, Custom String("Binding Heal {0}", + Event Player.abilities[10] == 1 ? Custom String("I") : Custom String("II")), Null, Left, 909, Color(Green), Color(Green), Color( + Green), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[6] ? Event Player : Null, Null, Custom String("Haste {0}", + Event Player.abilities[6] == 1 ? Custom String("I") : Custom String("II")), Null, Left, 906, Color(Green), Color(Green), Color( + Green), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[2] ? Event Player : Null, Null, Custom String("Ambush {0}", + Event Player.abilities[2] == 1 ? Custom String("I") : Custom String("II")), Null, Left, 902, Color(Green), Color(Green), Color( + Green), Visible To and String, Default Visibility); + Create HUD Text(Event Player.healBoost[0] != 0 ? Event Player : Null, Null, Custom String("+{0}% Healing", + Event Player.healBoost[0]), Null, Left, 915, Color(Green), Color(Green), Color(Green), Visible To and String, + Default Visibility); + Create HUD Text(Event Player.speedBoost != 0 ? Event Player : Null, Null, Custom String("+{0}% Movement Speed", + Event Player.speedBoost), Null, Left, 915, Color(Green), Color(Green), Color(Green), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[11] ? Event Player : Null, Null, Custom String("Resilience {0}", + Event Player.abilities[11] == 1 ? Custom String("I") : Custom String("II")), Null, Left, 910, Color(Green), Color(Green), Color( + Green), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[7] ? Event Player : Null, Null, Custom String("Heavy Impact {0}", + Event Player.abilities[7] == 1 ? Custom String("I") : Custom String("II")), Null, Left, 907, Color(Green), Color(Green), Color( + Green), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[3] ? Event Player : Null, Null, Custom String("Quick Fix {0}", + Event Player.abilities[3] == 1 ? Custom String("I") : Custom String("II")), Null, Left, 903, Color(Green), Color(Green), Color( + Green), Visible To and String, Default Visibility); + Create HUD Text(Global.automaticRepair ? Event Player : Null, Null, Custom String("{0} total Auto-Repair/5s", + Global.automaticRepair * (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 10 : 5)), Null, Left, 916, + Color(Green), Color(Green), Color(Green), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[12] ? Event Player : Null, Null, Custom String("{0} {1}", + Event Player.heroTalentText[2][0], Event Player.heroTalentText[2][1]), Null, Top, 902, Color(Green), Color(Green), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[12] ? Event Player : Null, Null, Custom String("Hero Talent 2"), Null, Left, 912, Color( + Green), Color(Green), Color(Green), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[8] ? Event Player : Null, Null, Custom String("{0} {1}", + Event Player.heroTalentText[1][0], Event Player.heroTalentText[1][1]), Null, Top, 901, Color(Green), Color(Green), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[8] ? Event Player : Null, Null, Custom String("Hero Talent 1"), Null, Left, 911, Color( + Green), Color(Green), Color(Green), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[4] ? Event Player : Null, Null, Custom String("Heavyweight {0}", + Event Player.abilities[4] == 1 ? Custom String("I") : Custom String("II")), Null, Left, 904, Color(Green), Color(Green), Color( + Green), Visible To and String, Default Visibility); + } +} + +rule("Boss Rotation") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.activeBoss == True; + } + + actions + { + If(Global.bossRotation == 0 || Global.bossRotation == 3); + Global.bossRotation = 1; + Global.lastBoss[1] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 1); + Global.bossRotation = 2; + Global.lastBoss[2] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 2); + Global.bossRotation = 3; + Global.lastBoss[3] = Hero Of(Global.activeBoss); + End; + } +} + +rule("BOSS HUD") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 10; + } + + actions + { + Create HUD Text(All Players(Team 1), Null, Global.activeBoss ? Custom String("Boss: {0}, HP: {1}/{2}", Hero Of(Global.activeBoss), + Health(Global.activeBoss), Max Health(Global.activeBoss)) : Custom String(""), Null, Top, 900, Color(White), Color(Red), + Color(White), Visible To and String, Default Visibility); + } +} + +rule("DEBUG - SKIP TIME") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.isDebug == True; + (Is Button Held(Event Player, Button(Primary Fire)) && Is Button Held(Event Player, Button(Crouch))) == True; + } + + actions + { + Global.timeSeconds = 59; + } +} + +rule("DEBUG - SKIP TIME") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.isDebug == True; + (Is Button Held(Event Player, Button(Secondary Fire)) && Is Button Held(Event Player, Button(Crouch))) == True; + } + + actions + { + Global.botEchoRespawnPosition = Vector(130, 23, -44); + } +} + +rule("DEBUG COLLECTION - Make Invincible, Show Player Coords") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.isDebug == True; + } + + actions + { + Create HUD Text(Local Player, Null, Custom String("{0}", Position Of(Event Player)), Null, Left, 0, Color(White), Color(Yellow), + Color(White), Visible To and String, Default Visibility); + Set Status(Event Player, Null, Invincible, 9999); + Set Status(Event Player, Null, Phased Out, 9999); + } +} + +rule("OPTIONAL ENDING - CREATE EXFIL POINT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount >= 12; + } + + actions + { + Create HUD Text(All Players(Team 1), Null, Custom String("Exfiltration available! (optional - ends the mode)"), Null, Top, 50, + Color(White), Color(Red), Color(White), Visible To and String, Default Visibility); + Global.globalHUDs[1] = Last Text ID; + Create In-World Text(All Players(Team 1), Custom String( + "Exfiltration available! Gather here!\n{0}/{1} Players ready to exfiltrate!", Count Of(Filtered Array(All Players(Team 1), + Distance Between(Vector(186, 11, -46.500), Current Array Element) <= 9)), Count Of(All Players(Team 1))), Vector(186, 15, + -46.500), 1.200, Do Not Clip, Visible To and String, Color(Green), Default Visibility); + Wait(3, Ignore Condition); + Destroy HUD Text(Global.globalHUDs[1]); + } +} + +rule("OPTIONAL ENDING - EXFIL PLAYERS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + Count Of(Filtered Array(All Players(Team 1), Distance Between(Vector(186, 11, -46.500), All Players(Team 1)) <= 9)) > Count Of( + All Players(Team 1)) / 2; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GG! YOU SUCCESSFULLY RAN AWAY, WHILE LEAVING THE GATE TO THE ENEMY!")); + Destroy All Dummy Bots; + Disable Movement Collision With Environment(All Players(Team 1), True); + Start Accelerating(All Players(Team 1), Up, 100, 5, To World, Direction Rate and Max Speed); + Wait(5, Ignore Condition); + Declare Team Victory(Team 1); + } +} + +rule("Team 1 (Ability): Second Wind save life") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + conditions + { + Event Player.abilities[9] == True; + Event Player.secondWindActive == True; + Health(Event Player) == 1; + } + + actions + { + Small Message(All Players(All Teams), Custom String("{0} received a second wind!", Event Player)); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(Green), Event Player, 1); + Clear Status(Event Player, Unkillable); + Set Player Health(Event Player, Max Health(Event Player)); + Event Player.lastSecondWind = 30; + Event Player.secondWindActive = 0; + } +} + +rule("Team 1 (Ability): Second Wind after buying") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[9] == True; + Event Player.secondWindActive == False; + Event Player.lastSecondWind == 0; + } + + actions + { + If(Random Integer(1, 100) > Event Player.abilities[9] * 30); + Wait(30, Ignore Condition); + Loop; + End; + Set Status(Event Player, Null, Unkillable, 9999); + Event Player.secondWindActive = 1; + } +} + +rule("Team 1 (Ability): Second Wind counter") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Player.lastSecondWind > 0; + } + + actions + { + Wait(1, Ignore Condition); + Event Player.lastSecondWind -= 1; + Loop If Condition Is True; + } +} + +rule("Team 1: Change Hero") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Distance Between(Vector(159, 11, -46.500), Event Player) <= 2; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + Set Player Allowed Heroes(Event Player, Hero(Pharah)); + Set Player Allowed Heroes(Event Player, Hero(Ana)); + Reset Player Hero Availability(Event Player); + Wait(0.500, Ignore Condition); + Wait Until(Has Spawned(Event Player), 99999); + Teleport(Event Player, Vector(159, 11, -46.500)); + } +} + +rule("Team 1: Player Dealt Healing") +{ + event + { + Player Dealt Healing; + Team 1; + All; + } + + actions + { + Abort If(Healee != Event Player); + If(Event Player.abilities[10] == True); + Set Player Health(Event Player, Health(Event Player) + Event Player.abilities[10] * 0.250 * Event Healing); + End; + } +} + +rule("Team 1: Player Dealt Damage") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + actions + { + If(Event Was Critical Hit == True); + If(Global.upgradeCriticalDamageValue >= Global.upgradeCriticalDamageMaxValue[0]); + Damage(Victim, Event Player, Event Damage * 0.500); + End; + If(Event Player.abilities[1] == True); + Damage(Victim, Event Player, Event Damage * Event Player.abilities[1] * 0.400); + End; + End; + If(Event Player.abilities[2] == True && Event Ability != Null && (Y Component Of(Position Of(Event Player)) - Y Component Of( + Position Of(Victim)) >= 3 || Absolute Value(Horizontal Angle Towards(Victim, Event Player)) >= 90) == True); + Damage(Victim, Event Player, Event Damage * Event Player.abilities[2] * 0.300); + End; + If(Global.perk[0] == True && Event Ability != Null && Distance Between(Event Player, Victim) >= 10); + Damage(Victim, Event Player, Event Damage * 0.500); + End; + } +} + +rule("▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒【Josbird's Cursor Menu】▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒") +{ + event + { + Ongoing - Global; + } +} + +rule("Global init") +{ + event + { + Ongoing - Global; + } + + actions + { + Create HUD Text(Is Game In Progress == False && Host Player.isInMenu[1] ? Host Player : Null, Null, Custom String( + "Cursor Menu created by Josbird {0} Code: GETVX", Ability Icon String(Hero(Mercy), Button(Ultimate))), Null, Right, -100, Color( + White), Color(Turquoise), Color(White), Visible To and String, Default Visibility); + Create HUD Text(Global.timeSeconds == 0 && Global.timeMinutes == 0 && !Host Player.isInMenu[1] ? Host Player : Null, Null, Custom String( + "{0}", Custom String("Press {0} - Crouch to open workshop settings", Input Binding String(Button(Crouch)))), Null, Top, + 1, Color(White), Color(Yellow), Color(White), Visible To and String, Default Visibility); + Create HUD Text(Is Game In Progress == False && Host Player.isInMenu[1] ? Host Player : Null, Null, Custom String("{0}", Custom String( + "Press {0} - Primary Fire to increase by X\nPress {1} - Secondary Fire to decrease by X", Input Binding String(Button( + Primary Fire)), Input Binding String(Button(Secondary Fire)))), Null, Right, 1, Color(White), Color(Yellow), Color( + White), Visible To and String, Default Visibility); + Global.extendedGlobalCollection[1] = 10; + Global.extendedGlobalCollection[2] = 5; + Global.extendedGlobalCollection[6] = True; + Global.exitButtonProperties = Array(Custom String("exit menu"), Global.extendedGlobalCollection[1] / 2 - 0.150, + Global.extendedGlobalCollection[2] / 2 - 0.150, 0.350); + } +} + +rule("Create a menu button") +{ + event + { + Subroutine; + createMenuButton; + } + + actions + { + If(Count Of(Event Player.newButton) != 13); + Log To Inspector(Custom String("[CursorMenu.createMenuButton] Error: incorrect number of arguments (got {0}, expected {1})", + Event Player.destroyButtonID, 13)); + Else; + Event Player.lastMenuButtonID = Count Of(Event Player.buttons); + Event Player.extendedPlayerCollection[2] = 0; + While(Event Player.extendedPlayerCollection[2] < Count Of(Event Player.buttons)); + If(Event Player.buttons[Event Player.extendedPlayerCollection[2]] == Null); + Event Player.lastMenuButtonID = Event Player.extendedPlayerCollection[2]; + Event Player.extendedPlayerCollection[2] = Count Of(Event Player.buttons); + End; + Event Player.extendedPlayerCollection[2] += 1; + End; + Event Player.buttons[Event Player.lastMenuButtonID] = Event Player.newButton; + End; + } +} + +rule("Destroy a menu button") +{ + event + { + Subroutine; + destroyMenuButton; + } + + actions + { + If(Event Player.destroyButtonID >= Count Of(Event Player.buttons) || !Event Player.buttons[Event Player.destroyButtonID]); + Log To Inspector(Custom String("[CursorMenu.destroyMenuButton] Error: tried to destroy an invalid button ID ({0})", + Event Player.destroyButtonID)); + Else; + Global.arrayBuilder = Event Player.buttons[Event Player.destroyButtonID]; + Global.arrayBuilder[15] = True; + Event Player.buttons[Event Player.destroyButtonID] = Global.arrayBuilder; + End; + } +} + +rule("Modify a menu button") +{ + event + { + Subroutine; + modifyMenuButton; + } + + actions + { + If(Count Of(Event Player.buttonModification) % 2 == 0 || Count Of(Event Player.buttonModification) < 3); + Log To Inspector(Custom String("[CursorMenu.modifyMenuButton] Error: incorrect number of arguments ({0})", Count Of(First Of( + Event Player.buttonModification)))); + Else If(First Of(Event Player.buttonModification) >= Count Of(Event Player.buttons) || !Event Player.buttons[First Of( + Event Player.buttonModification)]); + Log To Inspector(Custom String("[CursorMenu.modifyMenuButton] Error: tried to modify an invalid button ID ({0})", First Of( + Event Player.buttonModification))); + Else; + Event Player.extendedPlayerCollection[2] = 1; + While(Event Player.extendedPlayerCollection[2] < Count Of(Event Player.buttonModification)); + If( + Event Player.buttonModification[Event Player.extendedPlayerCollection[2]] < 0 || Event Player.buttonModification[Event Player.extendedPlayerCollection[2]] >= 13); + Log To Inspector(Custom String("[CursorMenu.modifyMenuButton] Error: tried to modify an invalid property index ({0})", Count Of( + Event Player.buttonModification[Event Player.extendedPlayerCollection[2]]))); + Else; + Global.arrayBuilder = Event Player.buttons[First Of(Event Player.buttonModification)]; + Global.arrayBuilder[Event Player.buttonModification[Event Player.extendedPlayerCollection[2]]] = Event Player.buttonModification[Event Player.extendedPlayerCollection[2] + 1]; + Event Player.buttons[First Of(Event Player.buttonModification)] = Global.arrayBuilder; + End; + Event Player.extendedPlayerCollection[2] += 2; + End; + End; + } +} + +rule("Get properties of a menu button") +{ + event + { + Subroutine; + getButtonProperties; + } + + actions + { + If(Event Player.getProperties >= Count Of(Event Player.buttons) || !Event Player.buttons[Event Player.getProperties]); + Log To Inspector(Custom String("[CursorMenu.getButtonProperties] Error: tried to access an invalid button ID ({0})", + Event Player.getProperties)); + Else; + Event Player.getProperties = Array Slice(Event Player.buttons[Event Player.getProperties], 0, 13); + End; + } +} + +rule("Toggle menu") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == False; + Event Player == Host Player; + !Is Dummy Bot(Event Player) == True; + Is Button Held(Event Player, Button(Crouch)) == True; + !Is Communicating Any Emote(Event Player) == True; + } + + actions + { + Event Player.isInMenu[1] = !Event Player.isInMenu[1]; + } +} + +rule("Create menu cursor") +{ + event + { + Subroutine; + createCursor; + } + + actions + { + Create In-World Text(Filtered Array(Event Player, Total Time Elapsed % 0.032 < 0.016), Custom String("▲"), Update Every Frame( + Eye Position(Event Player) + 100 * (Angle Difference(Horizontal Angle From Direction(Facing Direction Of(Event Player)), + Horizontal Angle From Direction(Event Player.menuOriginalFacing)) * Cross Product(Facing Direction Of(Event Player), + Direction From Angles(Horizontal Angle From Direction(Facing Direction Of(Event Player)), Vertical Angle From Direction( + Facing Direction Of(Event Player)) - 90)) + (Angle Difference(Vertical Angle From Direction(Facing Direction Of(Event Player)), + Vertical Angle From Direction(Event Player.menuOriginalFacing)) - 0.200) * Direction From Angles( + Horizontal Angle From Direction(Facing Direction Of(Event Player)), Vertical Angle From Direction(Facing Direction Of( + Event Player)) - 90) + 3 * Facing Direction Of(Event Player))), 3, Do Not Clip, Visible To Position String and Color, Color( + White), Default Visibility); + Modify Player Variable(Event Player, menuFrame, Append To Array, Last Text ID); + Create In-World Text(Filtered Array(Event Player, Total Time Elapsed % 0.032 >= 0.016), Custom String("▲"), Update Every Frame( + Eye Position(Event Player) + 100 * (Angle Difference(Horizontal Angle From Direction(Facing Direction Of(Event Player)), + Horizontal Angle From Direction(Event Player.menuOriginalFacing)) * Cross Product(Facing Direction Of(Event Player), + Direction From Angles(Horizontal Angle From Direction(Facing Direction Of(Event Player)), Vertical Angle From Direction( + Facing Direction Of(Event Player)) - 90)) + (Angle Difference(Vertical Angle From Direction(Facing Direction Of(Event Player)), + Vertical Angle From Direction(Event Player.menuOriginalFacing)) - 0.200) * Direction From Angles( + Horizontal Angle From Direction(Facing Direction Of(Event Player)), Vertical Angle From Direction(Facing Direction Of( + Event Player)) - 90) + 3 * Facing Direction Of(Event Player))), 3, Do Not Clip, Visible To Position String and Color, Color( + White), Default Visibility); + Modify Player Variable(Event Player, menuFrame, Append To Array, Last Text ID); + } +} + +rule("Do button update") +{ + event + { + Subroutine; + doButtonUpdate; + } + + actions + { + Event Player.extendedPlayerCollection[2] = 0; + While(Event Player.extendedPlayerCollection[2] < Count Of(Event Player.buttons)); + If(Event Player.buttons[Event Player.extendedPlayerCollection[2]]); + If(Event Player.buttons[Event Player.extendedPlayerCollection[2]][15]); + If(Event Player.buttons[Event Player.extendedPlayerCollection[2]][14]); + Destroy In-World Text(Event Player.buttons[Event Player.extendedPlayerCollection[2]][13]); + End; + Event Player.buttons[Event Player.extendedPlayerCollection[2]] = Null; + Else If(( + !Event Player.buttons[Event Player.extendedPlayerCollection[2]][12] && Event Player.buttons[Event Player.extendedPlayerCollection[2]][14]) + || !Event Player.isInMenu[1]); + Destroy In-World Text(Event Player.buttons[Event Player.extendedPlayerCollection[2]][13]); + Global.arrayBuilder = Event Player.buttons[Event Player.extendedPlayerCollection[2]]; + Global.arrayBuilder[14] = False; + Event Player.buttons[Event Player.extendedPlayerCollection[2]] = Global.arrayBuilder; + Else If( + Event Player.buttons[Event Player.extendedPlayerCollection[2]][12] && !Event Player.buttons[Event Player.extendedPlayerCollection[2]][14]); + Create In-World Text(Event Player, Event Player.buttons[Evaluate Once(Event Player.extendedPlayerCollection[2]) + ][10] ? Custom String("{0}", First Of(Event Player.buttons[Evaluate Once(Event Player.extendedPlayerCollection[2])])) + : First Of(Event Player.buttons[Evaluate Once(Event Player.extendedPlayerCollection[2])]), Update Every Frame(Eye Position( + Event Player) + 100 * (Event Player.buttons[Evaluate Once(Event Player.extendedPlayerCollection[2])][4] * Cross Product( + Facing Direction Of(Event Player), Direction From Angles(Horizontal Angle From Direction(Facing Direction Of(Event Player)), + Vertical Angle From Direction(Facing Direction Of(Event Player)) - 90)) + (Event Player.buttons[Evaluate Once( + Event Player.extendedPlayerCollection[2])][5] - 0.200) * Direction From Angles(Horizontal Angle From Direction( + Facing Direction Of(Event Player)), Vertical Angle From Direction(Facing Direction Of(Event Player)) - 90) + + 3 * Facing Direction Of(Event Player))), Event Player.buttons[Evaluate Once(Event Player.extendedPlayerCollection[2])][3], + Do Not Clip, Visible To Position String and Color, Event Player.buttons[Evaluate Once(Event Player.extendedPlayerCollection[2]) + ][11] && Absolute Value(Angle Difference(Horizontal Angle From Direction(Facing Direction Of(Event Player)), + Horizontal Angle From Direction(Event Player.menuOriginalFacing)) - Event Player.buttons[Evaluate Once( + Event Player.extendedPlayerCollection[2])][4]) <= Event Player.buttons[Evaluate Once(Event Player.extendedPlayerCollection[2]) + ][6] / 2 && Absolute Value(Angle Difference(Vertical Angle From Direction(Facing Direction Of(Event Player)), + Vertical Angle From Direction(Event Player.menuOriginalFacing)) - Event Player.buttons[Evaluate Once( + Event Player.extendedPlayerCollection[2])][5]) <= Event Player.buttons[Evaluate Once(Event Player.extendedPlayerCollection[2]) + ][7] / 2 ? Event Player.buttons[Evaluate Once(Event Player.extendedPlayerCollection[2]) + ][9] : Event Player.buttons[Evaluate Once(Event Player.extendedPlayerCollection[2])][8], Default Visibility); + Global.arrayBuilder = Event Player.buttons[Evaluate Once(Event Player.extendedPlayerCollection[2])]; + Global.arrayBuilder[13] = Last Text ID; + Event Player.buttons[Evaluate Once(Event Player.extendedPlayerCollection[2])] = Global.arrayBuilder; + Global.arrayBuilder = Event Player.buttons[Evaluate Once(Event Player.extendedPlayerCollection[2])]; + Global.arrayBuilder[14] = True; + Event Player.buttons[Evaluate Once(Event Player.extendedPlayerCollection[2])] = Global.arrayBuilder; + End; + End; + Event Player.extendedPlayerCollection[2] += 1; + End; + } +} + +rule("Close menu on start") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Player.isInMenu[1] == True; + } + + actions + { + Event Player.isInMenu[1] = False; + Set Aim Speed(Event Player, 100); + Set Primary Fire Enabled(Event Player, True); + Set Secondary Fire Enabled(Event Player, True); + Enable Hero HUD(Event Player); + Event Player.extendedPlayerCollection[2] = 0; + While(Event Player.extendedPlayerCollection[2] < Count Of(Event Player.menuFrame)); + Destroy In-World Text(Event Player.menuFrame[Event Player.extendedPlayerCollection[2]]); + Event Player.extendedPlayerCollection[2] += 1; + End; + Destroy Icon(First Of(Event Player.extendedPlayerCollection)); + Call Subroutine(doButtonUpdate); + Call Subroutine(EnablePlayer); + } +} + +rule("Open menu") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == False; + !Is Dummy Bot(Event Player) == True; + Event Player.isInMenu[1] == True; + } + + actions + { + Set Aim Speed(Event Player, 15); + Event Player.menuOriginalFacing = Facing Direction Of(Event Player); + Set Primary Fire Enabled(Event Player, False); + Set Secondary Fire Enabled(Event Player, False); + Disable Hero HUD(Event Player); + Disable Game Mode HUD(Event Player); + Event Player.menuFrame = Empty Array; + Call Subroutine(createCursor); + Wait(0.016, Ignore Condition); + Wait(0.016, Ignore Condition); + Wait(0.016, Ignore Condition); + Call Subroutine(doButtonUpdate); + Call Subroutine(DisablePlayer); + } +} + +rule("Close menu") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == False; + !Is Dummy Bot(Event Player) == True; + !Event Player.isInMenu[1] == True; + } + + actions + { + Set Aim Speed(Event Player, 100); + Set Primary Fire Enabled(Event Player, True); + Set Secondary Fire Enabled(Event Player, True); + Enable Hero HUD(Event Player); + Enable Game Mode HUD(Event Player); + Event Player.extendedPlayerCollection[2] = 0; + While(Event Player.extendedPlayerCollection[2] < Count Of(Event Player.menuFrame)); + Destroy In-World Text(Event Player.menuFrame[Event Player.extendedPlayerCollection[2]]); + Event Player.extendedPlayerCollection[2] += 1; + End; + Destroy Icon(First Of(Event Player.extendedPlayerCollection)); + Call Subroutine(doButtonUpdate); + Call Subroutine(EnablePlayer); + } +} + +rule("Check for button update") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == False; + Event Player.isInMenu[1] == True; + Is True For Any(Event Player.buttons, Current Array Element && (Current Array Element[15] || ( + !Current Array Element[12] && Current Array Element[14]) || (Current Array Element[12] && !Current Array Element[14]))) + == True; + } + + actions + { + Call Subroutine(doButtonUpdate); + Wait(0.016, Ignore Condition); + } +} + +rule("Detect primary fire button press") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == False; + Event Player.isInMenu[1] == True; + Is Button Held(Event Player, Button(Primary Fire)) == True; + } + + actions + { + If(Absolute Value(Angle Difference(Horizontal Angle From Direction(Facing Direction Of(Event Player)), + Horizontal Angle From Direction(Event Player.menuOriginalFacing)) - Global.exitButtonProperties[1]) + <= Global.exitButtonProperties[3] / 2 && Absolute Value(Angle Difference(Vertical Angle From Direction(Facing Direction Of( + Event Player)), Vertical Angle From Direction(Event Player.menuOriginalFacing)) - Global.exitButtonProperties[2]) + <= Global.exitButtonProperties[3] / 2); + Event Player.currActionID = First Of(Global.exitButtonProperties); + End; + Event Player.extendedPlayerCollection[3] = 0; + While(Event Player.extendedPlayerCollection[3] < Count Of(Event Player.buttons)); + If(Event Player.buttons[Event Player.extendedPlayerCollection[3]][11] && Absolute Value(Angle Difference( + Horizontal Angle From Direction(Facing Direction Of(Event Player)), Horizontal Angle From Direction( + Event Player.menuOriginalFacing)) - Event Player.buttons[Event Player.extendedPlayerCollection[3]][4]) + <= Event Player.buttons[Event Player.extendedPlayerCollection[3]][6] / 2 && Absolute Value(Angle Difference( + Vertical Angle From Direction(Facing Direction Of(Event Player)), Vertical Angle From Direction( + Event Player.menuOriginalFacing)) - Event Player.buttons[Event Player.extendedPlayerCollection[3]][5]) + <= Event Player.buttons[Event Player.extendedPlayerCollection[3]][7] / 2); + Event Player.currActionID = Event Player.buttons[Event Player.extendedPlayerCollection[3]][1]; + End; + Event Player.extendedPlayerCollection[3] += 1; + End; + If(Event Player.currActionID && Global.extendedGlobalCollection[6]); + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 30); + End; + Wait(0.016, Ignore Condition); + Event Player.currActionID = Null; + } +} + +rule("Detect secondary fire button press") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == False; + Event Player.isInMenu[1] == True; + Is Button Held(Event Player, Button(Secondary Fire)) == True; + } + + actions + { + If(Absolute Value(Angle Difference(Horizontal Angle From Direction(Facing Direction Of(Event Player)), + Horizontal Angle From Direction(Event Player.menuOriginalFacing)) - Global.exitButtonProperties[1]) + <= Global.exitButtonProperties[3] / 2 && Absolute Value(Angle Difference(Vertical Angle From Direction(Facing Direction Of( + Event Player)), Vertical Angle From Direction(Event Player.menuOriginalFacing)) - Global.exitButtonProperties[2]) + <= Global.exitButtonProperties[3] / 2); + Event Player.currActionID = First Of(Global.exitButtonProperties); + End; + Event Player.extendedPlayerCollection[4] = 0; + While(Event Player.extendedPlayerCollection[4] < Count Of(Event Player.buttons)); + If(Event Player.buttons[Event Player.extendedPlayerCollection[4]][11] && Absolute Value(Angle Difference( + Horizontal Angle From Direction(Facing Direction Of(Event Player)), Horizontal Angle From Direction( + Event Player.menuOriginalFacing)) - Event Player.buttons[Event Player.extendedPlayerCollection[4]][4]) + <= Event Player.buttons[Event Player.extendedPlayerCollection[4]][6] / 2 && Absolute Value(Angle Difference( + Vertical Angle From Direction(Facing Direction Of(Event Player)), Vertical Angle From Direction( + Event Player.menuOriginalFacing)) - Event Player.buttons[Event Player.extendedPlayerCollection[4]][5]) + <= Event Player.buttons[Event Player.extendedPlayerCollection[4]][7] / 2); + Event Player.currActionID = Event Player.buttons[Event Player.extendedPlayerCollection[4]][2]; + End; + Event Player.extendedPlayerCollection[4] += 1; + End; + If(Event Player.currActionID && Global.extendedGlobalCollection[6]); + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 30); + End; + Wait(0.016, Ignore Condition); + Event Player.currActionID = Null; + } +} + +rule("Cursor bounds") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == False; + Event Player.isInMenu[1] == True; + (Absolute Value(Angle Difference(Horizontal Angle From Direction(Facing Direction Of(Event Player)), + Horizontal Angle From Direction(Event Player.menuOriginalFacing))) + > Global.extendedGlobalCollection[1] / 2 + 0.050 || Absolute Value(Angle Difference(Vertical Angle From Direction( + Facing Direction Of(Event Player)), Vertical Angle From Direction(Event Player.menuOriginalFacing))) + > Global.extendedGlobalCollection[2] / 2 + 0.050) == True; + } + + actions + { + Set Facing(Event Player, Direction From Angles(Min(Max(Horizontal Angle From Direction(Event Player.menuOriginalFacing) + - Angle Difference(Horizontal Angle From Direction(Facing Direction Of(Event Player)), Horizontal Angle From Direction( + Event Player.menuOriginalFacing)), Horizontal Angle From Direction(Event Player.menuOriginalFacing) + - Global.extendedGlobalCollection[1] / 2), Horizontal Angle From Direction(Event Player.menuOriginalFacing) + + Global.extendedGlobalCollection[1] / 2), Min(Max(Vertical Angle From Direction(Event Player.menuOriginalFacing) + - Angle Difference(Vertical Angle From Direction(Facing Direction Of(Event Player)), Vertical Angle From Direction( + Event Player.menuOriginalFacing)), Vertical Angle From Direction(Event Player.menuOriginalFacing) + - Global.extendedGlobalCollection[2] / 2), Vertical Angle From Direction(Event Player.menuOriginalFacing) + + Global.extendedGlobalCollection[2] / 2)), To World); + Wait(0.016, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒a") +{ + event + { + Ongoing - Global; + } +} + +rule("workshop rules") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == False; + Event Player == Host Player; + } + + actions + { + Global.gateMaxHealth[1] = 100; + Global.gateMaxHealth[2] = 1000; + Global.moneyMultiplier[1] = 0.500; + Global.moneyMultiplier[2] = 2; + Host Player.newButton = Array(Custom String("GATE MAX HEALTH: {0}", Global.gateMaxHealth[0]), Null, Null, 3, -1, 0.500, 0, 0.300, + Color(Green), Color(Green), True, True, True); + Call Subroutine(createMenuButton); + Host Player.workshopButtons[0] = Host Player.lastMenuButtonID; + Host Player.newButton = Array(Custom String("+/- 1"), Custom String("gateMaxHealthAddOne"), Custom String( + "gateMaxHealthSubtractOne"), 3, 0.650, 0.500, 0.500, 0.300, Color(Green), Color(Yellow), True, True, True); + Call Subroutine(createMenuButton); + Host Player.workshopButtons[1] = Host Player.lastMenuButtonID; + Host Player.newButton = Array(Custom String("+/- 10"), Custom String("gateMaxHealthAddTen"), Custom String( + "gateMaxHealthSubtractTen"), 3, 1.150, 0.500, 0.500, 0.300, Color(Green), Color(Yellow), True, True, True); + Call Subroutine(createMenuButton); + Host Player.workshopButtons[2] = Host Player.lastMenuButtonID; + Host Player.newButton = Array(Custom String("+/- 100"), Custom String("gateMaxHealthAddHundred"), Custom String( + "gateMaxHealthSubtractHundred"), 3, 1.700, 0.500, 0.500, 0.300, Color(Green), Color(Yellow), True, True, True); + Call Subroutine(createMenuButton); + Host Player.workshopButtons[3] = Host Player.lastMenuButtonID; + Host Player.newButton = Array(Custom String("Money Multiplier: {0}", Global.moneyMultiplier[0]), Null, Null, 3, -1, 0, 0, 0.300, + Color(Green), Color(Green), True, True, True); + Call Subroutine(createMenuButton); + Host Player.workshopButtons[4] = Host Player.lastMenuButtonID; + Host Player.newButton = Array(Custom String("+/- 0.01"), Custom String("moneyMultAddTen"), Custom String("moneyMultSubtractTen"), + 3, 0.750, 0, 0.500, 0.300, Color(Green), Color(Yellow), True, True, True); + Call Subroutine(createMenuButton); + Host Player.workshopButtons[5] = Host Player.lastMenuButtonID; + Host Player.newButton = Array(Custom String("+/- 0.10"), Custom String("moneyMultAddHundred"), Custom String( + "moneyMultSubtractHundred"), 3, 1.500, 0, 0.500, 0.300, Color(Green), Color(Yellow), True, True, True); + Call Subroutine(createMenuButton); + Host Player.workshopButtons[6] = Host Player.lastMenuButtonID; + Host Player.newButton = Array(Custom String("Ana Self Nano: {0}", Global.selfNanoWorkshopSetting), Null, Null, 3, -1, -0.500, 0, + 0.300, Color(Green), Color(Green), True, True, True); + Call Subroutine(createMenuButton); + Host Player.workshopButtons[7] = Host Player.lastMenuButtonID; + Host Player.newButton = Array(Custom String("Toggle"), Custom String("anaSelfNano"), Null, 3, 0.750, -0.500, 1, 0.300, Color( + Green), Color(Yellow), True, True, True); + Call Subroutine(createMenuButton); + Host Player.workshopButtons[8] = Host Player.lastMenuButtonID; + Wait Until(Is Game In Progress == True, 9999); + Host Player.destroyButtonID = Host Player.workshopButtons[0]; + Call Subroutine(destroyMenuButton); + Host Player.destroyButtonID = Host Player.workshopButtons[1]; + Call Subroutine(destroyMenuButton); + Host Player.destroyButtonID = Host Player.workshopButtons[2]; + Call Subroutine(destroyMenuButton); + Host Player.destroyButtonID = Host Player.workshopButtons[3]; + Call Subroutine(destroyMenuButton); + Host Player.destroyButtonID = Host Player.workshopButtons[4]; + Call Subroutine(destroyMenuButton); + Host Player.destroyButtonID = Host Player.workshopButtons[5]; + Call Subroutine(destroyMenuButton); + Host Player.destroyButtonID = Host Player.workshopButtons[6]; + Call Subroutine(destroyMenuButton); + Host Player.destroyButtonID = Host Player.workshopButtons[7]; + Call Subroutine(destroyMenuButton); + Host Player.destroyButtonID = Host Player.workshopButtons[8]; + Call Subroutine(destroyMenuButton); + } +} + +rule("Actions") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == False; + Event Player.currActionID != Null; + } + + actions + { + If(Event Player.currActionID == Custom String("gateMaxHealthAddOne")); + If(Global.gateMaxHealth[0] + 1 <= Global.gateMaxHealth[2]); + Global.gateMaxHealth[0] += 1; + Else; + Global.gateMaxHealth[0] = Global.gateMaxHealth[2]; + End; + Else If(Event Player.currActionID == Custom String("gateMaxHealthSubtractOne")); + If(Global.gateMaxHealth[0] - 1 >= Global.gateMaxHealth[1]); + Global.gateMaxHealth[0] -= 1; + Else; + Global.gateMaxHealth[0] = Global.gateMaxHealth[1]; + End; + Else If(Event Player.currActionID == Custom String("gateMaxHealthAddTen")); + If(Global.gateMaxHealth[0] + 10 <= Global.gateMaxHealth[2]); + Global.gateMaxHealth[0] += 10; + Else; + Global.gateMaxHealth[0] = Global.gateMaxHealth[2]; + End; + Else If(Event Player.currActionID == Custom String("gateMaxHealthSubtractTen")); + If(Global.gateMaxHealth[0] - 10 >= Global.gateMaxHealth[1]); + Global.gateMaxHealth[0] -= 10; + Else; + Global.gateMaxHealth[0] = Global.gateMaxHealth[1]; + End; + Else If(Event Player.currActionID == Custom String("gateMaxHealthAddHundred")); + If(Global.gateMaxHealth[0] + 100 <= Global.gateMaxHealth[2]); + Global.gateMaxHealth[0] += 100; + Else; + Global.gateMaxHealth[0] = Global.gateMaxHealth[2]; + End; + Else If(Event Player.currActionID == Custom String("gateMaxHealthSubtractHundred")); + If(Global.gateMaxHealth[0] - 100 >= Global.gateMaxHealth[1]); + Global.gateMaxHealth[0] -= 100; + Else; + Global.gateMaxHealth[0] = Global.gateMaxHealth[1]; + End; + Else If(Event Player.currActionID == Custom String("moneyMultAddTen")); + If(Global.moneyMultiplier[0] + 0.010 <= Global.moneyMultiplier[2]); + Global.moneyMultiplier[0] += 0.010; + Else; + Global.moneyMultiplier[0] = Global.moneyMultiplier[2]; + End; + Else If(Event Player.currActionID == Custom String("moneyMultSubtractTen")); + If(Global.moneyMultiplier[0] - 0.010 >= Global.moneyMultiplier[1]); + Global.moneyMultiplier[0] -= 0.010; + Else; + Global.moneyMultiplier[0] = Global.moneyMultiplier[1]; + End; + Else If(Event Player.currActionID == Custom String("moneyMultAddHundred")); + If(Global.moneyMultiplier[0] + 0.100 <= Global.moneyMultiplier[2]); + Global.moneyMultiplier[0] += 0.100; + Else; + Global.moneyMultiplier[0] = Global.moneyMultiplier[2]; + End; + Else If(Event Player.currActionID == Custom String("moneyMultSubtractHundred")); + If(Global.moneyMultiplier[0] - 0.100 >= Global.moneyMultiplier[1]); + Global.moneyMultiplier[0] -= 0.100; + Else; + Global.moneyMultiplier[0] = Global.moneyMultiplier[1]; + End; + Else If(Event Player.currActionID == Custom String("anaSelfNano")); + Global.selfNanoWorkshopSetting = !Global.selfNanoWorkshopSetting; + End; + Global.upgradeGateMaxHealthMaxValue[0] = Round To Integer(Global.gateMaxHealth[0] + Global.gateMaxHealth[0] * 0.500, Up) > 1000 ? 1000 : Round To Integer(Global.gateMaxHealth[0] + Global.gateMaxHealth[0] * 0.500, Up); + Global.upgradeGateMaxHealthMaxValue[1] = Round To Integer(Global.upgradeGateMaxHealthMaxValue[0] + Global.upgradeGateMaxHealthMaxValue[0] * 0.500, Up); + Global.upgradeGateMaxHealthMaxValue[2] = Round To Integer(Global.upgradeGateMaxHealthMaxValue[1] + Global.upgradeGateMaxHealthMaxValue[1] * 0.500, Up); + Event Player.buttonModification = Array(Event Player.workshopButtons[0], 0, Custom String("GATE MAX HEALTH: {0}", + Global.gateMaxHealth[0])); + Call Subroutine(modifyMenuButton); + Event Player.buttonModification = Array(Event Player.workshopButtons[4], 0, Custom String("Money Multiplier: {0}", + Global.moneyMultiplier[0])); + Call Subroutine(modifyMenuButton); + Event Player.buttonModification = Array(Event Player.workshopButtons[7], 0, Custom String("Ana Self Nano: {0}", + Global.selfNanoWorkshopSetting)); + Call Subroutine(modifyMenuButton); + } +} \ No newline at end of file diff --git a/defendTheCastleExtended/old_versions/c090.ow b/defendTheCastleExtended/old_versions/c090.ow new file mode 100644 index 0000000..702f24d --- /dev/null +++ b/defendTheCastleExtended/old_versions/c090.ow @@ -0,0 +1,9078 @@ +settings +{ + main + { + Description: "Defend Castle v0.6.c090 by HuKuTa94#2589 modified by ShuriZma#2349 - J1K6F - Defend the gate, kill enemies and don't allow them to damage the gate! Torb, Brig and Rein can repair the gate but beware! You never know what the enemy might be hiding until now! Special Thanks to: Shingen#21859 for the Abilities, LemonAid#11644 for the Hero Talents & Josbird for teaching me about Menus! Find the Original Mode on: workshop.codes/BQEGS" + } + + lobby + { + Max Spectators: 4 + Max Team 1 Players: 4 + Max Team 2 Players: 0 + Return To Lobby: Never + Swap Teams After Match: No + } + + modes + { + Escort + { + enabled maps + { + Havana + } + } + + Team Deathmatch + { + enabled maps + { + } + } + + General + { + Game Mode Start: Immediately + Spawn Health Packs: Disabled + } + } + + workshop + { + Ana can nano herself even if there are other players only if no player targeted: On + Story Heroes: Off + } + + extensions + { + Beam Effects + Kinetic Explosion Effects + Explosion Sounds + Play More Effects + Spawn More Dummy Bots + } +} + +variables +{ + global: + 0: GatePosition + 1: ZenSpawnPositions + 2: SpawnPositionMaxId + 3: LoopIterator1 + 4: BigBossSpawnPositions + 5: PlayerSpawnPositions + 6: GateHealthChase + 7: GateHealth + 8: GateMaxHealth + 9: GateProgressBarColorCurrent + 10: GateProgressBarColorComponent + 11: GateHealthEvent + 12: BastionTargetPositions + 13: SniperPositions + 14: BallSpawnPositions + 15: ZenRespawnTime + 16: TimeMin + 17: TimeSec + 18: DefaultCurrentBot + 19: DefaultHeroBotsPool + 20: DefaultHeroBotsPoolCurrentId + 21: IsDebug + 22: BotOrisaParent + 23: IsStoryHeroes + 24: BotOrisaChild + 25: GateRepairPosition + 26: BotOrisaTargetPosition + 27: BotEchoRespawnPosition + 28: BotEchoTeleportPositions + 29: UpgradeGateMaxHealthValue + 30: UpgradeGateMaxHealthHudId + 31: UpgradePlayerMaxHealthValue + 32: UpgradePlayerMaxHealthHudId + 33: UpgradeCriticalDamageValue + 34: UpgradeCriticalDamageHudId + 35: UpgradeMaxAmmoValue + 36: UpgradeMaxAmmoHudId + 37: UpgradeMaxAmmoMaxValue + 38: UpgradePlayerMaxHealthMaxValue + 39: UpgradeCriticalDamageMaxValue + 40: UpgradeGateMaxHealthMaxValue + 41: UpgradePlayerMaxHealthNewValue + 42: IsDebugAINavigation + 43: GameLogicCountOfUniqueHeroes + 44: IsNewWaveGameLogicProcessing + 45: AutoRepair + 46: UpgradePerkSharpshooterValue + 47: Perk + 48: MaxHealthDone + 49: StartMoney + 50: Time5Min + 51: SelfNanoWorkshopSetting + 52: ShopCamPos + 53: ShopBasePos + 54: ShopPosAngle + 55: activeBoss + 56: bossTrigger + 57: bossRotation + 58: lastBoss + 59: Time10Min + 112: AllPos + 113: AllDir + 114: firstpos + 115: secondpos + 116: firstpoint2 + 117: secondpoint2 + 118: second + 119: z + 120: Wall_ID + 121: showwalls + 122: is_Grounded + 123: g_beamType + 124: x + 125: NodePositions + 126: NodeConnections + 127: DistanceMatrix + + player: + 0: BotSeePlayer + 1: BotDoesUniqueBehaviour + 2: BotEffects + 3: BotRayCastHitPosition + 4: BotEventPosition + 5: CurrentHero + 6: IsDead + 7: IsRespawning + 8: BotBastionArtilleryDidShotsCount + 9: BotCounter + 10: HasBadStatus + 11: EventHealth + 12: HealOverTimeId + 13: BotIsOrisaChild + 14: BotEchoCapturedPlayer + 15: BotPlayersInRadius + 16: BotLoopIterator2 + 17: BotWidowShotTime + 18: BotWidowTeleportTime + 19: IsNanoed + 20: AbilityHUD + 21: Lucio_Dash_Active + 22: Lucio_Dash_Icon + 23: AnaEntityID + 24: Abilities + 25: Money + 26: HeroTalentText + 27: DamageDealt + 28: PlayerHealth + 29: AbilityCountdown + 30: HP_Pool + 31: Effects_ + 32: Ability_Projectile1 + 33: Ability_End + 34: Storm_Projectile + 35: Storm_EndPoint + 36: Storm_Effects + 37: Feared_until + 38: Modification_Damage + 39: Ability_Projectile2 + 40: Ability_Position + 41: Chain_Reaction_On + 42: Chain_Reaction_Immune + 43: Ability_Active + 44: Ability_Resource + 46: isInMenu + 47: ReinPin + 48: PlayerFacing + 49: isBoss + 50: Gen_Direction + 51: Gen_Available + 52: Ability_Player + 53: Ability_Countdown + 105: filterpos + 106: lastsavedpos + 107: closestbodypos + 108: fullbodypos + 109: prevpos_intersection + 110: active_wall + 111: closestwall + 112: x + 113: intersection_length + 114: thickness + 115: BotCancelPathFinding + 116: BotLoopIterator1 + 117: BotTempArray + 118: BotTargetPlayer + 119: BotTargetPosition + 120: BotClosestNodeIdToTarget + 121: BotClosestNodeIdToBot + 122: BotPrevNodeId + 123: BotNextNodeId + 124: BotNextNodePosition + 125: BotCurrentDistanceToTarget + 126: BotShortestDistanceToTarget + 127: BotIsPathFinding +} + +subroutines +{ + 0: BotBastionArtilleryDamage + 1: BotBastionFlameGunDamage + 2: BotBastionRespawn + 3: GateProgressBarColor + 4: BotZenyattaRespawn + 5: BotWidowRespawn + 6: BotBallRespawn + 7: GameLogicAddNextHeroInGame + 8: BotOrisaRespawn + 9: BotLandingFromSky + 10: BotEchoRespawn + 11: BotEchoDetachPlayer + 12: BotEchoFlyToPlayer + 13: BotEchoFlyToPortal + 14: GameLogicSetBotProperties + 15: DisablePlayer + 16: BotApearFromUnderground + 17: BotReinRespawn + 18: PlayerInit + 19: BotInit + 20: PlayerRespawn + 21: BotRespawn + 22: BotWidowBadStatus + 23: GameLogicWave0 + 24: Refund + 25: EnablePlayer + 124: BotStartPathFinding + 125: BotGetClosestNodeIdToTarget + 126: BotGetNextNodeIdAndPosition + 127: BotResetPathFinding +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("MAP: HAVANA") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Havana); + } + + actions + { + Global.NodePositions = Array(Vector(147.588, 6.425, -46.749), Vector(136.181, 6.425, -57.159), Vector(130.189, 6.425, -63.781), + Vector(123.305, 6.425, -57.983), Vector(125.678, 6.504, -46.633), Vector(114.485, 7.471, -46.699), Vector(138.743, 6.425, + -32.974), Vector(126.498, 6.425, -39.920), Vector(124.572, 10.434, -34.300), Vector(138.605, 5.359, -18.647), Vector(119.009, + 2.331, -31.024), Vector(121.138, 5.228, -19.933), Vector(126.722, 6.425, -29.505), Vector(102.762, 3.157, -33.609), Vector( + 76.030, 7.418, -74.087), Vector(83.720, 9.425, -33.744), Vector(97.439, 7.238, -42.379), Vector(86.252, 12.416, -47.261), + Vector(65.178, 11.425, -73.187), Vector(97.466, 7.269, -50.596), Vector(113.039, 7.424, -37.337), Vector(106.179, 7.450, + -46.143), Vector(90.086, 7.411, -44.653), Vector(78.752, 7.418, -62.140), Vector(82.124, 7.428, -44.229), Vector(90.675, 7.231, + -51.234), Vector(85.717, 4.692, -63.446), Vector(90.830, 4.330, -70.697), Vector(102.425, 2.387, -72.817), Vector(81.443, + 4.425, -81.648), Vector(70.743, 6.418, -81.495), Vector(69.738, 6.419, -96.344), Vector(127.586, 12.643, -63.344), Vector( + 118.911, 13.468, -58.008), Vector(102.885, 1.092, -56.579), Vector(100.009, 2.967, -67.139), Vector(106.703, 0.465, -44.628), + Vector(81.695, 7.418, -52.140), Vector(126.979, 12.393, -55.079), Vector(153.720, 18.578, -21.745), Vector(155.301, 18.619, + -17.595), Vector(133.043, 10.425, -26.625), Vector(114.646, 7.278, -57.336), Vector(95.160, 3.688, -81.194), Vector(78.456, + 5.418, -93.581), Vector(75.455, 5.418, -101.492), Vector(148.071, 9.432, -32.123), Vector(146.706, 9.425, -27.858), Vector( + 144.273, 9.445, -63.119), Vector(144.278, 9.454, -58.447)); + Global.NodeConnections = Array(Array(1, 6, 4, 7), Array(2, 1, 4, 6, 7, 0, 49), Array(1, 3), Array(2, 4, 42), Array(3, 1, 5, 7, 6, + 1, 0), Array(4, 7, 20, 21, 19, 16, 42), Array(7, 1, 4, 1, 9, 12, 0, 46), Array(4, 5, 6, 1, 1, 12, 0), Array(7, 41), Array(6, + 11), Array(11, 13), Array(9, 10, 13), Array(6, 7, 10), Array(10, 16, 36), Array(18, 23, 30), Array(17, 24), Array(13, 19, 22, + 21, 25, 5), Array(15, 22, 25, 23), Array(14), Array(16, 21, 22, 26, 27, 35, 25, 5), Array(5, 13, 10), Array(19, 16, 5, 13, 22, + 34), Array(16, 19, 21, 24, 25), Array(14, 25, 26, 37), Array(22, 15, 37), Array(23, 22, 19, 16, 26, 27, 35, 37), Array(25, 19, + 27, 35, 29), Array(19, 26, 25, 29, 35, 43), Array(35, 34, 43), Array(27, 26, 30, 43, 44), Array(29, 14, 31), Array(30, 29, 45), + Array(33, 38, 1, 48), Array(32, 38, 42), Array(35, 36, 28), Array(28, 19, 25, 27, 26, 34), Array(13, 34), Array(25, 23, 24), + Array(5, 4, 1, 6, 1, 32, 33, 0), Array(40), Array(39), Array(6, 8, 47, 46), Array(3, 5, 34), Array(28, 27, 29, 44), Array(29, + 43, 45), Array(44, 31), Array(6, 47), Array(46, 41), Array(49, 32), Array(1, 0, 6, 48)); + Global.DistanceMatrix = Array(Array(0, 1, 2, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, + 4, 5, 4, 4, 5, 5, 5, 0, 0, 4, 3, 5, 6, 7, 2, 3, 3, 2), Array(1, 0, 1, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, + 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 3, 4, 4, 4, 5, 5, 4, 0, 0, 4, 3, 5, 6, 7, 2, 3, 2, 1), Array(2, 1, 0, 1, 2, 3, 2, 2, 6, 3, 4, 4, + 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 4, 6, 7, 8, 4, 5, 3, 4, 4, 6, 5, 0, 0, 5, 2, 5, 6, 7, 3, 4, 3, 2), Array(2, 2, + 1, 0, 1, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, 5, 6, 2, 3, 3, 5, 6, 0, 0, 5, 1, 4, + 5, 6, 3, 4, 4, 3), Array(1, 1, 2, 1, 0, 1, 1, 1, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, + 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, 2, 3, 3, 2), Array(2, 2, 3, 2, 1, 0, 2, 1, 6, 3, 2, 3, 2, 2, 4, 4, 1, 5, 5, 1, 1, 1, 2, 3, + 3, 2, 2, 2, 3, 3, 4, 5, 5, 6, 2, 2, 3, 3, 6, 0, 0, 5, 1, 3, 4, 5, 3, 4, 4, 3), Array(1, 1, 2, 2, 1, 2, 0, 1, 4, 1, 2, 2, 1, 3, + 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 4, 5, 4, 4, 4, 5, 5, 0, 0, 3, 3, 5, 6, 7, 1, 2, 3, 2), Array(1, 1, 2, 2, + 1, 1, 1, 0, 5, 2, 2, 3, 1, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, + 2, 3, 3, 2), Array(2, 2, 3, 3, 2, 2, 2, 1, 0, 3, 3, 4, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, + 5, 5, 6, 0, 0, 1, 3, 5, 6, 7, 2, 2, 4, 3), Array(2, 2, 3, 3, 2, 3, 1, 2, 5, 0, 2, 1, 2, 2, 6, 6, 3, 7, 7, 4, 4, 4, 4, 5, 5, 4, + 5, 5, 5, 6, 7, 8, 5, 6, 4, 5, 3, 5, 6, 0, 0, 4, 4, 6, 7, 8, 2, 3, 4, 3), Array(4, 4, 5, 5, 4, 3, 3, 4, 7, 2, 0, 1, 4, 1, 5, 5, + 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 7, 8, 3, 4, 2, 4, 8, 0, 0, 6, 4, 5, 6, 7, 4, 5, 6, 5), Array(3, 3, 4, 4, 3, 3, + 2, 3, 6, 1, 1, 0, 3, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 6, 7, 3, 4, 2, 4, 7, 0, 0, 5, 4, 5, 6, 7, 3, 4, + 5, 4), Array(2, 2, 3, 3, 2, 2, 1, 1, 5, 2, 1, 2, 0, 2, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, 3, 5, + 6, 0, 0, 4, 3, 5, 6, 7, 2, 3, 4, 3), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 3, 1, 2, 4, 0, 4, 4, 1, 5, 5, 2, 3, 2, 2, 3, 3, 2, 3, 3, + 3, 4, 5, 6, 7, 8, 2, 3, 1, 3, 8, 0, 0, 7, 3, 4, 5, 6, 5, 6, 6, 5), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 5, 6, 6, 4, 0, 4, 3, 5, + 1, 3, 5, 4, 3, 1, 3, 2, 2, 3, 4, 2, 1, 2, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 3, 3, 3, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, + 5, 10, 7, 5, 6, 6, 4, 3, 0, 3, 1, 4, 3, 5, 3, 2, 2, 1, 2, 3, 3, 4, 4, 4, 5, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 4, 5, 6, 7, 8, + 8, 7), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 3, 3, 0, 4, 4, 1, 2, 1, 1, 2, 2, 1, 2, 2, 3, 3, 4, 5, 6, 7, 2, 2, 2, 2, + 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 1, 2, 0, 3, 2, 4, 2, 1, 1, 2, 1, 2, 2, + 3, 3, 3, 4, 8, 9, 3, 2, 4, 2, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 6, 7, 7, 5, 1, 5, 4, 6, + 0, 4, 6, 5, 4, 2, 4, 3, 3, 4, 5, 3, 2, 3, 10, 11, 5, 4, 6, 3, 11, 0, 0, 10, 6, 4, 4, 4, 8, 9, 9, 8), Array(3, 3, 4, 3, 2, 1, 3, + 2, 7, 4, 3, 4, 3, 2, 3, 3, 1, 4, 4, 0, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 3, 4, 6, 7, 2, 1, 3, 2, 7, 0, 0, 6, 2, 2, 3, 4, 4, 5, 5, + 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 3, 1, 2, 3, 1, 5, 5, 2, 6, 6, 2, 0, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 6, 7, 3, 3, 2, 4, 7, + 0, 0, 6, 2, 4, 5, 6, 4, 5, 5, 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 4, 3, 1, 4, 5, 1, 2, 0, 1, 3, 2, 2, 2, 2, 2, + 3, 4, 5, 6, 7, 1, 2, 2, 3, 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 3, 2, 1, 3, 4, + 1, 3, 1, 0, 2, 1, 1, 2, 2, 3, 3, 4, 5, 7, 8, 2, 2, 3, 2, 8, 0, 0, 7, 3, 3, 4, 5, 5, 6, 6, 5), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, + 6, 4, 5, 5, 3, 1, 3, 2, 4, 2, 2, 4, 3, 2, 0, 2, 1, 1, 2, 3, 2, 2, 3, 8, 9, 3, 2, 4, 1, 9, 0, 0, 8, 4, 3, 3, 4, 6, 7, 7, 6), + Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 3, 1, 2, 2, 4, 2, 4, 2, 1, 2, 0, 2, 3, 3, 4, 4, 4, 5, 8, 9, 3, 3, 4, 1, 9, 0, + 0, 8, 4, 4, 5, 6, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 2, 3, 1, 4, 3, 1, 3, 2, 1, 1, 2, 0, 1, 1, 2, 2, + 3, 4, 7, 8, 2, 1, 3, 1, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, + 3, 2, 2, 2, 3, 1, 0, 1, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 2, 2, 3, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, + 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 0, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 1, 2, 3, 5, 6, 6, 5), Array( + 5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 4, 5, 3, 6, 5, 2, 4, 3, 3, 3, 4, 2, 2, 2, 0, 2, 3, 4, 8, 9, 1, 1, 2, 3, 9, 0, 0, 8, + 4, 1, 2, 3, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 2, 5, 3, 6, 3, 2, 4, 3, 3, 3, 4, 2, 1, 1, 2, 0, 1, 2, + 8, 9, 3, 2, 4, 3, 9, 0, 0, 8, 4, 1, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 1, 5, 4, 6, 2, 3, 5, 4, + 4, 2, 4, 3, 2, 2, 3, 1, 0, 1, 9, 10, 4, 3, 5, 3, 10, 0, 0, 9, 5, 2, 2, 2, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, + 7, 6, 5, 2, 6, 4, 7, 3, 3, 5, 4, 4, 3, 5, 3, 2, 2, 3, 1, 1, 0, 9, 10, 4, 3, 5, 4, 10, 0, 0, 9, 5, 2, 2, 1, 7, 8, 8, 7), Array( + 2, 1, 2, 3, 2, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 4, 5, 6, 7, 0, 1, 3, 4, 4, 5, 1, 0, 0, 5, + 2, 5, 6, 7, 3, 4, 1, 2), Array(2, 2, 3, 2, 2, 2, 2, 3, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, + 1, 0, 2, 3, 3, 5, 1, 0, 0, 5, 1, 4, 5, 6, 3, 4, 2, 3), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 5, 3, 4, 5, 2, 4, 5, 3, 6, 5, 2, 4, 3, + 3, 3, 4, 2, 2, 2, 1, 3, 4, 5, 8, 9, 0, 1, 1, 3, 9, 0, 0, 8, 4, 2, 3, 4, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, + 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 1, 1, 2, 3, 4, 7, 8, 1, 0, 2, 2, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(5, 5, + 6, 5, 4, 3, 5, 4, 9, 4, 2, 3, 5, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 8, 9, 1, 2, 0, 4, 9, 0, 0, 8, 4, 3, + 4, 5, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 2, 2, 3, 3, 2, 4, 3, 2, 1, 1, 1, 2, 2, 3, 3, 3, 4, 8, 9, + 3, 2, 4, 0, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(1, 1, 2, 2, 1, 1, 1, 2, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, + 4, 3, 3, 3, 4, 4, 5, 6, 1, 1, 3, 3, 4, 4, 0, 0, 0, 4, 2, 4, 5, 6, 2, 3, 2, 2), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(2, 2, 3, 3, 2, 3, 1, 2, 1, 2, 3, 3, 2, + 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 0, 4, 6, 7, 8, 1, 1, 4, 3), Array(3, 3, 2, + 1, 2, 1, 3, 2, 7, 4, 3, 4, 3, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 6, 7, 1, 2, 2, 4, 7, 0, 0, 6, 0, 3, 4, + 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 3, 5, 3, 6, 4, 2, 4, 3, 3, 3, 4, 2, 2, 1, 1, 1, 2, 3, 8, 9, 2, + 2, 3, 3, 9, 0, 0, 8, 4, 0, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 3, 6, 4, 7, 4, 3, 5, 4, 4, 4, 5, + 3, 2, 2, 2, 1, 2, 2, 9, 10, 3, 3, 4, 4, 10, 0, 0, 9, 5, 1, 0, 1, 7, 8, 8, 7), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 7, 8, 7, 6, + 3, 7, 5, 8, 4, 4, 6, 5, 5, 4, 6, 4, 3, 3, 3, 2, 2, 1, 10, 11, 4, 4, 5, 5, 11, 0, 0, 10, 6, 2, 1, 0, 8, 9, 9, 8), Array(2, 2, 3, + 3, 2, 3, 1, 2, 3, 2, 3, 3, 2, 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 2, 4, 6, 7, + 8, 0, 1, 4, 3), Array(3, 3, 4, 4, 3, 4, 2, 3, 2, 3, 4, 4, 3, 5, 8, 8, 5, 9, 9, 5, 5, 5, 6, 7, 7, 6, 6, 6, 7, 7, 8, 9, 6, 7, 6, + 6, 6, 7, 7, 0, 0, 1, 5, 7, 8, 9, 1, 0, 5, 4), Array(2, 2, 3, 4, 3, 3, 2, 3, 6, 3, 4, 4, 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, + 5, 5, 5, 5, 6, 7, 8, 1, 2, 4, 5, 5, 6, 2, 0, 0, 5, 3, 6, 7, 8, 3, 4, 0, 1), Array(1, 1, 2, 3, 2, 3, 1, 2, 5, 2, 3, 3, 2, 4, 7, + 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 2, 3, 5, 5, 5, 6, 3, 0, 0, 4, 4, 6, 7, 8, 2, 3, 1)); + } +} + +rule("SUBROUTINE: BOT - RESET PATH FINDING") +{ + event + { + Subroutine; + BotResetPathFinding; + } + + actions + { + Event Player.BotTargetPlayer = -1; + Event Player.BotTargetPosition = -1; + Event Player.BotPrevNodeId = -1; + Event Player.BotClosestNodeIdToTarget = -1; + Event Player.BotNextNodeId = -1; + Event Player.BotNextNodePosition = -1; + Event Player.BotIsPathFinding = False; + Event Player.BotCancelPathFinding = False; + Stop Throttle In Direction(Event Player); + disabled Stop Facing(Event Player); + } +} + +rule("SUBROUTINE: BOT - START PATH FINDING") +{ + event + { + Subroutine; + BotStartPathFinding; + } + + actions + { + disabled Abort If(Event Player.BotIsPathFinding == True); + Call Subroutine(BotGetNextNodeIdAndPosition); + disabled Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Event Player.BotIsPathFinding = True; + } +} + +rule("SUBROUTINE: BOT - GET NEXT NODE ID AND POSITION") +{ + event + { + Subroutine; + BotGetNextNodeIdAndPosition; + } + + actions + { + "BOT JUST START FOLLOW PATH OR LOST NEXT NODE" + If(Event Player.BotPrevNodeId == -1); + Event Player.BotClosestNodeIdToBot = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array(Global.NodePositions, + Is In Line of Sight(Position Of(Event Player) + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS) == True), + Distance Between(Position Of(Event Player), Current Array Element))[0]); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + "NEXT NODE IS TARGET (DISTANCE TO TARGET NODE = 1)" + If(Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1); + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToTarget; + "CHECK CONNECTIONS OF REACHED NODE" + Else; + Event Player.BotShortestDistanceToTarget = 999; + Event Player.BotCurrentDistanceToTarget = Event Player.BotShortestDistanceToTarget; + Event Player.BotTempArray = Global.NodeConnections[Event Player.BotClosestNodeIdToBot]; + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotTempArray), 1); + Event Player.BotCurrentDistanceToTarget = Global.DistanceMatrix[Event Player.BotTempArray[Event Player.BotLoopIterator1]][Event Player.BotClosestNodeIdToTarget]; + If(Event Player.BotCurrentDistanceToTarget < Event Player.BotShortestDistanceToTarget); + Event Player.BotShortestDistanceToTarget = Event Player.BotCurrentDistanceToTarget; + Event Player.BotNextNodeId = Event Player.BotTempArray[Event Player.BotLoopIterator1]; + End; + End; + End; + "NEXT NODE IS HIGHER THAN BOT AND BOT DIDN'T REACH CLOSEST NODE" + If(Y Component Of(Position Of(Event Player)) - Y Component Of(Global.NodePositions[Event Player.BotNextNodeId]) + < -3 && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + "BOT CAN SEE TARGET POSITION AND NEXT NODE IS TARGET" + Else If( + Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1 && Is In Line of Sight( + Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotTargetPosition + Vector(0, 2, 0), Barriers Do Not Block LOS)); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Abort; + "BOT CAN'T SEE NEXT NODE AND PREV NODE != REACHED NODE" + Else If(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), + Global.NodePositions[Event Player.BotNextNodeId] + Vector(0, 2, 0), Barriers Do Not Block LOS) + == False && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + End; + Event Player.BotNextNodePosition = Global.NodePositions[Event Player.BotNextNodeId]; + } +} + +rule("SUBROUTINE: BOT - GET CLOSEST NODE ID AND POSITION TO TARGET") +{ + event + { + Subroutine; + BotGetClosestNodeIdToTarget; + } + + actions + { + Event Player.BotTargetPosition = Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Event Player.BotTargetPosition; + Event Player.BotClosestNodeIdToTarget = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array( + Global.NodePositions, Is In Line of Sight(Event Player.BotTargetPosition + Vector(0, 2, 0), Current Array Element, + Barriers Do Not Block LOS) == True), Distance Between(Event Player.BotTargetPosition, Current Array Element))[0]); + } +} + +rule("BOT: PATH FINDING - START") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + (Event Player.BotTargetPosition != -1 || Event Player.BotTargetPlayer != -1) == True; + } + + actions + { + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - CANCEL") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotCancelPathFinding == True; + } + + actions + { + Start Rule(BotResetPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - LOST THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + (Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotNextNodePosition + Vector(0, 2.500, 0), + Barriers Do Not Block LOS) == False && Speed Of In Direction(Event Player, Throttle Of(Event Player)) < 2) == True; + } + + actions + { + Wait(0.500, Abort When False); + "RESET PREV NODE ID TO INFORM BOT THAT IT LOST NEXT NODE" + Event Player.BotPrevNodeId = -1; + "TRY FIND NEW NEXT NODE" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodeId), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +rule("BOT: PATH FINDING - REACHED THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotClosestNodeIdToTarget >= 0; + (Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotNextNodePosition), 0, Z Component Of(Event Player.BotNextNodePosition))) < 0.850) == True; + } + + actions + { + Event Player.BotPrevNodeId = Event Player.BotNextNodeId; + Event Player.BotClosestNodeIdToBot = Event Player.BotNextNodeId; + "BOT'S TARGET IS PLAYER" + If(Event Player.BotTargetPlayer != -1); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + Event Player.BotCurrentDistanceToTarget = Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of( + Position Of(Event Player))), Vector(X Component Of(Event Player.BotTargetPosition), 0, Z Component Of( + Event Player.BotTargetPosition))); + "BOT REACHED THE TARGET NODE OR TARGET POSITION" + If(Event Player.BotNextNodeId == Event Player.BotClosestNodeIdToTarget || Event Player.BotCurrentDistanceToTarget <= 0.850); + "BOT DIDN'T REACH TARGET POSITION" + If(Event Player.BotCurrentDistanceToTarget > 0.850); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Skip(6); + "BOT REACHED TARGET" + Else; + Call Subroutine(BotResetPathFinding); + Abort; + End; + End; + "CONTINUE FOLLOW PATH" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: GAME MODE INIT - WORKSHOP SETTINGS") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.IsDebug = False; + Global.IsDebugAINavigation = False; + Global.GateMaxHealth = Workshop Setting Integer(Custom String("DEFEND CASTLE"), Custom String("GATE MAX HEALTH"), 500, 100, 1000, + 0); + Global.IsStoryHeroes = Workshop Setting Toggle(Custom String("DEFEND CASTLE"), Custom String("Story Heroes"), True, 0); + Global.SelfNanoWorkshopSetting = Workshop Setting Toggle(Custom String("Ana Self Nano"), Custom String( + "Ana can nano herself even if there are other players (only if no player targeted)"), False, 0); + } +} + +rule("GLOBAL: GAME MODE INIT - COMMON PROPERTIES") +{ + event + { + Ongoing - Global; + } + + actions + { + Create HUD Text(All Players(All Teams), Null, Null, Custom String( + "DEFEND CASTLE v0.6.c090 BY HUKUTA94#2589\r\nmodified by ShuriZma#2349\r\nDiscord: discord.shurizma.de\r\n{1}", Null, + Custom String( + "Special Thanks to:\r\nShingen#21859 for the Abilities,\r\nLemonAid#11644 for the Hero Talents &\r\nJosbird for teaching me about Menus")), + Right, -1000, Color(White), Color(White), Color(White), Visible To, Default Visibility); + Global.GateRepairPosition = Vector(153, 8, -46.500); + Global.GatePosition = Vector(148.800, 6, -46.400); + Global.BallSpawnPositions = Array(Vector(104, 7, -46), Vector(106, 2, -31)); + Global.SniperPositions = Array(Vector(154, 18, -22.600), Vector(86, 12, -46.600), Vector(80.880, 11.300, -71.600), Vector(98, 9, + -19)); + Global.ZenSpawnPositions = Array(Vector(79.500, 5, -100), Vector(90, 4, -88), Vector(65, 11, -70), Vector(85, 4, -68), Vector(96, + 2, -73), Vector(84, 7, -47), Vector(95, 9, -34), Vector(108, 1.700, -28), Vector(113, 7, -37), Vector(123, 5, -19), Vector(144, + 5, -19), Vector(123, 6, -39), Vector(123, 6, -61), Vector(129, 6, -30.500), Vector(135, 6, -63)); + Global.PlayerSpawnPositions = Array(Vector(153.300, 10, -63.800), Vector(153.300, 10, -61.700), Vector(153.300, 10, -31.700), + Vector(153.300, 10, -29.600)); + Global.BigBossSpawnPositions = Array(Vector(78, 4, -84), Vector(95, 4, -82)); + Global.BastionTargetPositions = Array(Vector(131, 12, -62), Vector(115, 7, -46), Objective Position(2), Vector(136, 10, -27)); + Global.SpawnPositionMaxId = 2; + Global.BotOrisaTargetPosition = Vector(104, 7, -46); + Global.BotEchoRespawnPosition = Vector(130, 23, -44); + Global.BotEchoTeleportPositions = Array(Vector(88, 23, -79), Vector(108, 18, -27)); + Global.DefaultHeroBotsPool = Array(Hero(Zenyatta), Hero(Widowmaker), Null, Hero(Bastion), Hero(Echo), Hero(Bastion)); + Global.ZenRespawnTime = 10; + Global.GameLogicCountOfUniqueHeroes = 5; + Global.lastBoss = Array(Null, Null, Null, Null); + } +} + +disabled rule("PLAYER: DEBUG - PRESS INTERACT") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Host Player == True; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + disabled Modify Player Score(Event Player, 10); + disabled Global.GateHealth -= 5; + disabled Start Rule(GateProgressBarColor, Restart Rule); + Global.TimeSec = 59; + Set Status(Event Player, Null, Phased Out, 9999); + disabled Set Ultimate Charge(Event Player, 100); + disabled Kill(Event Player, Null); + disabled Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: DEBUG - AI NAVIGATION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.IsDebugAINavigation == True; + } + + actions + { + For Global Variable(LoopIterator1, 0, Count Of(Global.NodePositions), 1); + Create Effect(All Players(All Teams), Sphere, Color(Red), Global.NodePositions[Global.LoopIterator1], 0.850, Visible To); + Create In-World Text(All Players(All Teams), Custom String("NODE {0}", Global.LoopIterator1), + Global.NodePositions[Global.LoopIterator1], 1.200, Clip Against Surfaces, Visible To, Color(White), Default Visibility); + End; + } +} + +disabled rule("GLOBAL: DEBUG - CREATE BOTS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + Create Dummy Bot(Hero(Bastion), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + Create Dummy Bot(Hero(Orisa), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +disabled rule("PLAYER: DEBUG - INFOS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + Host Player == Event Player; + Has Spawned(Event Player) == True; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Create HUD Text(Event Player, Custom String("POS {0}\r\nFACING {1}", Position Of(Event Player), Facing Direction Of(Event Player)), + Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + Create HUD Text(Event Player, Custom String("SERVER PERFORMANCE\r\nLOAD {0}%\r\nPEAK {1}%\r\nAVG {2}%", Server Load, + Server Load Peak, Server Load Average), Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create Progress Bar HUD Text(Event Player, 45, Custom String("45 / 100 KILLS"), Left, -99, Color(Blue), Color(White), + Visible To Values and Color, Default Visibility); + disabled Create HUD Text(Event Player, Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Null, Custom String( + "LEVEL 1 - 50 AMMO CLIP"), Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + "ЭФФЕКТ С ОФФСЕТОМ ОТ ПОЗИЦИИ ГЛАЗ" + disabled Create Beam Effect(All Players(All Teams), Bad Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + Facing Direction Of( + Event Player) * 3, Eye Position(Event Player) + Facing Direction Of(Event Player) * 50, Color(Purple), + Visible To Position and Radius); + } +} + +disabled rule("=== TEAM UPGRADES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: TEAM UPGRADES - INIT") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.UpgradeMaxAmmoMaxValue[0] = 200; + Global.UpgradeMaxAmmoMaxValue[1] = 500; + Global.UpgradeCriticalDamageMaxValue[0] = 10; + Global.UpgradeCriticalDamageMaxValue[1] = 5; + Global.UpgradePlayerMaxHealthNewValue = 150; + Global.UpgradePlayerMaxHealthMaxValue[0] = 2500; + Global.UpgradePlayerMaxHealthMaxValue[1] = 5000; + Global.UpgradeGateMaxHealthMaxValue[0] = Round To Integer(Global.GateMaxHealth + Global.GateMaxHealth * 0.500, Up); + Global.UpgradeGateMaxHealthMaxValue[1] = Global.UpgradeGateMaxHealthMaxValue[0] + Global.UpgradeGateMaxHealthMaxValue[0]; + Abort If(Global.IsDebug == False); + Global.UpgradeMaxAmmoMaxValue[0] = 1; + Global.UpgradeCriticalDamageMaxValue[0] = 1; + Global.UpgradePlayerMaxHealthMaxValue[0] = 1; + Global.UpgradeGateMaxHealthMaxValue[0] = 1; + Global.UpgradeMaxAmmoMaxValue[1] = 10; + Global.UpgradeCriticalDamageMaxValue[1] = 1; + Global.UpgradePlayerMaxHealthMaxValue[1] = 100; + Global.UpgradeGateMaxHealthMaxValue[1] = 25; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GATE'S MAX HEALTH UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Global.GateMaxHealth = Global.UpgradeGateMaxHealthMaxValue[0]; + Global.GateHealth = Global.GateMaxHealth; + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Right, 1, Color( + Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X GATE REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[1]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Start Rule(GateProgressBarColor, Restart Rule); + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X GATE REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X GATE REPAIR"), Right, 1, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Global.GateHealth = Global.GateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + } +} + +rule("PLAYER: UPGRADE - PLAYER'S MAX HEALTH - DEALT HEALING") +{ + event + { + Player Received Healing; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + disabled Healer != Event Player; + Global.UpgradePlayerMaxHealthValue < Global.UpgradePlayerMaxHealthMaxValue[1]; + } + + actions + { + Global.UpgradePlayerMaxHealthValue += Event Healing; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH: {0}%", Global.UpgradePlayerMaxHealthNewValue), Right, 2, Color(Green), Color(Green), Color(Green), + Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("Up You Go: You respawn twice as fast"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[1]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.MaxHealthDone = 50; + All Players(Team 1).PlayerHealth = 100 + Global.MaxHealthDone + All Players(Team 1).Abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).PlayerHealth); + Heal(All Players(Team 1), Null, 9999); + } +} + +rule("GLOBAL: UPGRADE - PERK UP YOU GO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("UP YOU GO UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String("Up You Go"), + Right, 3, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + Set Respawn Max Time(All Players(Team 1), 5); + Heal(All Players(Team 1), Null, 9999); + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.Perk[2] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[17] = Last Text ID; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Hero Of(Victim) == Hero(Widowmaker); + Global.UpgradeCriticalDamageValue < Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradeCriticalDamageValue += 1; + Small Message(All Players(Team 1), Custom String("CRITICAL DAMAGE CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - CRITICAL DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("CRITICAL DAMAGE 150% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "CRITICAL DAMAGE 150%"), Right, 4, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String( + "Sharpshooter: Deal 40% more damage to enemies that are further than 15 meters away"), Custom String("KILL ECHO {0}/{1}", + Global.UpgradePerkSharpshooterValue, Global.UpgradeCriticalDamageMaxValue[1]), Left, 14, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - UNLOCKED") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.500); + } +} + +rule("PLAYER: UPGRADE - PERK SHARPSHOOTER - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Echo); + Global.UpgradePerkSharpshooterValue < Global.UpgradeCriticalDamageMaxValue[1]; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradePerkSharpshooterValue += 1; + Small Message(All Players(Team 1), Custom String("SHARPSHOOTER CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - PERK SHARPSHOOTER - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("SHARPSHOOTER UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Sharpshooter"), Right, 5, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + Global.Perk[0] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[18] = Last Text ID; + } +} + +rule("PLAYER: UPGRADE - MAX AMMO - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Zenyatta); + Global.UpgradeMaxAmmoValue < Global.UpgradeMaxAmmoMaxValue[1]; + } + + actions + { + Global.UpgradeMaxAmmoValue += 1; + } +} + +rule("GLOBAL: UPGRADE - MAX AMMO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("MAX AMMO 200% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "MAX AMMO 200%"), Right, 6, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("Bulletstorm: Your weapon can hold unlimited ammo"), + Custom String("KILL {2}: {0}/{1}", Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[1], Hero(Zenyatta)), Left, 15, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0) * 2); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1) * 2); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0)); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1)); + End; + } +} + +rule("GLOBAL: UPGRADE - PERK BULLETSTORM - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("BULLETSTORM UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Bulletstorm"), Right, 7, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + Global.Perk[1] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[19] = Last Text ID; + } +} + +disabled rule("=== GAME PHASES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: ASEMBLING PHASE - MAKE CHALLENGES HUDS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Assembling Heroes == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Disable Inspector Recording; + Set Match Time(20); + End; + Create In-World Text(All Players(Team 1), Custom String(" {0}\r\nREPAIR\r\n {1}", Hero Icon String(Hero(Torbjörn)), + Ability Icon String(Hero(Bastion), Button(Secondary Fire))), Global.GatePosition + Vector(0, 1.400, 0), 1.200, Do Not Clip, + Visible To, Color(White), Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("TEAM CHALLENGES"), Left, 11, Color(White), Color(Blue), Color( + White), Visible To, Default Visibility); + "UPGRADE - GATE'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String( + "GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Custom String("REPAIR GATE {0}/{1} HP", + Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[0]), Left, 12, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 2, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - PLAYER'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH {0}%", + Global.UpgradePlayerMaxHealthNewValue), Custom String("HEAL PLAYERS {0}/{1} HP", Round To Integer( + Global.UpgradePlayerMaxHealthValue, Down), Global.UpgradePlayerMaxHealthMaxValue[0]), Left, 13, Color(Orange), Color(White), + Color(White), Visible To and String, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 4, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - CRITICAL DAMAGE" + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("CRITICAL DAMAGE 150%"), Custom String( + "KILL WIDOW WITH HEADSHOT: {0}/{1}", Global.UpgradeCriticalDamageValue, Global.UpgradeCriticalDamageMaxValue[0]), Left, 14, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 6, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - MAX AMMO" + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("MAX AMMO 200%"), Custom String("KILL {2}: {0}/{1}", + Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[0], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Custom String("HOLD {0} - Reload to open the shop", Input Binding String(Button(Reload))), + Null, Null, Top, 1000, Color(Yellow), Color(White), Color(White), Visible To and String, Default Visibility); + } +} + +rule("GLOBAL: SETUP PHASE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Set Match Time(20); + End; + Set Objective Description(All Players(All Teams), Custom String("DEFEND GATE"), Visible To and String); + } +} + +rule("GLOBAL: GAME IN PROGRESS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + } + + actions + { + Set Match Time(3599); + Pause Match Time; + Disable Built-In Game Mode Scoring; + Disable Built-In Game Mode Announcer; + Disable Built-In Game Mode Completion; + Disable Game Mode HUD(All Players(All Teams)); + Disable Game Mode In-World UI(All Players(All Teams)); + Global.GateHealth = Global.GateMaxHealth; + Global.GateHealthChase = Global.GateHealth; + Global.GateProgressBarColorComponent = 255; + Global.GateProgressBarColorCurrent = Color(White); + Create Progress Bar HUD Text(All Players(Team 1), Global.GateHealthChase * 100 / Global.GateMaxHealth, Custom String( + "GATE {0}/{1}", Global.GateHealth, Global.GateMaxHealth), Top, 1, Global.GateProgressBarColorCurrent, Color(White), + Visible To Values and Color, Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("SURVIVED TIME: {0}:{1}", Global.TimeMin, + Global.TimeSec < 10 ? Custom String("0{0}", Global.TimeSec) : Global.TimeSec), Top, 2, Color(White), Color(White), Color( + White), Visible To and String, Default Visibility); + Start Rule(GameLogicWave0, Do Nothing); + } +} + +disabled rule("=== GAME - MAIN LOGIC ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: DEFEAT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.IsDebug == False; + Global.GateHealth <= 0; + } + + actions + { + Declare Team Victory(Team 2); + } +} + +rule("GLOBAL: TIMER - MAIN GAME LOOP") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + disabled Global.GateHealth > 0; + } + + actions + { + Wait(1, Ignore Condition); + Global.TimeSec += 1; + If(Global.TimeSec == 60); + Global.TimeSec = 0; + Global.TimeMin += 1; + Global.Time5Min = Round To Integer(Global.TimeMin / 5, Down); + Global.Time10Min = Round To Integer(Global.TimeMin / 10, Down); + Global.SpawnPositionMaxId += 1; + disabled Start Rule(GameLogicAddNextHeroInGame, Restart Rule); + Else If(Global.TimeSec == 30); + Global.SpawnPositionMaxId += 1; + End; + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GAME LOGIC - ADD NEXT HERO IN GAME") +{ + event + { + Subroutine; + GameLogicAddNextHeroInGame; + } + + actions + { + "REDUCE RESPAWN TIME FOR ZENS" + disabled Global.ZenRespawnTime -= 1.500; + disabled Global.ZenRespawnTime = Max(1, Global.ZenRespawnTime); + disabled Set Respawn Max Time(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Global.DefaultHeroBotsPool[0]), + Global.ZenRespawnTime); + "ALL HEROES WAS ADDED IN GAME" + Abort If(Global.DefaultHeroBotsPoolCurrentId == Count Of(Global.DefaultHeroBotsPool) - 1); + Global.DefaultHeroBotsPoolCurrentId += 1; + "ВРЕМЕННЫЙ КОСТЫЛЬ ЧТОБЫ ЭХО ЗАМЕНИЛА ХАМСТЕРА" + If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Hero(Echo)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Abort; + End; + "ABORT IF NEXT HERO IN ARRAY ORDER IS NULL" + Abort If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Null); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId], Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("SUBROUTINE: GAME LOGIC - SET BOT PROPERTIES") +{ + event + { + Subroutine; + GameLogicSetBotProperties; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + If(Global.TimeMin >= 10); + If(Filtered Array(Global.lastBoss, Current Array Element == Hero Of(Event Player)) == False); + If(Global.activeBoss == False); + If(Global.bossTrigger < Global.TimeMin); + Global.bossTrigger = Global.TimeMin; + Global.activeBoss = Event Player; + Event Player.isBoss = 1; + Big Message(All Players(Team 1), Custom String("BOSS SPAWNED - {0}", Hero Of(Event Player))); + End; + End; + End; + End; + "PROPERTIES BY DEFAULT" + Set Gravity(Event Player, 100); + Set Damage Dealt(Event Player, 100); + Set Respawn Max Time(Event Player, 10); + Start Scaling Player(Event Player, 1, False); + "INDIVIDUAL HERO'S PROPERTIES" + If(Hero Of(Event Player) == Hero(Zenyatta)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 30); + Set Max Health(Event Player, 5 * (100 + Global.TimeMin * 10)); + Start Scaling Player(Event Player, 1.500, False); + Else; + If(20 + 3 * Number Of Players(Team 1) + 3 * Global.TimeMin > 75); + Set Move Speed(Event Player, 75); + Else; + Set Move Speed(Event Player, 20 + 3 * Count Of(All Players(Team 1)) + 3 * Global.TimeMin); + End; + Set Max Health(Event Player, 100 + Global.TimeMin * 10); + End; + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 20); + Set Max Health(Event Player, 5 * (70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin)); + Start Scaling Player(Event Player, 2, False); + Else; + If(30 + Global.TimeMin + 2.500 * Global.Time5Min > 50); + Set Move Speed(Event Player, 50); + Else; + Set Move Speed(Event Player, 30 + Global.TimeMin + 2.500 * Global.Time5Min); + End; + Set Ultimate Charge(Event Player, 0); + Set Max Health(Event Player, 70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + If(Event Player.isBoss == 1); + Set Damage Dealt(Event Player, 2 * (85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min)); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 5 * (100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin)); + Start Scaling Player(Event Player, 2, False); + Else; + Event Player.BotCounter = 0; + Set Damage Dealt(Event Player, 85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Bastion)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 50); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Start Scaling Player(Event Player, 3, False); + Set Max Health(Event Player, 5 * (155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin)); + Else; + Set Move Speed(Event Player, 80); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Start Scaling Player(Event Player, 2, False); + Set Max Health(Event Player, 155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Orisa)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 5 * (220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min)); + Set Move Speed(Event Player, 30 + 5 * Global.Time5Min); + Else; + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min); + Set Move Speed(Event Player, 90 + 5 * Global.Time5Min); + End; + Else If(Hero Of(Event Player) == Hero(Echo)); + If(Event Player.isBoss == 1); + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 70 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 5 * (90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin)); + Start Scaling Player(Event Player, 2, False); + Else; + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 130 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.500, False); + Set Move Speed(Event Player, 70); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 5 * (55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin)); + Else; + disabled Start Scaling Player(Event Player, 0.850, False); + Set Move Speed(Event Player, 110); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin); + End; + End; + Wait(0.250, Ignore Condition); + "FILL HEALTH" + Heal(Event Player, Null, 100000); + } +} + +disabled rule("=== GATE ===") +{ + event + { + Ongoing - Global; + } +} + +rule("TORB: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Has Spawned(Event Player) == True; + Weapon(Event Player) == 2; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500; + Is Game In Progress == True; + } + + actions + { + Small Message(Event Player, Custom String("REPAIR +2% ULTIMATE")); + "UPGRADE - GATE'S MAX HEALTH" + If(Global.UpgradeGateMaxHealthValue < Global.UpgradeGateMaxHealthMaxValue[1]); + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 100 - Number Of Players(Team 1) * 20; + Else; + Global.UpgradeGateMaxHealthValue += 50 - Number Of Players(Team 1) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 50 - Number Of Players(Team 1) * 10; + Else; + Global.UpgradeGateMaxHealthValue += 25 - Number Of Players(Team 1) * 5; + End; + End; + End; + "HEAL GATE" + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 100 - Number Of Players(Team 1) * 20; + Else; + Global.GateHealth += 50 - Number Of Players(Team 1) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 50 - Number Of Players(Team 1) * 10; + Else; + Global.GateHealth += 25 - Number Of Players(Team 1) * 5; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + "CHARGE ULTIMATE" + Else; + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + End; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(Is Using Ability 2(Event Player) == True ? 0.350 : 0.700, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Brig: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 5; + Is Game In Progress == True; + } + + actions + { + Small Message(Event Player, Custom String("REPAIR +2% ULTIMATE")); + "UPGRADE - GATE'S MAX HEALTH" + If(Global.UpgradeGateMaxHealthValue < Global.UpgradeGateMaxHealthMaxValue[1]); + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 100 - Number Of Players(Team 1) * 20; + Else; + Global.UpgradeGateMaxHealthValue += 50 - Number Of Players(Team 1) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 50 - Number Of Players(Team 1) * 10; + Else; + Global.UpgradeGateMaxHealthValue += 25 - Number Of Players(Team 1) * 5; + End; + End; + End; + "HEAL GATE" + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 100 - Number Of Players(Team 1) * 20; + Else; + Global.GateHealth += 50 - Number Of Players(Team 1) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 50 - Number Of Players(Team 1) * 10; + Else; + Global.GateHealth += 25 - Number Of Players(Team 1) * 5; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + "CHARGE ULTIMATE" + Else; + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + End; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Rein: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + Is Game In Progress == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Small Message(Event Player, Custom String("REPAIR +2% ULTIMATE")); + "UPGRADE - GATE'S MAX HEALTH" + If(Global.UpgradeGateMaxHealthValue < Global.UpgradeGateMaxHealthMaxValue[1]); + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 100 - Number Of Players(Team 1) * 20; + Else; + Global.UpgradeGateMaxHealthValue += 50 - Number Of Players(Team 1) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 50 - Number Of Players(Team 1) * 10; + Else; + Global.UpgradeGateMaxHealthValue += 25 - Number Of Players(Team 1) * 5; + End; + End; + End; + "HEAL GATE" + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 100 - Number Of Players(Team 1) * 20; + Else; + Global.GateHealth += 50 - Number Of Players(Team 1) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 50 - Number Of Players(Team 1) * 10; + Else; + Global.GateHealth += 25 - Number Of Players(Team 1) * 5; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + "CHARGE ULTIMATE" + Else; + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + End; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.850, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GATE PROGRESS BAR COLOR") +{ + event + { + Subroutine; + GateProgressBarColor; + } + + actions + { + Stop Chasing Global Variable(GateHealthChase); + Chase Global Variable Over Time(GateHealthChase, Global.GateHealth, 0.100, Destination and Duration); + "GATE WAS DAMAGED" + If(Global.GateHealth < Global.GateHealthEvent); + For Global Variable(LoopIterator1, 0, 3, 1); + Global.GateProgressBarColorCurrent = Color(Red); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(White); + Wait(0.030, Ignore Condition); + End; + "GATE WAS REPAIRED" + Else; + Global.GateProgressBarColorCurrent = Color(Green); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(Yellow); + Wait(0.030, Ignore Condition); + End; + Global.GateHealthEvent = Global.GateHealth; + Global.GateProgressBarColorComponent = Global.GateHealth * 255 / Global.GateMaxHealth; + Global.GateProgressBarColorCurrent = Custom Color(255, Global.GateProgressBarColorComponent, Global.GateProgressBarColorComponent, + 255); + } +} + +disabled rule("=== COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("ALL: INIT") +{ + event + { + Player Joined Match; + All; + All; + } + + actions + { + "ALL (COMMON) INIT" + Event Player.IsDead = True; + Disable Kill Feed(Event Player); + Disable Game Mode In-World UI(Event Player); + Disable Death Spectate Target HUD(Event Player); + "BOT INIT" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotInit); + "PLAYER INIT" + Else; + Call Subroutine(PlayerInit); + End; + } +} + +rule("SUBROUTINE: BOT - INIT") +{ + event + { + Subroutine; + BotInit; + } + + actions + { + "INIT VARS" + Event Player.HasBadStatus = False; + Event Player.IsRespawning = False; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEventPosition = Vector(9999, 999, 9999); + "DISABLE ALL FOR BOT" + Disable Hero HUD(Event Player); + Disable Messages(Event Player); + Disable Text Chat(Event Player); + Disable Scoreboard(Event Player); + Disable Game Mode HUD(Event Player); + Disable Death Spectate All Players(Event Player); + Disable Voice Chat(Event Player, True, True, True); + "INIT AI NAVIGATION VARS" + Call Subroutine(BotResetPathFinding); + } +} + +rule("SUBROUTINE: PLAYER - INIT") +{ + event + { + Subroutine; + PlayerInit; + } + + actions + { + "STORY HEROES" + If(Global.IsStoryHeroes); + Reset Player Hero Availability(Event Player); + Set Player Allowed Heroes(Event Player, Array(Hero(Ana), Hero(Brigitte), Hero(Mercy), Hero(Lúcio), Hero(Moira), Hero(Baptiste), + Hero(Ashe), Hero(D.Va), Hero(Genji), Hero(Hanzo), Hero(Widowmaker), Hero(Cassidy), Hero(Reinhardt), Hero(Soldier: 76), Hero( + Torbjörn), Hero(Tracer), Hero(Winston), Hero(Pharah))); + End; + "TEAM CHALLENGE - PLAYER'S MAX HEALTH" + If(Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0] && Max Health(Event Player) + != Global.UpgradePlayerMaxHealthNewValue); + Set Max Health(Event Player, Global.UpgradePlayerMaxHealthNewValue); + End; + If(Is Game In Progress); + Disable Game Mode HUD(Event Player); + End; + } +} + +rule("ALL: RESPAWN") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + (Hero Of(Event Player) != Event Player.CurrentHero || Event Player.IsDead == True) == True; + } + + actions + { + Event Player.IsDead = False; + "BOT RESPAWN" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotRespawn); + If(Global.IsDebugAINavigation); + Create Beam Effect(All Players(All Teams), Good Beam, Eye Position(Event Player), Event Player.BotNextNodePosition, Color(Green), + Visible To Position and Radius); + End; + "PLAYER RESPAWN" + Else; + Call Subroutine(PlayerRespawn); + End; + "MUST BE AFTER ALL RESPAWN SUBROUTINES!" + Event Player.CurrentHero = Hero Of(Event Player); + } +} + +rule("SUBROUTINE: BOT - RESPAWN") +{ + event + { + Subroutine; + BotRespawn; + } + + actions + { + "RESET COMMON PROPERTIES" + Event Player.IsRespawning = True; + Enable Nameplates(Event Player, All Players(Team 1)); + Call Subroutine(BotResetPathFinding); + disabled If(Hero Of(Event Player) != Event Player.CurrentHero); + Call Subroutine(GameLogicSetBotProperties); + disabled End; + "INDIVIDUAL HERO'S RESPAWN SCRIPTS" + If(Hero Of(Event Player) == Hero(Bastion)); + Call Subroutine(BotBastionRespawn); + Else If(Hero Of(Event Player) == Hero(Zenyatta)); + Call Subroutine(BotZenyattaRespawn); + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + Call Subroutine(BotWidowRespawn); + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Call Subroutine(BotBallRespawn); + Else If(Hero Of(Event Player) == Hero(Orisa)); + Call Subroutine(BotOrisaRespawn); + Else If(Hero Of(Event Player) == Hero(Echo)); + Call Subroutine(BotEchoRespawn); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Call Subroutine(BotReinRespawn); + End; + Event Player.IsRespawning = False; + } +} + +rule("SUBROUTINE: PLAYER - RESPAWN") +{ + event + { + Subroutine; + PlayerRespawn; + } + + actions + { + "TEAM CHALLENGE - MAX AMMO" + If(Hero Of(Event Player) != Event Player.CurrentHero && Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]); + Set Max Ammo(Event Player, 0, Ammo(Event Player, 0) * 2); + Set Max Ammo(Event Player, 1, Ammo(Event Player, 1) * 2); + Set Ammo(Event Player, 0, Max Ammo(Event Player, 0)); + Set Ammo(Event Player, 1, Max Ammo(Event Player, 1)); + End; + "MUST BE AFTER TEAM CHALLENGE MAX AMMO!" + disabled Event Player.CurrentHero = Hero Of(Event Player); + "PLAYER RESPAWN" + Set Status(Event Player, Null, Phased Out, 3); + Set Facing(Event Player, Vector(-1, 0, 0), To World); + Teleport(Event Player, Global.PlayerSpawnPositions[Slot Of(Event Player) == Count Of(Global.PlayerSpawnPositions) ? Random Integer( + 0, Count Of(Global.PlayerSpawnPositions) - 1) : Slot Of(Event Player)]); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + } +} + +rule("PLAYER: DEATH") +{ + event + { + Player Died; + Team 1; + All; + } + + actions + { + Event Player.IsDead = True; + } +} + +rule("BOT: DEATH") +{ + event + { + Player Died; + Team 2; + All; + } + + actions + { + If(Event Player.isBoss == 1); + Event Player.isBoss = 0; + Global.activeBoss = Null; + Big Message(All Players(Team 1), Custom String("BOSS DIED - {0}", Hero Of(Event Player))); + End; + Event Player.IsDead = True; + Event Player.HasBadStatus = False; + Event Player.BotDoesUniqueBehaviour = False; + Disable Nameplates(Event Player, All Players(Team 1)); + disabled Stop Holding Button(Event Player, Button(Ability 1)); + disabled Stop Holding Button(Event Player, Button(Primary Fire)); + disabled Stop Holding Button(Event Player, Button(Secondary Fire)); + "BOT HAS 1 EFFECT IN VAR (NOT ARRAY)" + Skip If(!Entity Exists(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects); + "BOT HAS MORE THEN 1 EFFECT IN VAR (ARRAY)" + Skip If(Count Of(Event Player.BotEffects) == 0, 3); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects[Event Player.BotLoopIterator1]); + End; + } +} + +disabled rule("=== BOT COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BAD STATUS") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + Event Player.HasBadStatus = True; + "PROCESS BAD STATUS" + If(Hero Of(Event Player) == Hero(Widowmaker)); + Start Rule(BotWidowBadStatus, Do Nothing); + End; + Wait Until(!Has Status(Event Player, Knocked Down) && !Has Status(Event Player, Asleep) && !Has Status(Event Player, Frozen) + && !Has Status(Event Player, Stunned), 15); + Event Player.HasBadStatus = False; + } +} + +rule("SUBROUTINE: BOT - LANDING FROM SKY") +{ + event + { + Subroutine; + BotLandingFromSky; + } + + actions + { + Stop Throttle In Direction(Event Player); + "SET RESPAWN POSITION" + Event Player.BotEventPosition = Random Value In Array(Global.BigBossSpawnPositions); + "CREATE EFFECTS" + disabled Create Effect(All Players(All Teams), Light Shaft, Color(Red), Event Player.BotEventPosition, 3, Visible To); + disabled Event Player.BotEffects = Last Created Entity; + "RESPAWN IN LIGHT SHAFT EFFECT" + Teleport(Event Player, Event Player.BotEventPosition + Vector(0, 25, 0)); + Wait(0.020, Ignore Condition); + "SLOW LANDING" + Set Gravity(Event Player, 50); + While(Is In Air(Event Player) == True); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Position Of(Event Player) + Vector(0, -2.700, 0), 2); + Wait(0.250, Ignore Condition); + End; + Set Gravity(Event Player, 100); + disabled Destroy Effect(Event Player.BotEffects); + "LANDING EFFECTS" + Play Effect(All Players(All Teams), Wrecking Ball Piledriver Impact Effect, Custom Color(105, 87, 46, 255), Position Of( + Event Player), 8); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Sound, Color(White), Position Of(Event Player), 150); + } +} + +rule("SUBROUTINE: BOT - APPEAR FROM UNDERGROUND") +{ + event + { + Subroutine; + BotApearFromUnderground; + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1); + Wait(0.200, Ignore Condition); + Set Gravity(Event Player, 20); + Disable Movement Collision With Environment(Event Player, True); + Teleport(Event Player, Global.ZenSpawnPositions[Random Integer(Min(Global.TimeMin, Count Of(Global.ZenSpawnPositions) - 10), Min( + Global.SpawnPositionMaxId, Count Of(Global.ZenSpawnPositions) - 4))] + Vector(0, -1.500, 0)); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Sigma Accretion Impact Effect, Custom Color(220, 175, 100, 255), Eye Position(Event Player), + 3); + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(Gray), Eye Position(Event Player), 50); + Apply Impulse(Event Player, Up, 3.500, To World, Cancel Contrary Motion); + Wait(0.400, Ignore Condition); + Clear Status(Event Player, Knocked Down); + Set Gravity(Event Player, 100); + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("=== PLAYER MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("PLAYER: DARKNESS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + !Entity Exists(Event Player.BotEffects) == True; + } + + actions + { + Disable Nameplates(Event Player, All Players(All Teams)); + Start Forcing Player Outlines(Event Player, All Players(All Teams), False, Color(White), Default); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 14), 25, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(-5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + } +} + +rule("PLAYER: HEALTH REGEN") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + actions + { + Stop Heal Over Time(Event Player.HealOverTimeId); + Event Player.EventHealth = Health(Event Player); + Wait(4, Ignore Condition); + "TOOK DAMAGE, RESET REGENERATION TIMER" + Loop If(Is Alive(Event Player) && Event Player.EventHealth > Health(Event Player)); + Start Heal Over Time(Event Player, Null, 3, Max Health(Event Player) / 3); + Event Player.HealOverTimeId = Last Heal Over Time ID; + } +} + +disabled rule("=== NERFS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("REINHARDT: ANTI-CHARGE FOR BASTION & ORISA") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Using Ability 1(Event Player) == True; + Hero Of(Ray Cast Hit Player(Eye Position(Event Player) + Vector(0, 2, 0), Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 2, All Living Players(Team 2), Event Player, True)) == (Hero(Bastion) == True || Hero( + Orisa) == True); + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1.500); + } +} + +rule("HOG: ANTI-HOOK FOR BASTION & ORISA") +{ + event + { + Player Dealt Damage; + Team 1; + Roadhog; + } + + conditions + { + Event Ability == Button(Ability 1); + (Hero Of(Victim) == Hero(Bastion) || Hero Of(Victim) == Hero(Orisa)) == True; + } + + actions + { + Set Status(Event Player, Null, Stunned, 0.005); + } +} + +disabled rule("=== ZENYATTA ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ZEN - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Zenyatta; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + } + + actions + { + Set Ammo(Event Player, 0, 0); + Communicate(Event Player, Hello); + disabled Call Subroutine(BotResetPathFinding); + Wait(1.500, Ignore Condition); + Abort If(Is Dead(Event Player) == True); + Kill(Event Player, Null); + } +} + +rule("BOT: ZEN - DEATH") +{ + event + { + Player Died; + Team 2; + Zenyatta; + } + + actions + { + "EFFECT" + Play Effect(All Players(All Teams), Junkrat Frag Launcher Explosion Effect, Color(Red), Eye Position(Event Player), 2.500); + Play Effect(All Players(All Teams), Ashe Dynamite Explosion Sound, Color(Red), Eye Position(Event Player), 70); + "DAMAGE AND APPLY IMPULSE TO PLAYERS" + Event Player.BotPlayersInRadius = Players Within Radius(Position Of(Event Player), 2.500, All Teams, Surfaces And Enemy Barriers); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotPlayersInRadius), 1); + Apply Impulse(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Direction Towards(Position Of(Event Player), + Eye Position(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1])), 5, To World, Incorporate Contrary Motion); + If(Team Of(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1]) == Team 1); + Damage(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Event Player, 50); + End; + End; + "DAMAGE GATE" + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 125; + Else; + Global.GateHealth -= 25; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Respawn(Event Player); + Abort; + End; + "KILLED BY PLAYER" + Teleport(Event Player, Vector(0, -999, 0)); + Wait(2, Ignore Condition); + Respawn(Event Player); + Wait(2, Ignore Condition); + } +} + +rule("SUBROUTINE: ZEN - RESPAWN") +{ + event + { + Subroutine; + BotZenyattaRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WRECKING BALL ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BALL - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + disabled Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Set Ammo(Event Player, 0, 0); + Wait(1, Ignore Condition); + Set Ultimate Charge(Event Player, 100); + Start Holding Button(Event Player, Button(Ultimate)); + Wait Until(Is Using Ultimate(Event Player), 0.600); + Abort If(Is Dead(Event Player)); + Kill(Event Player, Null); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Effect, Color(Orange), Eye Position(Event Player), 6); + Play Effect(All Players(All Teams), DVa Self Destruct Explosion Sound, Color(White), Eye Position(Event Player), 250); + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 300; + Else; + Global.GateHealth -= 150; + End; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Damage(Players Within Radius(Eye Position(Event Player), 7, Team 1, Surfaces And All Barriers), Event Player, 200); + } +} + +rule("BOT: BALL - ALTERNATIVE FORM") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is In Alternate Form(Event Player) == False; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is In Alternate Form(Event Player), 10); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: BALL - DEATH") +{ + event + { + Player Died; + Team 2; + Wrecking Ball; + } + + actions + { + Stop Holding Button(Event Player, Button(Ability 1)); + Stop Holding Button(Event Player, Button(Ultimate)); + } +} + +rule("SUBROUTINE: BALL - RESPAWN") +{ + event + { + Subroutine; + BotBallRespawn; + } + + actions + { + "RESPAWN IN AIR" + Teleport(Event Player, Random Value In Array(Global.BallSpawnPositions) + Vector(0, 20, 0)); + Stop Holding Button(Event Player, Button(Ultimate)); + Wait(0.250, Ignore Condition); + "LANDING" + Start Holding Button(Event Player, Button(Crouch)); + Wait Until(Is On Ground(Event Player), 9999); + Stop Holding Button(Event Player, Button(Crouch)); + "LANDING IMPACT EFFECT" + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(White), Event Player, 150); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Effect, Color(Gray), Position Of(Event Player), 10); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Eye Position(Event Player), 1.500, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + "PATH FINDING TO GATE" + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +disabled rule("=== ECHO ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ECHO - FLY ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is Using Ability 1(Event Player) == False; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), 0); + Press Button(Event Player, Button(Ability 1)); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - BEAM ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Using Ability 1(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == True; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - BAD STATUS - RESET BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.HasBadStatus == True; + disabled (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + Wait Until(Event Player.HasBadStatus, 7); + } +} + +rule("BOT: ECHO - CAN'T SEE PORTAL - APPLY IMPULSE") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == True; + Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Wait(0.300, Abort When False); + Apply Impulse(Event Player, Vector(Random Integer(-1, 1), 1, Random Integer(-1, 1)), 20, To World, Incorporate Contrary Motion); + Wait(1, Ignore Condition); + If(!Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + Event Player.BotTargetPosition = Global.BotEchoRespawnPosition; + Start Rule(BotStartPathFinding, Restart Rule); + Else; + Call Subroutine(BotResetPathFinding); + End; + Loop If Condition Is True; + } +} + +disabled rule("BOT: ECHO - MAIN LOGIC - BACKUP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(!Event Player.BotIsPathFinding); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Is In Line of Sight(Eye Position(Event Player), + Eye Position(Current Array Element), Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), + Position Of(Current Array Element)))[0]; + End; + "NO PLAYERS IN VIEW RANGE" + disabled If(Event Player.BotSeePlayer == Null); + disabled Stop Throttle In Direction(Event Player); + disabled End; + "FLY TO PLAYER" + If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + > 4 && Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + "ACTIVATE FOCUS BEAM" + Else If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + < 4 && Event Player.BotDoesUniqueBehaviour == False && Event Player.HasBadStatus == False); + Event Player.BotDoesUniqueBehaviour = True; + Set Status(Event Player.BotSeePlayer, Event Player, Stunned, 1); + Set Status(Event Player.BotSeePlayer, Event Player, Hacked, 99999); + Attach Players(Event Player.BotSeePlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + "TELEPORT PLAYER TO AWAY" + Else If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotSeePlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotSeePlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotSeePlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + "BEGIN TO FLY TO THE PORTAL" + Else If(Event Player.BotDoesUniqueBehaviour == True); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + End; + "TELEPORT PLAYER SO FAR" + If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotEchoCapturedPlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotEchoCapturedPlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + End; + "BEGIN TO FLY TO THE PORTAL WITH A PLAYER" + If(Event Player.BotDoesUniqueBehaviour); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotEchoCapturedPlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - DEFEND PORTAL") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + } + + actions + { + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPlayer); + } +} + +rule("BOT: ECHO - PATH FINDING TO PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Call Subroutine(BotStartPathFinding); + } +} + +rule("BOT: ECHO - ATTACH PLAYER BY BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotEchoCapturedPlayer == Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 3; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Event Player.BotEchoCapturedPlayer = Event Player.BotSeePlayer; + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Stunned, 0.700); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Hacked, 10); + Attach Players(Event Player.BotEchoCapturedPlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - PLAYER DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Dead(Event Player.BotEchoCapturedPlayer) != Null; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - DEATH") +{ + event + { + Player Died; + Team 2; + Echo; + } + + actions + { + Call Subroutine(BotEchoDetachPlayer); + Stop Holding Button(Event Player, Button(Jump)); + Wait(5, Ignore Condition); + Teleport(Event Player, Vector(0, 999, 0)); + Start Forcing Player To Be Hero(Event Player, Hero(Orisa)); + } +} + +rule("SUBROUTINE: ECHO - RESPAWN") +{ + event + { + Subroutine; + BotEchoRespawn; + } + + actions + { + Event Player.BotCounter = 0; + Event Player.BotEffects = Empty Array; + Create Effect(All Players(All Teams), Good Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Energy Sound, Color(White), Global.BotEchoRespawnPosition, 200, Visible To); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Chase Player Variable Over Time(Event Player, BotCounter, 3, 0.800, Destination and Duration); + Play Effect(All Players(All Teams), Sombra EMP Explosion Effect, Color(Sky Blue), Global.BotEchoRespawnPosition, 12); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Null, Global.BotEchoRespawnPosition, 100); + Wait(3, Ignore Condition); + Teleport(Event Player, Global.BotEchoRespawnPosition); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Global.BotEchoRespawnPosition, 2.500); + Play Effect(All Players(All Teams), Debuff Impact Sound, Null, Global.BotEchoRespawnPosition, 100); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PLAYER") +{ + event + { + Subroutine; + BotEchoFlyToPlayer; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Stop Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PORTAL") +{ + event + { + Subroutine; + BotEchoFlyToPortal; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - DETACH PLAYER") +{ + event + { + Subroutine; + BotEchoDetachPlayer; + } + + actions + { + Detach Players(Event Player.BotEchoCapturedPlayer); + Clear Status(Event Player.BotEchoCapturedPlayer, Hacked); + "IF PLAYER INSIDE THE WALL" + If(Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotEchoCapturedPlayer), Barriers Do Not Block LOS)); + Teleport(Event Player.BotEchoCapturedPlayer, Position Of(Event Player)); + End; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEchoCapturedPlayer = Null; + } +} + +disabled rule("=== REINHARDT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: REIN - SET PLAYER AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + disabled Event Player.BotIsPathFinding == False; + "BOT IS FAR FROM GATES" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Global.GatePosition), 0, Z Component Of(Global.GatePosition))) > 20; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET CLOSEST PLAYER TO BOT AS TARGET AND FOLLOW HIM" + Event Player.BotTargetPlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - SET GATE AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "BOT DOESN'T FOLLOW PLAYER" + Event Player.BotTargetPlayer == -1; + "CAN'T SEE ANY PLAYER" + disabled Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), !Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET GATE AS TARGET" + Event Player.BotTargetPosition = Global.GatePosition; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - TARGET DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer != -1; + Is Dead(Event Player.BotTargetPlayer) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + } +} + +rule("BOT: REIN - ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) < 4; + "CAN ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) < 4; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + "TARGET IS PLAYER" + Abort If(Event Player.BotTargetPlayer != -1); + If(Event Player.isBoss == 1); + "TARGET IS GATE" + Global.GateHealth -= 25; + Else; + Global.GateHealth -= 5; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: REIN - STOP ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) > 4; + "CAN'T ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) > 4; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + } +} + +rule("BOT: REIN - USE SHIELD") +{ + event + { + Player Took Damage; + Team 2; + Reinhardt; + } + + conditions + { + Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) > 3; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Attacker)), 200, To World, + Direction and Turn Rate); + Start Holding Button(Event Player, Button(Secondary Fire)); + Wait Until(Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) < 3, 3); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("BOT: REIN - CHARGE IN GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer == -1; + Is Using Ability 1(Event Player) == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == True; + Is In View Angle(Event Player, Global.GatePosition, 7.500) == True; + } + + actions + { + disabled Wait(0.800, Abort When False); + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is Using Ability 1(Event Player), 1); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: REIN - DEATH") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("SUBROUTINE: REIN - RESPAWN") +{ + event + { + Subroutine; + BotReinRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WIDOW ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: WIDOW - SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer == Null; + Event Player.HasBadStatus == False; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Event Player.BotWidowShotTime = Total Time Elapsed + (Global.TimeMin >= 9 ? Random Real(2, 5) : Random Real(5, 10)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 9999, To World, + Direction and Turn Rate); + } +} + +rule("BOT: WIDOW - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer != Null; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowShotTime; + } + + actions + { + Press Button(Event Player, Button(Primary Fire)); + Stop Facing(Event Player); + Event Player.BotSeePlayer = Null; + } +} + +rule("BOT: WIDOW - Aim Sound") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Alive(Event Player) == True; + Is In Line of Sight(Eye Position(Players On Hero(Hero(Widowmaker), Team 2)), Eye Position(Event Player), Barriers Do Not Block LOS) + == True; + Is Alive(Players On Hero(Hero(Widowmaker), Team 2)) == True; + Players On Hero(Hero(Widowmaker), Team 2).BotSeePlayer == True; + } + + actions + { + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 100); + Wait(1, Abort When False); + Loop If Condition Is True; + } +} + +rule("BOT: WIDOW - TELEPORT TO NEW POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowTeleportTime; + } + + actions + { + Event Player.BotWidowTeleportTime = Total Time Elapsed + 28; + Event Player.BotWidowShotTime = Total Time Elapsed + Random Real(1, 1.600); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Event Player, 1); + Wait(0.016, Ignore Condition); + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + } +} + +rule("BOT: WIDOW - DEATH") +{ + event + { + Player Died; + Team 2; + Widowmaker; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + Wait(0.250, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - RESPAWN") +{ + event + { + Subroutine; + BotWidowRespawn; + } + + actions + { + "RESPAWN ON RANDOM SNIPER POSITION" + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Wait(0.700, Ignore Condition); + Start Holding Button(Event Player, Button(Secondary Fire)); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait Until(Is Dead(Event Player), 99999); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - BAD STATUS") +{ + event + { + Subroutine; + BotWidowBadStatus; + } + + actions + { + Stop Facing(Event Player); + Destroy Effect(Event Player.BotEffects); + Wait Until(!Event Player.HasBadStatus, 15); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + } +} + +disabled rule("=== BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("BOT: BASTION - FLAME GUN") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 50) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 8; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Stop Holding Button(Event Player, Button(Primary Fire)); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Update Every Frame(Eye Position(Event Player) + World Vector Of( + Vector(-1, -1.200, 1.800), Event Player, Rotation)), 1, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Start Rule(BotBastionFlameGunDamage, Do Nothing); + Wait(1.100, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(4, Ignore Condition); + Loop If Condition Is True; + } +} + +disabled rule("BOT: BASTION - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + disabled Event Player.BotSeePlayer == Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - CAN'T SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == False; + } + + actions + { + Event Player.BotSeePlayer = Null; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - MOVE TO BASTION'S TARGET (POSITION)") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotTargetPosition = Random Value In Array(Filtered Array(Global.BastionTargetPositions, Distance Between(Position Of( + Event Player), Current Array Element) > 3.500)); + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("BOT: BASTION - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + "SEE THE PLAYER" + If(Event Player.BotSeePlayer != Null); + Stop Holding Button(Event Player, Button(Secondary Fire)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer) - Vector(0, 0.500, + 0)), 100, To World, Direction and Turn Rate); + "SELF REPAIRING" + Else If(!Is Firing Secondary(Event Player) && Health(Event Player) < Max Health(Event Player)); + Start Holding Button(Event Player, Button(Secondary Fire)); + End; + "START FOLLOW PATH" + disabled If(!Event Player.BotIsPathFinding && !Event Player.BotDoesUniqueBehaviour); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled Wait(0.050, Ignore Condition); + disabled Event Player.BotTargetPosition = Random Value In Array(Global.BastionTargetPositions); + disabled Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Event Player.BotTargetPosition + Vector(0, 2, 0)), 100, + To World, Direction and Turn Rate); + disabled Start Rule(BotStartPathFinding, Do Nothing); + "REACHED PATH TARGET" + disabled Else If(Distance Between(Position Of(Event Player), Event Player.BotTargetPosition) <= 3); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled End; + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - ARTILLERY") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 30) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) > 18; + Distance Between(Eye Position(Event Player), Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Up * 99, Null, Event Player, False)) >= 35; + } + + actions + { + "TRYING TO CAPTURE TARGET" + Wait(0.800, Abort When False); + "CAPTURE TARGET" + Event Player.BotDoesUniqueBehaviour = True; + Stop Throttle In Direction(Event Player); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Update Every Frame(Eye Position(Event Player)), + Update Every Frame(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 1000, All Living Players(Team 1), Event Player, True)), Color(Sky Blue), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait(1.400, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Event Player.BotEventPosition = Position Of(Event Player.BotSeePlayer); + "SHOOT FROM ARTILLERY" + Event Player.BotBastionArtilleryDidShotsCount = 0; + For Player Variable(Event Player, BotLoopIterator1, 0, 4, 1); + Event Player.BotBastionArtilleryDidShotsCount += 1; + Play Effect(All Players(All Teams), Wrecking Ball Minefield Explosion Sound, Color(White), Eye Position(Event Player), 250); + Play Effect(All Players(All Teams), Pharah Barrage Explosion Effect, Color(Orange), Eye Position(Event Player) + World Vector Of( + Vector(0, 1.400, -0.700), Event Player, Rotation), 2); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) + World Vector Of(Vector(0, 1.400, + -0.700), Event Player, Rotation), Eye Position(Event Player) + World Vector Of(Vector(Random Real(-1, 1), Random Integer(40, + 80), Random Real(0.500, 1.500)), Event Player, Rotation), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + If(Is Dead(Event Player)); + Break; + End; + End; + disabled Call Subroutine(BotResetPathFinding); + disabled Start Rule(BotStartPathFinding, Do Nothing); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Wait(1.500, Ignore Condition); + Start Rule(BotBastionArtilleryDamage, Do Nothing); + Wait(4, Ignore Condition); + } +} + +rule("BOT: BASTION - PRIMARY FIRE") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 40) == True; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Stop Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Bastion; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + For Player Variable(Event Player, BotLoopIterator1, 0, 3, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Effect, Color(White), Event Player, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player, 100); + Wait(0.250, Ignore Condition); + End; + } +} + +rule("SUBROUTINE: BASTION - RESPAWN") +{ + event + { + Subroutine; + BotBastionRespawn; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + Call Subroutine(BotLandingFromSky); + Set Ammo(Event Player, 0, 0); + Wait Until(!Is Reloading(Event Player), 99999); + Event Player.BotTargetPosition = Objective Position(2); + } +} + +rule("SUBROUTINE: BASTION - ARTILLERY DAMAGE") +{ + event + { + Subroutine; + BotBastionArtilleryDamage; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = False; + "EXPLOSIONS OF ARTILLERY" + For Player Variable(Event Player, BotLoopIterator2, 0, Event Player.BotBastionArtilleryDidShotsCount, 1); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotEventPosition + Vector(0, 50, 0), + Event Player.BotEventPosition + Vector(Random Integer(-4, 4), -15, Random Integer(-4, 4)), Null, Event Player, True); + Damage(Players Within Radius(Event Player.BotEventPosition, 8, Team 1, Surfaces And Enemy Barriers), Event Player, 50); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Pharah Rocket Launcher Explosion Effect, Color(Orange), Event Player.BotEventPosition, 5); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Event Player.BotEventPosition, + Event Player.BotEventPosition + Vector(0, 60, 0), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + End; + } +} + +disabled rule("SUBROUTINE: BASTION - FLAME GUN DAMAGE") +{ + event + { + Subroutine; + BotBastionFlameGunDamage; + } + + actions + { + Event Player.BotRayCastHitPosition = Eye Position(Event Player) + World Vector Of(Vector(-1, -1.200, 1.800), Event Player, + Rotation); + "FIRE PARTICLES OF FLAME GUN" + For Player Variable(Event Player, BotLoopIterator1, 1, 13, 3); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotRayCastHitPosition, + Event Player.BotRayCastHitPosition + Facing Direction Of(Event Player) * Event Player.BotLoopIterator1, Null, Event Player, + True); + Damage(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Surfaces And Enemy Barriers), Event Player, 20); + Set Status(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Off), Event Player, Burning, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.BotEventPosition, 2.500); + Wait(0.200, Ignore Condition); + End; + Event Player.BotDoesUniqueBehaviour = False; + } +} + +disabled rule("=== ORISA + BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ORISA-BASTION - REACHED TARGET POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotIsPathFinding == True; + Distance Between(Position Of(Event Player), Global.BotOrisaTargetPosition) < 1.500; + } + + actions + { + Call Subroutine(BotResetPathFinding); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Vector(X Component Of(Global.GatePosition), -999, + Z Component Of(Global.GatePosition))), 80, To World, Direction and Turn Rate); + Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + disabled Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element) && Is In Line of Sight(Eye Position(Event Player), Position Of(Current Array Element), + Barriers Do Not Block LOS)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + Press Button(Event Player, Button(Ability 1)); + Wait Until(Y Component Of(Facing Direction Of(Event Player)) < -0.300, 99999); + Press Button(Event Player, Button(Ability 2)); + Wait(0.800, Ignore Condition); + Global.BotOrisaChild.BotDoesUniqueBehaviour = False; + Disallow Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ORISA-BASTION - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + While(Is Alive(Event Player)); + disabled Create Effect(All Players(All Teams), Bad Aura, Color(Purple), Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3.200, 1, Visible To Position and Radius); + disabled Event Player.BotEffects = Last Created Entity; + Wait(1.500, Ignore Condition); + disabled Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Press Button(Event Player, Button(Primary Fire)); + Press Button(Event Player, Button(Reload)); + Event Player.BotRayCastHitPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Facing Direction Of(Event Player) * 999, All Players(Team 1), All Players(Team 2), True); + "ANTI-SHIELD BUG" + Event Player.BotRayCastHitPosition = Event Player.BotRayCastHitPosition + Direction Towards(Event Player.BotRayCastHitPosition, + Eye Position(Event Player)) * 0.200; + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3, Event Player.BotRayCastHitPosition, Color(Purple), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Damage(Players Within Radius(Event Player.BotRayCastHitPosition, 4, Team 1, Surfaces And All Barriers), Event Player, 0.040); + Play Effect(All Players(All Teams), Pharah Concussive Blast Effect, Color(Purple), Event Player.BotRayCastHitPosition, 4); + Play Effect(All Players(All Teams), Pharah Concussive Blast Sound, Color(Purple), Event Player.BotRayCastHitPosition, 250); + Play Effect(All Players(All Teams), Bad Explosion, Color(Purple), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 3.300, 2); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Color(Purple), Eye Position(Event Player), 170); + If(Distance Between(Event Player.BotRayCastHitPosition, Global.GatePosition) < 4 && Is In Line of Sight( + Event Player.BotRayCastHitPosition, Global.GatePosition, Enemy Barriers Block LOS)); + Global.GateHealth -= 80; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Wait(0.150, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.060, Ignore Condition); + Wait Until(!Is Reloading(Event Player), 2.500); + End; + } +} + +rule("BOT: ORISA-BASTION - CAN'T SEE THE TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: ORISA-BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Orisa; + } + + actions + { + Allow Button(Event Player, Button(Ability 2)); + Kill(Global.BotOrisaChild, Null); + Detach Players(Global.BotOrisaChild); + Clear Status(Global.BotOrisaChild, Phased Out); + Set Damage Dealt(Global.BotOrisaChild, 100); + Global.BotOrisaChild.BotIsOrisaChild = False; + Global.BotOrisaChild = Null; + Global.BotOrisaParent = Null; + Start Forcing Player To Be Hero(Event Player, Hero(Widowmaker)); + } +} + +rule("SUBROUTINE: ORISA - RESPAWN") +{ + event + { + Subroutine; + BotOrisaRespawn; + } + + actions + { + Global.BotOrisaParent = Event Player; + "WAITING FOR ANY BASTION TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero(Bastion)), + 99999); + "SETUP BASTION AS CHILD" + Global.BotOrisaChild = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Bastion))[0]; + Global.BotOrisaChild.BotIsOrisaChild = True; + Global.BotOrisaChild.BotDoesUniqueBehaviour = True; + Wait(2, Ignore Condition); + Respawn(Global.BotOrisaChild); + Start Scaling Player(Global.BotOrisaChild, 1.800, False); + Set Damage Dealt(Global.BotOrisaChild, 2000); + Set Status(Global.BotOrisaChild, Null, Phased Out, 9999); + Disable Nameplates(Global.BotOrisaChild, All Players(All Teams)); + Set Facing(Global.BotOrisaChild, Vector(X Component Of(Facing Direction Of(Event Player)), 9999, Z Component Of( + Facing Direction Of(Event Player))), To World); + Start Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Wait Until(Is In Alternate Form(Global.BotOrisaChild), 5); + Stop Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Teleport(Global.BotOrisaChild, Position Of(Event Player)); + Attach Players(Global.BotOrisaChild, Global.BotOrisaParent, Vector(0, 1.800, 0.230)); + disabled Wait(1, Ignore Condition); + disabled Stop Holding Button(Global.BotOrisaChild, Button(Primary Fire)); + disabled Wait(0.250, Ignore Condition); + Call Subroutine(BotLandingFromSky); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 0 - ZENS, REINS, BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 0; + } + + actions + { + "CREATE BOTS - ZEN" + While(Count Of(All Players(Team 2)) < 15); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "BALL" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "REPLACE DEAD ZEN TO REIN" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) != 3); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 1 - WIDOW") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 1; + } + + actions + { + Global.IsNewWaveGameLogicProcessing = True; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Global.IsNewWaveGameLogicProcessing = False; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 3 - BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 3; + } + + actions + { + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 5 - REINS WAVE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 5; + } + + actions + { + "PREPARE WAVE - DESTROY WIDOW AND BALLS" + Destroy Dummy Bot(Team 2, Slot Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))[0])); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))[0]; + Kill(Global.DefaultCurrentBot, Null); + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + "BOSS WAVE" + Big Message(All Players(All Teams), Custom String("BOSS WAVE - {1} {0}", Hero Icon String(Hero(Reinhardt)), Hero(Reinhardt))); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) < 6); + Wait Until(Is True For Any(All Players(Team 2), Distance Between(Position Of(Current Array Element), Global.GatePosition) + > 15 && Hero Of(Current Array Element) == Hero(Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + disabled Wait(0.200, Ignore Condition); + disabled Set Max Health(Global.DefaultCurrentBot, 50); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) > 3); + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Reinhardt)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Reinhardt))[0]; + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(All Players(Team 2)) < 15); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Big Message(All Players(All Teams), Custom String("BOSS WAVE FINISHED!")); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 7 - BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 7; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 9 - ECHO, +1 BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 9; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Echo))) == 0); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + "FILL EMPTY SLOTS BY ZENS" + While(Count Of(All Players(Team 2)) < 14); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("Ana Nano Variable") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + } + + actions + { + Player Closest To Reticle(Event Player, Team 1).IsNanoed = 1; + } +} + +rule("IsNanoed") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.IsNanoed == True; + } + + actions + { + If(Is Dead(Event Player)); + Event Player.IsNanoed = 0; + End; + Wait(8, Ignore Condition); + Event Player.IsNanoed = 0; + } +} + +rule("money on kill") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + actions + { + If(Hero Of(Victim) == Hero(Zenyatta)); + All Players(Team 1).Money[0] += 5 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 5 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Reinhardt)); + All Players(Team 1).Money[0] += 15 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 15 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Wrecking Ball)); + All Players(Team 1).Money[0] += 20 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 20 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Widowmaker)); + All Players(Team 1).Money[0] += 25 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 25 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Bastion)); + All Players(Team 1).Money[0] += 50 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 50 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Echo)); + All Players(Team 1).Money[0] += 75 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 75 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Orisa)); + All Players(Team 1).Money[0] += 100 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 100 * (Victim.isBoss ? 3 : 1); + End; + } +} + +rule("Abilities and Hero Talents by Shingen and LemonAid") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.DamageDealt = 100; + Event Player.PlayerHealth = 100; + Event Player.Money[0] = 2400 + Global.StartMoney; + If(Custom String("{0}", Event Player) == Custom String("ShuriZma")); + Create HUD Text(Event Player, Custom String("Serverload: {0}, AVG {1}, Peak {2}", Server Load, Server Load Average, + Server Load Peak), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + End; + } +} + +rule("Team 1 (Ability): Headhunter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[1] == True; + Event Was Critical Hit == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[1] * 40 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Ambush") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[2] == True; + Event Ability != Null; + (Y Component Of(Position Of(Event Player)) - Y Component Of(Position Of(Victim)) >= 3 || Absolute Value(Horizontal Angle Towards( + Victim, Event Player)) >= 90) == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[2] * 30 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Quick Fix") +{ + event + { + Player Earned Elimination; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[3] == True; + } + + actions + { + Heal(Event Player, Null, Event Player.Abilities[3] * 50); + Set Move Speed(Event Player, 100 + Event Player.Abilities[3] * 20); + Wait(5, Restart When True); + Set Move Speed(Event Player, 100); + } +} + +rule("Team 1 (Ability): Heavyweight") +{ + event + { + Player Dealt Knockback; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[4] == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[4] * 25 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Charged") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[5] == True; + Ultimate Charge Percent(Event Player) < Event Player.Abilities[5] * 20; + } + + actions + { + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + If(Is Duplicating(Event Player)); + Wait(0.016, Ignore Condition); + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + End; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Team 1 (Ability): Haste Primary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Primary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Primary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Primary Fire))); + } +} + +rule("Team 1 (Ability): Haste Secondary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Secondary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Secondary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Secondary Fire))); + } +} + +rule("Team 1 (Ability): Haste Ability 1") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 1)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 1))); + } +} + +rule("Team 1 (Ability): Haste Ability 2") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 2)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 2))); + } +} + +rule("Team 1 (Ability): Haste Jump") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Jump)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Jump), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Jump))); + } +} + +rule("Team 1 (Ability): Haste Crouch") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Crouch)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Crouch), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Crouch))); + } +} + +rule("Team 2 (Ability): Heavy Impact") +{ + event + { + Player Took Damage; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[7] == True; + } + + actions + { + Abort If(Random Real(-0.020, 1) > Event Damage / Max Health(Event Player)); + Set Status(Event Player, Attacker, Stunned, 1 * Attacker.Abilities[7]); + Wait(5, Ignore Condition); + } +} + +rule("Team 1 (Ability): Second Wind") +{ + event + { + Player Died; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[9] == True; + } + + actions + { + Abort If(Random Integer(1, 100) > Event Player.Abilities[9] * 30); + Resurrect(Event Player); + Small Message(All Players(All Teams), Custom String("{0} received a second wind!", Event Player)); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Green), Event Player, 1); + Wait(30, Ignore Condition); + } +} + +rule("Team 1 (Ability): Binding Heal") +{ + event + { + Player Dealt Healing; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[10] == True; + Healee != Event Player; + } + + actions + { + Set Player Health(Event Player, Health(Event Player) + Event Player.Abilities[10] * 0.250 * Event Healing); + } +} + +rule("Team 1 (Ability): Resilience") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[11] == True; + Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300; + } + + actions + { + Set Damage Received(Event Player, 70); + Wait Until(!(Event Player.Abilities[11] && Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Auto Repair") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.AutoRepair == True; + Global.GateHealth < Global.GateMaxHealth; + } + + actions + { + Global.GateHealth += 5 * Global.AutoRepair; + Global.UpgradeGateMaxHealthValue += 5 * Global.AutoRepair; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(5, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ana Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ana), Button(Ability 1)), Custom String( + "Sleep Paralysis: Slept enemies cannot be woken up by damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Ana), Button(Ability 2)), Custom String( + "Multinade: Ana throws multiple Biotic Grenades")); + } +} + +rule("Brigitte Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Brigitte), Button(Ability 1)), Custom String( + "Heavy Iron: Hitting enemies with Whip Flail will root them in pace")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Brigitte), Button(Ultimate)), Custom String( + "Endeavor: Gain a health, damage and speed boost when your barrier breaks")); + } +} + +rule("Mercy Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mercy), Button(Ability 2)), Custom String( + "Angelic blessing: Healing an ally slowly charges their ultimate")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mercy), Button(Ultimate)), Custom String( + "Holy light missiles: Unleash blasts of holy light missiles during valkyrie")); + } +} + +rule("Lúcio Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Lúcio), Button(Secondary Fire)), Custom String( + "Healing Wave: Soundwave heals allies for 30% of their max HP")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Lúcio), Button(Ability 1)), Custom String( + "Reverse Amp: Amp It Up inflicts the opposite effect of the currently played song to enemies")); + } +} + +rule("Moira Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Moira), Button(Secondary Fire)), Custom String( + "Hose: Biotic Grasp primary will damage and push enemies back")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Moira), Button(Ability 2)), Custom String( + "Flourish: Biotic Orbs are 3x more effective")); + } +} + +rule("Baptiste Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String( + "Corrode: Regenerative Burst will damage and poison enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Breakthrough: Immortality Field HP threshold increased to 100%; allies inside gain ultimate")); + } +} + +rule("Ashe Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ashe), Button(Ability 2)), Custom String( + "Wildfire: Shooting a burning enemy ignites other nearby enemies")); + Event Player.HeroTalentText[2] = Array(Icon String(Fire), Custom String( + "Flare trigger: Coach gun instantly damages all burning enemies")); + } +} + +rule("D.Va Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(D.Va), Button(Secondary Fire)), Custom String( + "Voltage Grid: Defense Matrix will damage and root enemies it's casted over")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(D.Va), Button(Ability 1)), Custom String( + "Shooting Star: Boosters set enemies on fire")); + } +} + +rule("Genji Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Genji), Button(Ability 1)), Custom String( + "Venomous Strike: Swift Strike poisons enemies; heal for poison damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Genji), Button(Ultimate)), Custom String( + "Dragon's Breath: Dragonblade fires large explosive energy charges")); + } +} + +rule("Hanzo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Hanzo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "Stormbreak: Enemies eliminated by hanzo unleash a thundercloud")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Hanzo), Button(Ability 2)), Custom String( + "Punch II: Storm Arrows deal more damage and stun and knockback enemies")); + } +} + +rule("Widowmaker Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Widowmaker; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Widowmaker), Button(Ultimate)), Custom String( + "Kiss Of Death: Scoped critical hits against enemies below 30% health explode and instantly die")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Widowmaker), Button(Ability 2)), Custom String( + "Epidemic: Enemies hurt by Venom Mine unleash toxic pulses; heal for dealt damage")); + } +} + +rule("McCree Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Cassidy), Button(Ability 2)), Custom String( + "Panic: Flashbang puts enemies in fear; deal +120% more damage to enemies in fear")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Cassidy), Button(Ultimate)), Custom String( + "Clocked: Deadeye deals more damage and knocks enemies down")); + } +} + +rule("Reinhardt Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reinhardt), Button(Ability 2)), Custom String( + "Fire Blast: Fire Strike explodes as it deals damage, setting enemies on fire")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reinhardt), Button(Ultimate)), Custom String( + "Epicenter: Earthshatter travels in all directions")); + } +} + +rule("Soldier: 76 Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ultimate)), Custom String( + "Triple Threat: 2 more rockets are fired alongside Helix Rockets")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Soldier: 76), Button(Ability 1)), Custom String( + "Shoulder Check: Sprinting into enemies will damage and tackle them to the ground")); + } +} + +rule("Torbjörn Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Torbjörn), Button(Ability 2)), Custom String( + "Melting point: Unleash heatwaves during overload and molten core")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Torbjörn), Button(Ultimate)), Custom String( + "Roots Of Magma: Enemies trapped in Molten Core blots cannot move")); + } +} + +rule("Tracer Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Tracer), Button(Ability 2)), Custom String( + "Vortex: Recall pulls and roots enemies towards the activation point")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Tracer), Button(Ultimate)), Custom String( + "Chain Reaction: Pulse Bomb creates chain explosions on enemies damaged by it")); + } +} + +rule("Winston Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Winston), Button(Ability 2)), Custom String( + "Blast Barrier: Barrier Projector damages enemies inside the area")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Winston), Button(Ultimate)), Custom String( + "Next Generation: Eliminations during Primal Rage add +15% ultimate charge towards the next")); + } +} + +rule("Pharah Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Pharah; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ability 2)), Custom String( + "Head Trauma: Concussive Blast stuns and damages enemies for 25% of their max health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Pharah), Button(Ability 1)), Custom String( + "Thunderbird: Gain 150 shields and deal 4x the damage to barriers and objects")); + } +} + +rule("Bastion Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Bomblets: Bullets shot during sentry configuration are explosive")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ability 1)), Custom String( + "Tesla: A powerful mounted laser will autmotically attack one enemy at a time")); + } +} + +rule("Doomfist Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Jump)), Custom String( + "Phase Shifter: Immune to damage while any ability is active")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Doomfist), Button(Ultimate)), Custom String( + "Fissure: Meteor Strike leaves a large fissure behind that burns enemies over it")); + } +} + +rule("Echo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Focusing Optics: Focusing Beam damage ramp starts at 90% health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Streamline: Fire many more sticky bombs per burst")); + } +} + +rule("Junkrat Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Junkrat; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Fire), Custom String("Pyromania: All explosive attacks inflict fire damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Junkrat), Button(Ability 2)), Custom String( + "Short Fused: Steel Trap sets off violent explosions once triggered")); + } +} + +rule("Mei Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mei), Button(Ultimate)), Custom String( + "Cold Snap: Instantly freeze neaerby enemies once Cryo-Freeze expires")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mei), Button(Ability 2)), Custom String( + "Icebound: While Ice Wall is up, Icicles freeze and deal much more damage")); + } +} + +rule("Orisa Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Orisa), Button(Ability 1)), Custom String( + "Immovable Object: During Fortify, become immune and convert 50% of taken damage to healing")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Orisa), Button(Secondary Fire)), Custom String( + "Unstoppable Force: Halt! is much larger and pushes enemies. When triggered, it explodes violently")); + } +} + +rule("Reaper Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reaper), Button(Ability 1)), Custom String( + "shadow streak: shadow step creates a beam that damages enemies who cross")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reaper), Button(Ultimate)), Custom String( + "Loom: Traumatize enemies in front of you when using Wraith Form")); + } +} + +rule("Roadhog Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String("Stench: Roadhog constantly damages enemies nearby")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Roadhog), Button(Ability 1)), Custom String( + "Rusted Anchor: Hook deals more damage; Eliminations will reset hook cooldown")); + } +} + +rule("Sigma Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sigma), Button(Ability 1)), Custom String( + "Gravity Well: Kinetic Grasp gives invincibility")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sigma), Button(Ultimate)), Custom String( + "Gravity Channels: Gravitic Flux damages enemies for 75% of max hp instead of 50%")); + } +} + +rule("Sombra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sombra), Button(Secondary Fire)), Custom String( + "Malware: Enemies hacked or in fear take +100% more damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sombra), Button(Ultimate)), Custom String( + "G̶̨͈̹̫̠̳̰̺̜̟̣͓͕̍̍̋̽̏̾̿̀̍̊̕͜l̶̬͎̉̋̓̇͌̽̓̈́i̶̩̯͍̬͉̺̼̫̱̐t̸̝͕͎̉͆̀͗̎͐̅̈́̋̓̂͑̕͠c̷̛͉̬͙̦̗̦̘͖͊̏́͒̉̚͜h̸̡̡̨̪̱͈̜̖̗̟̲̠̟͗̓̋̍̈́̐̇̈́̇̃̅̔͘͝: EMP leave")); + } +} + +rule("Symmetra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Symmetra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "High Voltage: Enemies eliminated by Symmetra explode and damage other enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ultimate)), Custom String( + "Energy Source: While Photon Barrier is active, all players regenerate health and gain ultimate")); + } +} + +rule("Wrecking Ball Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ultimate)), Custom String( + "Mirror Ball: Reflect 100% of taken damage to nearby enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ability 2)), Custom String( + "Distort: Adaptive Shields damages and hacks nearby enemies")); + } +} + +rule("Zarya Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zarya; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Zarya), Button(Ability 1)), Custom String( + "Augment: Health and barrier hp increased by 50%; barrier sized doubled")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Perpetual Energy: secondary inflicts burn damage that continues to last until the enemy dies")); + } +} + +rule("Zenyatta Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Vigor: The ally under the effect of Harmony Orb is immune to damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Zenyatta), Button(Ultimate)), Custom String( + "Perfect Balance: Transcendence damages enemies in a large proximity")); + } +} + +rule("Ana: Sleep Paralysis") +{ + event + { + Player Dealt Damage; + Team 1; + Ana; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Black), Victim, 1); + Wait(0.250, Ignore Condition); + Set Status(Victim, Null, Knocked Down, 5); + } +} + +rule("Ana: Multinade") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.AbilityCountdown = 4; + While(Event Player.AbilityCountdown > 0); + Wait(0.030, Ignore Condition); + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Cancel Primary Action(Event Player); + Wait(0.050, Ignore Condition); + Press Button(Event Player, Button(Ability 2)); + Event Player.AbilityCountdown -= 1; + End; + Wait(2, Ignore Condition); + } +} + +rule("Brigitte: Heavy Iron") +{ + event + { + Player Dealt Damage; + Team 1; + Brigitte; + } + + conditions + { + (Event Ability == Button(Primary Fire) || Event Ability == Button(Ability 1)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Victim, 1.500); + Set Status(Victim, Null, Rooted, 0.500); + Set Environment Credit Player(Victim, Event Player); + } +} + +rule("Brigitte: Endeavor") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Ability Cooldown(Event Player, Button(Secondary Fire)) >= 0.100; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Eye Position(Event Player), 15); + Heal(Players Within Radius(Event Player, 15, Team Of(Event Player), Off), Event Player, 200); + Event Player.DamageDealt *= 2.500; + Set Move Speed(Event Player, 100 * 1.750); + Add Health Pool To Player(Event Player, Armor, Max Health(Event Player) / 2, False, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(Is Dead(Event Player), 6); + Event Player.DamageDealt = 100 + Event Player.Abilities[13] * 5; + Set Move Speed(Event Player, 100); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Mercy: Angelic Blessing") +{ + event + { + Player Dealt Healing; + All; + Mercy; + } + + conditions + { + Event Player.Abilities[8] == True; + Healee != Event Player; + Normalized Health(Healee) < True; + } + + actions + { + Set Ultimate Charge(Healee, Ultimate Charge Percent(Healee) + 1); + Wait(0.400, Ignore Condition); + } +} + +rule("Mercy: Aurora") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ultimate(Event Player) == True; + } + + actions + { + Wait(1.500, Ignore Condition); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(All Teams), Event Player, True); + Create Beam Effect(All Players(All Teams), Mercy Heal Beam, Event Player, Event Player.Ability_Projectile1, Color(White), + Visible To Position and Radius); + Event Player.Effects_[3] = Last Created Entity; + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 70, Destination and Rate); + While(Event Player.Ability_End != Event Player.Ability_Projectile1); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Event Player.Ability_Projectile1, 1); + Wait(0.032, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[3]); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 120); + Loop If Condition Is True; + } +} + +rule("Lucio: Healing Wave") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4); + Heal(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 4, 4, Team Of(Event Player), Surfaces), + Event Player, Max Health(Filtered Array(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4, Team Of(Event Player), Surfaces), Is Alive(Current Array Element))) * 0.300); + } +} + +rule("Lucio: Reverse Amp") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + If(Is Using Ability 1(Event Player)); + Set Status(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Rooted, 4); + Else; + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 16.250); + End; + Play Effect(All Players(All Teams), Ring Explosion, Is Using Ability 1(Event Player) ? Color(Green) : Color(Yellow), Event Player, + 1); + Wait(0.400, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Hose") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Event Player.Abilities[8] == True; + Ability Resource(Event Player, Button(Primary Fire)) > False; + } + + actions + { + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Facing Direction Of(Event Player), 15, To World, + Cancel Contrary Motion); + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && !Is In Line of Sight(Current Array Element, Event Player, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Up, 8, To World, Cancel Contrary Motion); + Start Damage Over Time(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), + Distance Between(Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS)), Event Player, 1, 15); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Flourish - Damage") +{ + event + { + Player Dealt Damage; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("[Moira] Flourish - Healing") +{ + event + { + Player Dealt Healing; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Heal(Healee, Event Player, Event Healing * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Healee, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("Baptiste: Corrode") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 20); + Wait(0.200, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 12); + } +} + +rule("Baptiste: Breakthrough") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Status(Event Player, Unkillable) == True; + (Event Player.Abilities[12] ? Players On Hero(Hero(Baptiste), Team Of(Event Player)) : Empty Array).Abilities[12] == True; + } + + actions + { + Heal(Event Player, Event Player, 10000); + Set Status(Event Player, Null, Invincible, 0.800); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ashe: Firebourne") +{ + event + { + Player Dealt Damage; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability == Button(Primary Fire); + Has Status(Victim, Burning) == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Null, Burning, 10); + Start Damage Over Time(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Event Player, 10, 15); + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 5); + Wait(0.250, Ignore Condition); + } +} + +rule("Ashe: Taunt") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Damage(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, Burning)), + Event Player, 125); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Frozen, + 0.016); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Stunned, + 2); + } +} + +rule("D.Va: Voltage Grid") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 2, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 5, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 8, 0.500); + Wait(0.300, Ignore Condition); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Wait(0.016, Ignore Condition); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Loop If Condition Is True; + } +} + +rule("D.Va: Shooting Star") +{ + event + { + Player Dealt Knockback; + Team 1; + D.Va; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, 40); + Set Status(Victim, Null, Burning, 3); + Start Damage Over Time(Victim, Event Player, 3, 35); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 1); + } +} + +rule("Genji: Venomous Strike") +{ + event + { + Player Dealt Damage; + Team 1; + Genji; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 3, 25); + Start Damage Over Time(Victim, Event Player, 3, 25); + Damage(Victim, Event Player, 25); + Heal(Event Player, Event Player, 25); + } +} + +rule("Genji: Dragon's Breath") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is Firing Primary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Good Aura, Color(Lime Green), Event Player.Ability_Projectile1, 1, + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 80, Destination and Rate); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True); + Wait Until(Event Player.Ability_End == Event Player.Ability_Projectile1, 1); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Green), Event Player.Ability_Projectile1, 100); + Play Effect(All Players(All Teams), Bad Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Green), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 100); + } +} + +rule("[Hanzo] Stormbreak (Storm_Effects6)") +{ + event + { + Player Died; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[8] == True; + Hero Of(Attacker) == Hero(Hanzo); + } + + actions + { + Event Player.Storm_Projectile = Eye Position(Event Player); + Event Player.Storm_EndPoint = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Up * 12, Null, + All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Storm_Projectile, Event Player.Storm_EndPoint, 4, Destination and Rate); + Create Effect(All Players(All Teams), Cloud, Color(White), Vector(False, -0.500, False) + Event Player.Storm_Projectile, 4, + Visible To Position and Radius); + Event Player.Storm_Effects[3] = Last Created Entity; + Create Effect(All Players(All Teams), Bad Aura, Color(White), Event Player.Storm_Projectile, 3, Visible To Position and Radius); + Event Player.Storm_Effects[4] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(White), Event Player.Storm_Projectile, 3.500, Visible To Position and Radius); + Event Player.Storm_Effects[5] = Last Created Entity; + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Storm_Projectile, Ray Cast Hit Position( + Event Player.Storm_Projectile, Vector(0.100, 0, 0) + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), + False), Color(Aqua), Visible To Position and Radius); + Event Player.Storm_Effects[6] = Last Created Entity; + While(Distance Between(Event Player.Storm_Projectile, Event Player.Storm_EndPoint) > 1); + Wait(0.600, Ignore Condition); + Damage(Players Within Radius(Ray Cast Hit Position(Event Player.Storm_Projectile, Event Player.Storm_Projectile + Down * 1000, + Null, All Players(All Teams), False), 3, Team Of(Event Player), Surfaces), Attacker, 50); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + End; + Destroy Effect(Event Player.Storm_Effects[3]); + Destroy Effect(Event Player.Storm_Effects[4]); + Destroy Effect(Event Player.Storm_Effects[5]); + Destroy Effect(Event Player.Storm_Effects[6]); + } +} + +rule("Hanzo: Punch II") +{ + event + { + Player Dealt Damage; + Team 1; + Hanzo; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + Hero Of(Victim) != Hero(Torbjörn); + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.800); + Apply Impulse(Victim, Event Direction, 12, To World, Cancel Contrary Motion); + Apply Impulse(Victim, Up, 5, To World, Cancel Contrary Motion); + Set Environment Credit Player(Victim, Event Player); + Set Status(Victim, Null, Stunned, 1); + } +} + +rule("Widowmaker: Kiss Of Death") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + Normalized Health(Victim) <= 0.300; + Is Firing Secondary(Event Player) == True; + Event Ability == Button(Primary Fire); + Event Player.Abilities[8] == True; + Event Damage >= 40; + Event Was Critical Hit == True; + } + + actions + { + Kill(Victim, Event Player); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 2), Victim, 3); + Damage(Players Within Radius(Victim, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage * 1.500); + } +} + +rule("Widowmaker: Epidemic") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 8); + Play Effect(All Players(All Teams), Good Explosion, Color(Purple), Victim, 4); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Victim, 16); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Victim, 3); + Start Damage Over Time(Players Within Radius(Victim, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, 50); + Start Heal Over Time(Event Player, Event Player, 3, 50); + Wait(0.500, Ignore Condition); + } +} + +rule("McCree: Panic") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Victim.Feared_until = Total Time Elapsed + 3.500; + } +} + +rule("McCree: Panic - Damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), + Event Player.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 220, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("McCree: Clocked") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Damage(Victim, Event Player, Event Damage * 1.500); + Set Status(Victim, Null, Knocked Down, 3); + } +} + +rule("Reinhardt: Fire Blast") +{ + event + { + Player Dealt Damage; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Start Damage Over Time(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, 20); + Set Status(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Burning, 5); + } +} + +rule("Reinhardt: Epicenter") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is On Ground(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, Knocked Down, 2.500); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 10); + Damage(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, 50); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 20); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 30); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 40); + Wait(5, Ignore Condition); + } +} + +rule("[Soldier: 76] Rocket Assault Rifle") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile2 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(-2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Projectile1 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Position = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, + 0), Event Player, Rotation); + Event Player.Ability_End = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, 0), + Event Player, Rotation); + Chase Player Variable At Rate(Event Player, Ability_Position, Event Player.Ability_Projectile1, 60, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_End, Event Player.Ability_Projectile2, 60, Destination and Rate); + Wait Until(Event Player.Ability_Position == 0 && Event Player.Ability_End == 0, 2.500); + } +} + +rule("[Soldier: 76] First Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile1 != Event Player.Ability_Position; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_Position, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_Position, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_Position, 2.500); + Stop Chasing Player Variable(Event Player, Ability_Position); + Wait(0.016, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 80); + Stop Chasing Player Variable(Event Player, Ability_Position); + Event Player.Ability_Position = 0; + Event Player.Ability_Projectile1 = 0; + Wait(0.016, Ignore Condition); + } +} + +rule("[Soldier: 76] Second Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile2 != Event Player.Ability_End; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_End, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_End, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_End, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_End, 2.500); + Stop Chasing Player Variable(Event Player, Ability_End); + Damage(Players Within Radius(Event Player.Ability_End, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Event Player.Ability_End = 0; + Event Player.Ability_Projectile2 = 0; + } +} + +rule("Soldier: 76 - Init rockets") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile1 = Event Player.Ability_Position; + Event Player.Ability_Projectile2 = Event Player.Ability_End; + } +} + +rule("[Soldier: 76] Shoulder Check") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 3; + Is Alive(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) == True; + } + + actions + { + Damage(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Event Player, 55); + Set Status(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Null, Knocked Down, 1.500); + Apply Impulse(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Facing Direction Of(Event Player), 15, + To World, Cancel Contrary Motion); + Apply Impulse(Event Player, Vector(0, 8, 15), 15, To Player, Cancel Contrary Motion); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Closest Player To(Event Player, Opposite Team Of(Team Of( + Event Player))), 1); + Set Ability Cooldown(Event Player, Button(Melee), 0); + Press Button(Event Player, Button(Melee)); + Wait(1, Ignore Condition); + } +} + +rule("Torbjorn: Melting Point") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Event Player.Abilities[8] == True; + (Is Using Ability 2(Event Player) || Is Using Ultimate(Event Player)) == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Event Player, 8); + Play Effect(All Players(All Teams), Bad Explosion, Color(Yellow), Event Player, 8); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 16); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, + 25); + Set Status(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Off), Null, Burning, 3); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player, 100); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Torbjorn: Roots of Magma") +{ + event + { + Player Dealt Damage; + Team 1; + Torbjörn; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Set Status(Victim, Null, Rooted, 1); + Wait(1, Ignore Condition); + } +} + +rule("Tracer: Vortex") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, 0); + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 10); + Play Effect(All Players(All Teams), Ring Explosion, Color(Red), Position Of(Event Player), 24); + Play Effect(All Players(All Teams), Ring Explosion, Color(Yellow), Position Of(Event Player), 18); + Play Effect(All Players(All Teams), Ring Explosion, Color(Green), Position Of(Event Player), 12); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player), 6); + Set Environment Credit Player(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player); + } +} + +rule("Tracer: Vortex 2") +{ + event + { + Player Received Healing; + Team 2; + All; + } + + conditions + { + Healer.Abilities[8] == True; + Hero Of(Healer) == Hero(Tracer); + Is Using Ability 2(Healer) == True; + Event Ability == Null; + Event Damage <= 20; + } + + actions + { + Apply Impulse(Event Player, Up, 5, To World, Cancel Contrary Motion); + Wait(0.100, Ignore Condition); + Apply Impulse(Event Player, Direction Towards(Event Player, Healer), Distance Between(Event Player, Healer) * 3.500, To World, + Cancel Contrary Motion); + Set Status(Event Player, Null, Rooted, 1.300); + } +} + +rule("Tracer: Chain Reaction") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is True For Any(Filtered Array(All Players(Team Of(Event Player)), Current Array Element.Chain_Reaction_On), Distance Between( + Event Player, Current Array Element) <= 8 && True) == True; + Event Player.Chain_Reaction_Immune == False; + Event Player.Chain_Reaction_On == False; + Is Alive(Event Player) == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Event Player.Chain_Reaction_On = True; + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player, 3); + } +} + +rule("Tracer: Chain Reaction 2") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Event Player.Chain_Reaction_On == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Aqua), Event Player, 3); + Damage(Event Player, Players On Hero(Hero(Tracer), Opposite Team Of(Team Of(Event Player))), 200); + Wait(0.500, Ignore Condition); + Event Player.Chain_Reaction_Immune = True; + Event Player.Chain_Reaction_On = False; + Wait(2, Ignore Condition); + Event Player.Chain_Reaction_Immune = False; + } +} + +rule("Tracer: Chain Reaction 3") +{ + event + { + Player Dealt Damage; + Team 1; + Tracer; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Damage > 20; + Event Player.Abilities[12] == True; + } + + actions + { + Victim.Chain_Reaction_On = True; + } +} + +rule("[Winston] Electric Field") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 65); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Orb, Color(White), Event Player.Ability_Projectile1, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Stop Chasing Player Variable(Event Player, Ability_Resource); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Down * 1000, Null, + All Players(All Teams), False); + Wait(0.100, Ignore Condition); + Event Player.Ability_Resource = 5; + Wait(0.250, Ignore Condition); + Chase Player Variable At Rate(Event Player, Ability_Resource, 20, 7, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, Event Player.Ability_Resource, + Destination and Rate); + Wait(8.650, Restart When True); + Event Player.Ability_Active = False; + } +} + +rule("[Winston] Electric Field 2") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 33); + Play Effect(All Players(All Teams), Ring Explosion, Color(Blue), Event Player.Ability_Projectile1, 10); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 80); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Event Player.Ability_Projectile1, 12); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player.Ability_Projectile1, 125); + } +} + +rule("Winston: Next Generation") +{ + event + { + Player Earned Elimination; + Team 1; + Winston; + } + + conditions + { + Ultimate Charge Percent(Event Player) <= 80; + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 15); + } +} + +rule("Pharah: Head Trauma") +{ + event + { + Player Dealt Knockback; + Team 1; + Pharah; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Victim != Event Player; + } + + actions + { + Damage(Victim, Event Player, Max Health(Victim) * 0.300); + Set Status(Victim, Event Player, Knocked Down, 1); + Play Effect(All Players(All Teams), Good Explosion, Color(Team 1), Victim, 1); + } +} + +rule("Pharah: Thunderbird") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[12] == True; + Hero Of(Event Player) == Hero(Pharah); + } + + actions + { + Event Player.DamageDealt *= 4; + Start Damage Modification(All Players(All Teams), Event Player, 25, Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Add Health Pool To Player(Event Player, Shields, 150, True, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(!Event Player.Abilities[12] || Hero Of(Event Player) != Hero(Pharah), 99999); + Event Player.DamageDealt = 100 + Event Player.Abilities[13] * 5; + Stop Damage Modification(Event Player.Modification_Damage[1]); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + } +} + +rule("Orisa: Unstoppable Force") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Direction = Facing Direction Of(Event Player); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Sphere, Color(Green), Event Player.Ability_Projectile1, 4, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player) + Facing Direction Of(Event Player) * 0.500; + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 100, Null, All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 25, Destination and Rate); + Wait(0.250, Ignore Condition); + Wait Until((!Event Player.Gen_Available && Is Button Held(Event Player, Button(Secondary Fire))) || ( + Event Player.Ability_Projectile1 == Event Player.Ability_End), 99999); + Stop Chasing Player Variable(Event Player, Ability_Projectile1); + Wait(0.500, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, + 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Orisa: Availability for Halt!") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Available = True; + Wait Until(!Is Button Held(Event Player, Button(Secondary Fire)), 99999); + Event Player.Gen_Available = False; + } +} + +rule("Orisa: Drag effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Player.Ability_Active == True; + } + + actions + { + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Is Alive(Event Player) ? Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of( + Event Player)), Surfaces) : Empty Array, Event Player.Ability_Projectile1), 8, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Event Player.Ability_Projectile1, Event Player.Ability_End), 20, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Up, 5, + To Player, Cancel Contrary Motion); + Wait(0.200, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Orisa: Immoveable Object - Reduce dmg") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Damage Received(Event Player, 100 * 0.003); + Wait Until(!Is Using Ability 1(Event Player), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Orisa: Immovable Object - Healing") +{ + event + { + Player Took Damage; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Event Player, Null, Event Damage * 3); + } +} + +rule("[Reaper] Shadow Streak (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Event Player.Ability_Position = Position Of(Event Player) + Vector(0, 1, 0); + Wait(2, Abort When False); + Event Player.Ability_End = Position Of(Event Player) + Vector(0, 1, 0); + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Ability_End, Event Player.Ability_Position, Color(Black), + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player) || Is Using Ability 2(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage start to end (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players(Opposite Team Of(Team Of( + Event Player))), Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_Position, + Event Player.Ability_End, All Living Players(All Teams), Event Player, True), 1); + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage end to start (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Players(Opposite Team Of(Team Of(Event Player))), + Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_End, + Event Player.Ability_Position, All Living Players(All Teams), Event Player, True), 1); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Reaper: Loom") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Hacked, 1.500); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Rooted, 1.500); + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Event Player, 45); + } +} + +rule("Sigma: Gravity Well") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, 25); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Null, Rooted, 2); + Set Status(Event Player, Null, Invincible, 1); + Play Effect(Event Player, Ring Explosion, Color(Blue), Eye Position(Event Player), 50); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Sigma: Gravity Channels") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ultimate(Event Player)), Event Player, 150, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[12], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Echo: Focusing Optics") +{ + event + { + Player Dealt Damage; + Team 1; + Echo; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Normalized Health(Victim) > 0.500; + Normalized Health(Victim) <= 0.900; + Is Duplicating(Event Player) == False; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 3); + Play Effect(All Players(All Teams), Bad Explosion, Color(Violet), Victim, 0.500); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Wait(0.700, Abort When False); + Cancel Primary Action(Event Player); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Set Projectile Speed(Event Player, 100); + Wait(0.150, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Bomblets") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Is In Alternate Form(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Orange), Null + Ray Cast Hit Position(Eye Position(Event Player), + Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, All Living Players(Opposite Team Of(Team Of( + Event Player))), All Players(Team Of(Event Player)), True), 2); + Damage(Players Within Radius(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 2, + Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 12); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Taser - Loop damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is True For Any(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive(Current Array Element) + && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status(Current Array Element, + Phased Out) && Distance Between(Event Player, Current Array Element) <= 25) == True; + Is Alive(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Explosion Sound, Color(White), Event Player.Ability_Player, 80); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Event Player.Ability_Player, 1); + Event Player.Ability_Player = Filtered Array(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive( + Current Array Element) && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status( + Current Array Element, Phased Out) && Distance Between(Event Player, Current Array Element) <= 25); + Damage(Players Within Radius(Event Player.Ability_Player, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 30); + Wait(0.450, Ignore Condition); + Loop If Condition Is True; + Event Player.Ability_Player = Null; + } +} + +rule("Bastion: Taser - Visual beam") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player + Vector(False, 1, False), + Event Player.Ability_Player != Null ? Event Player.Ability_Player : Event Player, Color(Aqua), + Visible To Position Radius and Color); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[12], 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Sombra: Malware") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, + Hacked) || Current Array Element.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 200, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Sombra: Glitch") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Ability_Active = True; + Event Player.Ability_Position = Position Of(Event Player); + Create Effect(All Players(All Teams), Sphere, Color(Purple), Event Player.Ability_Position, 15, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait(8, Ignore Condition); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Sombra: Glitch - Loop") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Ability_Active == True; + } + + actions + { + Set Status(Players Within Radius(Event Player.Ability_Position, 15, Opposite Team Of(Team Of(Event Player)), Off), Null, Hacked, + 0.750); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Mei: Cold Snap") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Event Player, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Is Using Ability 1(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Damage(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Frozen, 2); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Rooted, 2); + Play Effect(All Players(All Teams), Ring Explosion, Color(White), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Sky Blue), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player) + Vector(0, 1, 0), 20); + } +} + +rule("Mei: Icebound") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Aqua), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Set Projectile Speed(Event Player, 200); + Wait Until(!Is Firing Secondary(Event Player), 99999); + Destroy Effect(Event Player.Effects_[2]); + Set Projectile Speed(Event Player, 100); + } +} + +rule("Mei: Icebound - Icicles hit") +{ + event + { + Player Dealt Damage; + Team 1; + Mei; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 1.250); + Set Status(Victim, Null, Frozen, 1); + Set Status(Victim, Null, Rooted, 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Victim, 1); + } +} + +rule("Wrecking Ball: Mirror Ball") +{ + event + { + Player Took Damage; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 4.500, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage); + Wait(0.100, Ignore Condition); + } +} + +rule("Wrecking Ball: Distort") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Set Status(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Hacked, Count Of( + Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces)) * 1.500); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Violet), Position Of(Event Player), 125); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Sound, Color(Purple), Position Of(Event Player), 16); + Play Effect(All Players(All Teams), Explosion Sound, Color(Violet), Position Of(Event Player), 80); + } +} + +rule("Symmetra: High voltage") +{ + event + { + Player Dealt Final Blow; + Team 1; + Symmetra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Victim, 10); + Play Effect(All Players(All Teams), Bad Explosion, Color(Aqua), Victim, 8); + Damage(Players Within Radius(Victim, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 150); + } +} + +rule("Symmetra: Energy Source") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is True For Any(Players On Hero(Hero(Symmetra), Team Of(Event Player)), Is Using Ultimate(Current Array Element) + && Current Array Element.Abilities[12]) == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 1, 40); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Event Player, 0.100); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Junkrat: Pyromania") +{ + event + { + Player Dealt Knockback; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability != Button(Melee); + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 2, 30); + Set Status(Victim, Null, Burning, 2); + } +} + +rule("Junkrat: Short Fused") +{ + event + { + Player Dealt Damage; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + } + + actions + { + Event Player.Ability_Countdown = 4; + While(Event Player.Ability_Countdown > 0); + Event Player.Ability_Countdown -= 1; + Event Player.Ability_Position = Position Of(Victim) + Vector(Random Real(-2, 2), Random Real(-2, 2), Random Real(-2, 2)); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 4); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Position, 4); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 35); + Set Status(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player, Stunned, 0.800); + Wait(0.200, Ignore Condition); + End; + } +} + +rule("Zenyatta: Vigor") +{ + event + { + Player Dealt Healing; + Team 1; + Zenyatta; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Healee, Null, Invincible, 1); + Wait(0.800, Ignore Condition); + } +} + +rule("Zenyatta: Perfect Balance") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Over Time(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 0.750, 200); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player, 24); + Wait(0.600, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Stench") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Violet), Event Player, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Roadhog: Stench effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 8; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 9); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Rusted Anchor") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ability 1(Event Player)), Event Player, 400, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Roadhog: Rusted Anchor - Reset cooldown") +{ + event + { + Player Earned Elimination; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ability 1(Event Player), 3); + Set Ability Cooldown(Event Player, Button(Ability 1), False); + } +} + +rule("Zarya: Augment") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Scaling Barriers(Event Player, 2, True); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5 + 50; + Set Max Health(Event Player, Event Player.PlayerHealth); + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Zarya), 99999); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Stop Scaling Barriers(Event Player); + } +} + +rule("Zarya: Perpetual Energy") +{ + event + { + Player Dealt Knockback; + Team 1; + Zarya; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Event Player.Abilities[12] == True; + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 9999, 15); + Set Status(Victim, Null, Burning, 9999); + } +} + +rule("Doomfist: Phase Shifter") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + (Is Firing Secondary(Event Player) || Is Using Ability 1(Event Player) || Is Using Ability 2(Event Player)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Event Player, Null, Phased Out, 1); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ultimate(Event Player), 99999); + Event Player.Ability_Position = Position Of(Event Player); + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player), 8); + Event Player.Ability_Active = False; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player.Ability_Position, 16); + While(Event Player.Ability_Active == True); + Damage(Players Within Radius(Event Player.Ability_Position, 8, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 34); + Wait(0.235, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[1]); + Destroy Effect(Event Player.Effects_[2]); + } +} + +rule("Team 1 (Perk): Sharpshooter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Global.Perk[0] == True; + Event Ability != Null; + Distance Between(Event Player, Victim) >= 10; + } + + actions + { + Damage(Victim, Event Player, 50 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Perk): Bulletstorm") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.Perk[1] == True; + (Ammo(Event Player, 0) < Max Ammo(Event Player, 0) || Ammo(Event Player, 1) < Max Ammo(Event Player, 1)) == True; + } + + actions + { + Set Ammo(Event Player, 0, 1000); + Set Ammo(Event Player, 1, 1000); + } +} + +rule("Team 1 Challenges") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + If(Global.Perk[2] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[17] = Last Text ID; + End; + If(Global.Perk[0] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[18] = Last Text ID; + End; + If(Global.Perk[1] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[19] = Last Text ID; + End; + If(Global.MaxHealthDone == 50); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + End; + } +} + +rule("Remove Auto Repair when Player leaves") +{ + event + { + Player Left Match; + Team 1; + All; + } + + actions + { + Global.AutoRepair -= Event Player.Abilities[16]; + } +} + +rule("Create +Health HUD if not exists and Player Health Challenge Done") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.MaxHealthDone == True; + Event Player.Abilities[14] == 0; + } + + actions + { + Create HUD Text(Event Player, Null, Null, Custom String("+{0}% Health", Global.MaxHealthDone + Event Player.Abilities[14] * 5), + Left, 914, Color(White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Event Player.AbilityHUD[14] = Last Text ID; + } +} + +rule("Refund") +{ + event + { + Subroutine; + Refund; + } + + actions + { + "Refund Money" + Event Player.Money[0] += Event Player.Money[1]; + Event Player.Money[1] = 0; + "Reset Headhunter" + Event Player.Abilities[1] = 0; + "Reset Ambush" + Event Player.Abilities[2] = 0; + "Reset QuickFix" + Event Player.Abilities[3] = 0; + "Reset HeavyWeight" + Event Player.Abilities[4] = 0; + "Reset Charged" + Event Player.Abilities[5] = 0; + "Reset Haste" + Event Player.Abilities[6] = 0; + "Reset HeavyImpact" + Event Player.Abilities[7] = 0; + "Reset HeroTalent1" + Event Player.Abilities[8] = 0; + "Reset SecondWind" + Event Player.Abilities[9] = 0; + "Reset BindingHeal" + Event Player.Abilities[10] = 0; + "Reset Resilience" + Event Player.Abilities[11] = 0; + "Reset HeroTalent2" + Event Player.Abilities[12] = 0; + "Reset Damage" + Event Player.Abilities[13] = 0; + Event Player.DamageDealt = 100 + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + "Reset Health" + Event Player.Abilities[14] = 0; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + If(Global.MaxHealthDone == 0); + End; + "Reset Healing" + Event Player.Abilities[15] = 0; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + "Reset AutoRepair" + Global.AutoRepair -= Event Player.Abilities[16]; + Event Player.Abilities[16] = 0; + } +} + +rule("Lucio Dash HUD Creation") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + } + + actions + { + If(Event Player.Lucio_Dash_Active == False); + Event Player.Lucio_Dash_Active = True; + Create HUD Text(Event Player, Null, Null, Custom String("{0} Slam on ground - Press: {1}", Ability Icon String(Hero(Wrecking Ball), + Button(Crouch)), Input Binding String(Button(Crouch))), Left, 1000, Color(White), Color(White), Color(White), + Visible To and String, Default Visibility); + Event Player.Lucio_Dash_Icon = Last Text ID; + End; + } +} + +rule("Lucio Dash Remove HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) != Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + } + + actions + { + Destroy HUD Text(Event Player.Lucio_Dash_Icon); + Event Player.Lucio_Dash_Active = False; + } +} + +rule("Lucio Dash") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + Is On Ground(Event Player) == False; + Is Button Held(Event Player, Button(Crouch)) == True; + } + + actions + { + Apply Impulse(Event Player, Down, 20, To World, Cancel Contrary Motion); + } +} + +rule("Ana Self-Nano") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + Ultimate Charge Percent(Event Player) == 100; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Abort If(Global.SelfNanoWorkshopSetting == False && Number Of Players(Team 1) > 1); + Wait(0.100, Ignore Condition); + If(Is Using Ultimate(Event Player) == False); + Create Dummy Bot(Hero(Ana), Team Of(Event Player), -1, Position Of(Event Player) + Backward, Eye Position(Event Player)); + Event Player.AnaEntityID = Last Created Entity; + Wait(0.100, Ignore Condition); + Set Ultimate Charge(Event Player.AnaEntityID, 100); + Start Facing(Event Player.AnaEntityID, Direction Towards(Eye Position(Event Player.AnaEntityID), Position Of(Event Player) + Up), + 1000, To World, Direction and Turn Rate); + Set Invisible(Event Player.AnaEntityID, All); + Set Status(Event Player.AnaEntityID, Null, Phased Out, 9999); + Wait(0.150, Ignore Condition); + Press Button(Event Player.AnaEntityID, Button(Ultimate)); + Set Ultimate Charge(Event Player, 0); + Wait(0.150, Ignore Condition); + Teleport(Event Player.AnaEntityID, Position Of(First Of(Spawn Points(Team Of(Event Player))))); + Wait(10, Ignore Condition); + Destroy Dummy Bot(Team Of(Event Player), Slot Of(Event Player.AnaEntityID)); + End; + } +} + +rule("Reinhard Charge Cancel") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + } + + actions + { + Wait(0.600, Ignore Condition); + Wait Until(Is Button Held(Event Player, Button(Ability 1)), 5); + Set Status(Event Player, Null, Rooted, 0.001); + Wait Until(Event Player.ReinPin, 1); + If(Event Player.ReinPin != 0); + Apply Impulse(Event Player.ReinPin, Facing Direction Of(Event Player), 15, To World, Cancel Contrary Motion); + End; + } +} + +rule("Display Current HP/Max HP of bot") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + (Custom String("{0}", Event Player) == Custom String("ShuriZma")) == True; + Is Button Held(Event Player, Button(Crouch)) == True; + } + + actions + { + Small Message(Event Player, Custom String("HP: {0}/{1}", Health(Victim), Max Health(Victim))); + } +} + +disabled rule("Map Editor Walls") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("Initial Global") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Empty Array; + Global.AllDir = Empty Array; + Global.firstpos = Empty Array; + Global.secondpos = Empty Array; + Global.firstpoint2 = Empty Array; + Global.secondpoint2 = Empty Array; + Global.second = Empty Array; + Global.z = Empty Array; + Global.Wall_ID = Empty Array; + Global.g_beamType = Empty Array; + } +} + +disabled rule("Initial Player") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.filterpos = 0; + Event Player.lastsavedpos = 0; + Event Player.closestbodypos = 0; + Event Player.fullbodypos = 0; + Event Player.prevpos_intersection = 0; + Event Player.active_wall = Empty Array; + Event Player.closestwall = Empty Array; + } +} + +disabled rule("Collision Logic") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Event Player.lastsavedpos = (Eye Position(Event Player) + Position Of(Event Player)) / 2; + Wait(0.016, Ignore Condition); + Event Player.closestwall = Filtered Array(Global.AllPos, Distance Between(Global.AllPos[Current Array Index], Event Player) + <= Distance Between(Global.AllPos[Current Array Index], Global.firstpos[Current Array Index]) + || Event Player.active_wall[Current Array Index] == 1 || (Dot Product(Direction Towards(Current Array Element, + Event Player.lastsavedpos), Global.AllDir[Current Array Index]) > 0) != (Dot Product(Direction Towards(Current Array Element, + Event Player), Global.AllDir[Current Array Index]) > 0)); + For Player Variable(Event Player, x, 0, Count Of(Event Player.closestwall), 1); + Global.z = Index Of Array Value(Global.AllPos, Event Player.closestwall[Event Player.x]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3 || Global.Wall_ID[Global.z] == 5); + If(Y Component Of(Global.firstpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.firstpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.firstpos[Global.z]; + Else If(Y Component Of(Global.secondpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.secondpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.secondpos[Global.z]; + Else; + Event Player.closestbodypos = Position Of(Event Player); + End; + Event Player.fullbodypos = Vector(X Component Of(Eye Position(Event Player)), Y Component Of(Event Player.closestbodypos), + Z Component Of(Eye Position(Event Player))); + Event Player.filterpos = Event Player.fullbodypos + Global.AllDir[Global.z] * Dot Product( + Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) / Dot Product(Global.AllDir[Global.z], + Global.AllDir[Global.z]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3); + If((Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.lastsavedpos), Global.AllDir[Global.z]) > 0) != ( + Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.fullbodypos), Global.AllDir[Global.z]) > 0)); + Event Player.intersection_length = Dot Product(Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) + / Dot Product(Direction Towards(Event Player.lastsavedpos, Event Player.fullbodypos), Global.AllDir[Global.z]); + Event Player.prevpos_intersection = Event Player.fullbodypos + Direction Towards(Event Player.lastsavedpos, + Event Player.fullbodypos) * Vector(1, Empty Array, 1) * Event Player.intersection_length; + If(Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of( + Global.firstpos[Global.z]), Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], + Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of( + Global.firstpos[Global.z]), Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), + Direction Towards(Global.firstpos[Global.z], Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards( + Global.secondpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.prevpos_intersection)) + >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.secondpos[Global.z], Event Player.prevpos_intersection)) >= 0); + Cancel Primary Action(Event Player); + Teleport(Event Player, Event Player.prevpos_intersection + Direction Towards(Event Player.prevpos_intersection, + Event Player.lastsavedpos) * Vector(1, Empty Array, 1) * 2); + End; + End; + End; + Event Player.thickness = 0; + If(Global.Wall_ID[Global.z] == 5); + Event Player.thickness = 4; + Else; + Event Player.thickness = 1; + End; + If(Distance Between(Event Player.fullbodypos, Event Player.filterpos) <= Event Player.thickness && Dot Product(Direction Towards( + Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], Event Player.filterpos)) + >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.firstpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector( + X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), Z Component Of( + Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product( + Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), Y Component Of( + Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], + Event Player.filterpos)) >= 0); + If(!Global.is_Grounded); + Set Gravity(Event Player, 100); + End; + If(Event Player.active_wall[Global.z] == False); + Event Player.active_wall[Global.z] = 1; + If((Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3) && Global.is_Grounded == False); + Set Gravity(Event Player, 100); + Else If(Global.Wall_ID[Global.z] == 5); + Disable Movement Collision With Environment(Event Player, False); + End; + End; + If(Global.Wall_ID[Global.z] == 1); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos) * Vector(1, Empty Array, 1), 0.001, + To World, Cancel Contrary Motion); + Set Move Speed(Event Player, 100 - Dot Product(Direction Towards(Eye Position(Event Player), Eye Position(Event Player) + + World Vector Of(Throttle Of(Event Player), Event Player, Rotation)), Direction Towards(Event Player.filterpos, + Event Player.fullbodypos) * -1) * 100); + Else If(Global.Wall_ID[Global.z] == 3); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos), Speed Of(Event Player), To World, + Cancel Contrary Motion); + End; + Else; + Event Player.active_wall[Global.z] = 0; + Set Move Speed(Event Player, 100); + End; + End; + End; + Loop; + } +} + +disabled rule("Reset") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Count Of(Filtered Array(Event Player.active_wall, Current Array Element != 0)) == 0; + } + + actions + { + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("Effect Creation") +{ + event + { + Ongoing - Global; + } + + actions + { + Wait(5, Ignore Condition); + If(Global.showwalls); + For Global Variable(x, 0, Count Of(Global.AllPos), 1); + If(Global.Wall_ID[Global.x] == 5); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Else; + Skip(Array(14, 0, 5, 10)[Index Of Array Value(Array(1, 2, 3), Global.g_beamType[Global.x]) + 1]); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(9); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(4); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + End; + Wait(0.016, Ignore Condition); + End; + End; + } +} + +disabled rule("Wall Data") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Array(Vector(1.154, 8.133, -45.517), Vector(5.154, 8.171, -45.534), Vector(9.162, 8.246, -45.510), Vector(13.147, + 8.094, -45.538), Vector(17.157, 8.148, -45.522), Vector(9.937, 8.337, -21.624), Vector(22.998, 7.607, -20.287), Vector(26.615, + 7.773, -29.822), Vector(27.583, 8.147, -38.875), Vector(-2.486, 8.569, -79.139), Vector(-40.924, 7.449, -86), Vector(-40.885, + 11.441, -97.992), Vector(66.823, 8.544, -83.185), Vector(81.162, 6.417, -103.845), Vector(69.207, 6.436, -103.848), Vector( + 155.967, 12.476, -30.504), Vector(155.960, 12.467, -62.505)); + Global.AllDir = Array(Vector(0, 0, -1), Vector(0.007, 0, 1), Vector(0, 0, 1), Vector(0.003, 0, 1), Vector(-0.006, 0, 1), Vector( + -0.064, 0, 0.998), Vector(-0.997, 0, -0.072), Vector(0.999, 0, 0.053), Vector(-0.037, 0, 0.999), Vector(-1, 0, -0.009), Vector( + -1, 0, -0.010), Vector(-1, 0, 0.003), Vector(-1, 0, 0.003), Vector(-0.006, 0, -1), Vector(-0.001, 0, -1), Vector(1, 0, -0.003), + Vector(1, 0, 0.008)); + Global.firstpos = Array(Vector(2.423, 6.041, -45.517), Vector(3.886, 6.002, -45.525), Vector(7.902, 6.018, -45.510), Vector(11.886, + 6.009, -45.534), Vector(15.896, 6, -45.529), Vector(-3.161, 6.068, -22.459), Vector(23.035, 6.068, -20.789), Vector(26.132, + 5.035, -20.753), Vector(27.099, 6, -38.893), Vector(-2.443, 6.191, -83.959), Vector(-40.910, 6.066, -87.299), Vector(-40.889, + 10.050, -99.283), Vector(66.807, 6.208, -88.052), Vector(82.547, 5.023, -103.853), Vector(70.523, 5.046, -103.849), Vector( + 155.971, 11.057, -29.237), Vector(155.949, 11.040, -61.239)); + Global.secondpos = Array(Vector(-0.114, 10.225, -45.517), Vector(6.423, 10.339, -45.542), Vector(10.423, 10.474, -45.511), Vector( + 14.409, 10.179, -45.542), Vector(18.418, 10.297, -45.514), Vector(23.035, 10.606, -20.789), Vector(22.962, 9.145, -19.784), + Vector(27.098, 10.510, -38.891), Vector(28.068, 10.294, -38.857), Vector(-2.530, 10.947, -74.318), Vector(-40.937, 8.833, + -84.701), Vector(-40.881, 12.833, -96.701), Vector(66.838, 10.881, -78.317), Vector(79.777, 7.810, -103.837), Vector(67.890, + 7.825, -103.847), Vector(155.963, 13.894, -31.771), Vector(155.971, 13.894, -63.771)); + Global.firstpoint2 = Array(Vector(2.423, 10.225, -45.517), Vector(3.886, 10.339, -45.525), Vector(7.902, 10.474, -45.510), Vector( + 11.886, 10.179, -45.534), Vector(15.896, 10.297, -45.529), Vector(-3.161, 10.606, -22.459), Vector(23.035, 9.145, -20.789), + Vector(26.132, 10.510, -20.753), Vector(27.099, 10.294, -38.893), Vector(-2.443, 10.947, -83.959), Vector(-40.910, 8.833, + -87.299), Vector(-40.889, 12.833, -99.283), Vector(66.807, 10.881, -88.052), Vector(82.547, 7.810, -103.853), Vector(70.523, + 7.825, -103.849), Vector(155.971, 13.894, -29.237), Vector(155.949, 13.894, -61.239)); + Global.secondpoint2 = Array(Vector(-0.114, 6.041, -45.517), Vector(6.423, 6.002, -45.542), Vector(10.423, 6.018, -45.511), Vector( + 14.409, 6.009, -45.542), Vector(18.418, 6, -45.514), Vector(23.035, 6.068, -20.789), Vector(22.962, 6.068, -19.784), Vector( + 27.098, 5.035, -38.891), Vector(28.068, 6, -38.857), Vector(-2.530, 6.191, -74.318), Vector(-40.937, 6.066, -84.701), Vector( + -40.881, 10.050, -96.701), Vector(66.838, 6.208, -78.317), Vector(79.777, 5.023, -103.837), Vector(67.890, 5.046, -103.847), + Vector(155.963, 11.057, -31.771), Vector(155.971, 11.040, -63.771)); + Global.z = 16; + Global.g_beamType = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); + Global.showwalls = True; + Global.Wall_ID = Array(5, 5, 5, 5, 5, 1, 1, 1, 1, 5, 5, 5, 5, 5, 5, 5, 5); + } +} + +disabled rule("NEW SHOP") +{ + event + { + Ongoing - Global; + } +} + +rule("Setting Shop Position") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.ShopCamPos = 900 * Up; + Global.ShopPosAngle[1] = Direction From Angles(Horizontal Angle From Direction(Forward), Vertical Angle From Direction(Forward) + - 90); + Global.ShopPosAngle[0] = Cross Product(Global.ShopPosAngle[1], Forward); + Global.ShopBasePos = Global.ShopCamPos - 9 * Global.ShopPosAngle[1] + 142 * Forward; + } +} + +rule("Create Shop Buttons") +{ + event + { + Ongoing - Global; + } + + actions + { + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] + 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] - 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Refund"), + Global.ShopBasePos + 45 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 3, Do Not Clip, Visible To, Color(Green), + Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("[{0}] Leave", + Input Binding String(Button(Reload))), Global.ShopBasePos + 45 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 3, + Do Not Clip, Visible To and String, Color(Green), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("{0}$\n", Local Player.Money[0]), + Global.ShopBasePos + 36.500 * Global.ShopPosAngle[1], 3, Do Not Clip, Visible To and String, Color(White), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("▲"), Update Every Frame( + Global.ShopBasePos - (4 + Vertical Facing Angle Of(Local Player)) * Global.ShopPosAngle[1] + Horizontal Facing Angle Of( + Local Player) * Global.ShopPosAngle[0]), 4, Do Not Clip, Visible To Position and Color, Custom Color( + 245 + 10 * Sine From Radians(4 * Total Time Elapsed), 205 + 50 * Sine From Radians(4 * Total Time Elapsed), + 200 * Sine From Radians(4 * Total Time Elapsed), 255), Default Visibility); + "Headhunter" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[1] ? Custom String("Headhunter II\n  800$") : Custom String("Headhunter I\n  800$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[1] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Ambush" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[2] ? Custom String("Ambush II\n 800$") : Custom String("Ambush I\n 800$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[2] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Quick Fix" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[3] ? Custom String("Quick Fix II\n  700$") : Custom String("Quick Fix I\n  700$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[3] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavyweight" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[4] ? Custom String("Heavyweight II\n  1000$") : Custom String("Heavyweight I\n  1000$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[4] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Charged" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[5] ? Custom String("Charged II\n  700$") : Custom String("Charged I\n  700$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[5] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Haste" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[6] ? Custom String("Haste II\n 700$") : Custom String("Haste I\n 700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[6] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavy Impact" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[7] ? Custom String("Heavy Impact II\n  1000$") : Custom String("Heavy Impact I\n  1000$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[7] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 1" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 1\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[8] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "Second Wind" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[9] ? Custom String("Second Wind II\n   900$") : Custom String("Second Wind I\n   900$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[9] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Binding Heal" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[10] ? Custom String("Binding Heal II\n   700$") : Custom String("Binding Heal I\n   700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[10] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Resilience" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[11] ? Custom String("Resilience II\n  800$") : Custom String("Resilience I\n  800$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[11] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 2" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 2\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[12] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "PlusDamage" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Damage\n  400$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealth" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Health\n 400$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Healing\n  400$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, Visible To and String, + Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "+5 Auto-Repair\n    400$"), Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To String and Color, Global.AutoRepair < 5 ? Color(Green) : Color(Gray), Default Visibility); + "Use Update Every Frame to avoid showing the String when the cursor is out of bounds, resulting in 0\r\n ROW 0" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -33.750 ? Array(Custom String("Leave Buy Menu\n"), Custom String( + ""), Custom String(""), Custom String("Refund your money\n"))[Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) + / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, + Color(White), Default Visibility); + "ROW 1" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 22.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -11.250 ? Array(Custom String("Increase your damage by 5%\n"), + Local Player.Abilities[9] ? Custom String( + "Second Wind II: 60% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds") + : Custom String( + "Second Wind I: 30% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds"), + Local Player.Abilities[5] ? Custom String("Charged II: Ultimates cost 40% less\n") : Custom String( + "Charged I: Ultimates cost 20% less\n"), Local Player.Abilities[1] ? Custom String( + "Headhunter II: Critical hits deal 80% more damage\n") : Custom String("Headhunter I: Critical hits deal 40% more damage\n")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 2" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 36.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 11.250 ? Array(Custom String("Increase your health by 5%\n"), + Local Player.Abilities[10] ? Custom String("Binding Heal II: Heal yourself for 50% the amount when healing allies\n") + : Custom String("Binding Heal I: Heal yourself for 25% the amount when healing allies\n"), + Local Player.Abilities[6] ? Custom String( + " Haste II: Ability cooldown is reduced by 50%\nDoes not affect abilities with multiple charges") : Custom String( + " Haste I: Ability cooldown is reduced by 25%\nDoes not affect abilities with multiple charges"), + Local Player.Abilities[2] ? Custom String("Ambush II: Deal 60% more damage when attacking enemies from behind or above\n") + : Custom String("Ambush I: Deal 30% more damage when attacking enemies from behind or above\n"))[Round To Integer(( + Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 3" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 83.750) < 72.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 33.750 ? Array(Custom String("Increase your healing by 5%\n"), + Local Player.Abilities[11] ? Custom String("Resilience II: Take 30% less damage while below 60% health\n") : Custom String( + "Resilience I: Take 30% less damage while below 30% health\n"), Local Player.Abilities[7] ? Custom String( + "Heavy Impact II: Every hit has a chance to stun the enemy for 2 seconds\n") : Custom String( + "Heavy Impact I: Every hit has a chance to stun the enemy for 1 second\n"), Local Player.Abilities[3] ? Custom String( + "Quick Fix II: Eliminations restore 100 HP and shortly increase speed by 40%\n") : Custom String( + "Quick Fix I: Eliminations restore 50 HP and shortly increase speed by 20%\n"))[Round To Integer((Horizontal Facing Angle Of( + Local Player) + 90) / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, + Visible To and String, Color(White), Default Visibility); + "ROW 4" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 133) < 99.250 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 56.250 ? Array(Custom String( + "Increase your auto-repair by 5/5s\n"), Custom String("{0}", Local Player.HeroTalentText[2][1]), Custom String("{0}", + Local Player.HeroTalentText[1][1]), Local Player.Abilities[4] ? Custom String( + "Heavyweight II: Your knock back attacks deal 50% more damage and knock back\n            You receive 33% less knock back") + : Custom String( + "Heavyweight I: Your knock back attacks deal 25% more damage and knock back\n            You receive 20% less knock back")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + } +} + +rule("Toggle Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + !Is Dummy Bot(Event Player) == True; + Is Button Held(Event Player, Button(Reload)) == True; + !Is Communicating Any Emote(Event Player) == True; + } + + actions + { + If(Event Player.isInMenu == False); + Wait Until(!Is Button Held(Event Player, Button(Reload)), 0.500); + If(!Is Button Held(Event Player, Button(Reload))); + Abort; + End; + End; + Event Player.isInMenu = !Event Player.isInMenu; + } +} + +rule("Open Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == True; + } + + actions + { + Event Player.PlayerFacing = Facing Direction Of(Event Player); + Start Camera(Event Player, Global.ShopCamPos, Global.ShopCamPos + Forward, 0); + Disable Hero HUD(Event Player); + Call Subroutine(DisablePlayer); + Set Aim Speed(Event Player, 200); + } +} + +rule("Close Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == False; + } + + actions + { + Stop Camera(Event Player); + Enable Hero HUD(Event Player); + Call Subroutine(EnablePlayer); + Set Aim Speed(Event Player, 100); + Set Facing(Event Player, Event Player.PlayerFacing, To World); + } +} + +rule("Subroutine: Disable Player") +{ + event + { + Subroutine; + DisablePlayer; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + Set Primary Fire Enabled(Event Player, False); + Set Secondary Fire Enabled(Event Player, False); + Set Ability 1 Enabled(Event Player, False); + Set Ability 2 Enabled(Event Player, False); + Set Melee Enabled(Event Player, False); + Set Jump Enabled(Event Player, False); + Set Crouch Enabled(Event Player, False); + Disallow Button(Event Player, Button(Ultimate)); + } +} + +rule("Subroutine: Enable Player") +{ + event + { + Subroutine; + EnablePlayer; + } + + actions + { + Stop Forcing Throttle(Event Player); + Set Primary Fire Enabled(Event Player, True); + Set Secondary Fire Enabled(Event Player, True); + Set Ability 1 Enabled(Event Player, True); + Set Ability 2 Enabled(Event Player, True); + Set Melee Enabled(Event Player, True); + Set Jump Enabled(Event Player, True); + Set Crouch Enabled(Event Player, True); + Allow Button(Event Player, Button(Ultimate)); + } +} + +rule("Buy Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Primary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + Event Player.isInMenu = !Event Player.isInMenu; + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Money[1] != 0); + Call Subroutine(Refund); + Else; + Small Message(Local Player, Custom String("You don't have anything to refund!")); + End; + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[13] += 1; + Event Player.DamageDealt = 100 + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 2); + If(Event Player.Money[0] >= 900); + Event Player.Money[0] -= 900; + Event Player.Money[1] += 900; + Event Player.Abilities[9] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[5] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[1] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[14] += 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[10] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[6] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[2] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[15] += 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[11] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[7] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[3] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Global.AutoRepair != 5); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Global.AutoRepair += 1; + Event Player.Abilities[16] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[12] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[8] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[4] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + End; + } +} + +rule("Refund Single Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Secondary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[13] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[13] -= 1; + Event Player.DamageDealt = 100 + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 0); + Event Player.Money[0] += 900; + Event Player.Money[1] -= 900; + Event Player.Abilities[9] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[5] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[1] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[14] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[14] -= 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[10] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[6] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[2] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[15] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[15] -= 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[11] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[7] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[3] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[16] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Global.AutoRepair -= 1; + Event Player.Abilities[16] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[12] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[8] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[4] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + End; + } +} + +rule("Create Player HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Custom String("{0}{1}", + Event Player, Event Player.isInMenu ? Custom String("(In Shop)") : Custom String("")), Custom String("{0}{1}", Is Alive( + Event Player) ? Custom String("{0} HP", Round To Integer(Health(Event Player), Up)) : Custom String("Dead"), Custom String( + ", {0}$", Event Player.Money)), Left, Local Player == Event Player ? -1 : Slot Of(Event Player), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), + Visible To Sort Order String and Color, Default Visibility); + Create HUD Text(Event Player.Abilities[13] ? Event Player : Null, Null, Null, Custom String("+{0}% Damage", + Event Player.Abilities[13] * 5), Left, 913, Color(White), Color(White), Color(Turquoise), Visible To and String, + Default Visibility); + Create HUD Text(Event Player.Abilities[9] ? Event Player : Null, Null, Null, Custom String("Second Wind {0}", + Event Player.Abilities[9] == 1 ? Custom String("I") : Custom String("II")), Left, 908, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[5] ? Event Player : Null, Null, Null, Custom String("Charged {0}", + Event Player.Abilities[5] == 1 ? Custom String("I") : Custom String("II")), Left, 905, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[1] ? Event Player : Null, Null, Null, Custom String("Headhunter {0}", + Event Player.Abilities[1] == 1 ? Custom String("I") : Custom String("II")), Left, 901, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[14] ? Event Player : Null, Null, Null, Custom String("+{0}% Health", + Global.MaxHealthDone + Event Player.Abilities[14] * 5), Left, 914, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[10] ? Event Player : Null, Null, Null, Custom String("Binding Heal {0}", + Event Player.Abilities[10] == 1 ? Custom String("I") : Custom String("II")), Left, 909, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[6] ? Event Player : Null, Null, Null, Custom String("Haste {0}", + Event Player.Abilities[6] == 1 ? Custom String("I") : Custom String("II")), Left, 906, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[2] ? Event Player : Null, Null, Null, Custom String("Ambush {0}", + Event Player.Abilities[2] == 1 ? Custom String("I") : Custom String("II")), Left, 902, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[15] ? Event Player : Null, Null, Null, Custom String("+{0}% Healing", + Event Player.Abilities[15] * 5), Left, 915, Color(White), Color(White), Color(Turquoise), Visible To and String, + Default Visibility); + Create HUD Text(Event Player.Abilities[11] ? Event Player : Null, Null, Null, Custom String("Resilience {0}", + Event Player.Abilities[11] == 1 ? Custom String("I") : Custom String("II")), Left, 910, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[7] ? Event Player : Null, Null, Null, Custom String("Heavy Impact {0}", + Event Player.Abilities[7] == 1 ? Custom String("I") : Custom String("II")), Left, 907, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[3] ? Event Player : Null, Null, Null, Custom String("Quick Fix {0}", + Event Player.Abilities[3] == 1 ? Custom String("I") : Custom String("II")), Left, 903, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Global.AutoRepair ? Event Player : Null, Null, Null, Custom String("{0} total Auto-Repair/5s", + Global.AutoRepair * 5), Left, 916, Color(White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[2][0], Event Player.HeroTalentText[2][1]), Top, 902, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("Hero Talent 2"), Left, 912, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[1][0], Event Player.HeroTalentText[1][1]), Top, 901, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("Hero Talent 1"), Left, 911, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[4] ? Event Player : Null, Null, Null, Custom String("Heavyweight {0}", + Event Player.Abilities[4] == 1 ? Custom String("I") : Custom String("II")), Left, 904, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + } +} + +rule("Rein Pin detect") +{ + event + { + Player Dealt Knockback; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 1); + Has Status(Victim, Stunned) == True; + } + + actions + { + Event Player.ReinPin = Victim; + Wait(1, Ignore Condition); + Event Player.ReinPin = Null; + } +} + +rule("Boss Rotation") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.activeBoss == True; + } + + actions + { + If(Global.bossRotation == 0 || Global.bossRotation == 3); + Global.bossRotation = 1; + Global.lastBoss[1] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 1); + Global.bossRotation = 2; + Global.lastBoss[2] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 2); + Global.bossRotation = 3; + Global.lastBoss[3] = Hero Of(Global.activeBoss); + End; + } +} + +rule("15 minutes hud") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 10; + } + + actions + { + Create HUD Text(All Players(Team 1), Global.activeBoss ? Custom String("Boss: {0}, HP: {1}/{2}", Hero Of(Global.activeBoss), + Health(Global.activeBoss), Max Health(Global.activeBoss)) : Custom String(""), Null, Null, Top, 900, Color(Red), Color(White), + Color(White), Visible To and String, Default Visibility); + } +} \ No newline at end of file diff --git a/defendTheCastleExtended/old_versions/c119.ow b/defendTheCastleExtended/old_versions/c119.ow new file mode 100644 index 0000000..953586b --- /dev/null +++ b/defendTheCastleExtended/old_versions/c119.ow @@ -0,0 +1,9370 @@ +settings +{ + main + { + Description: "Defend Castle v0.6.c119 by HuKuTa94#2589 modified by ShuriZma#2349 - J1K6F (Code Version: v090) - Defend the gate, kill enemies and don't allow them to damage the gate! Torb, Brig and Rein can repair the gate but beware! You never know what the enemy might be hiding until now! Special Thanks to: Shingen#21859 for the Abilities, LemonAid#11644 for the Hero Talents & Josbird for teaching me about Menus! Find the Original Mode on: workshop.codes/BQEGS" + Mode Name: "Defend Castle v0.6.c119" + } + + lobby + { + Max Spectators: 4 + Max Team 1 Players: 4 + Max Team 2 Players: 0 + Return To Lobby: Never + Swap Teams After Match: No + } + + modes + { + Escort + { + enabled maps + { + Havana + } + } + + Team Deathmatch + { + enabled maps + { + } + } + + General + { + Game Mode Start: Immediately + Spawn Health Packs: Disabled + } + } + + workshop + { + Ana can nano herself even if there are other players only if no player targeted: On + Story Heroes: Off + } + + extensions + { + Beam Effects + Kinetic Explosion Effects + Explosion Sounds + Play More Effects + Spawn More Dummy Bots + } +} + +variables +{ + global: + 0: GatePosition + 1: ZenSpawnPositions + 2: SpawnPositionMaxId + 3: LoopIterator1 + 4: BigBossSpawnPositions + 5: PlayerSpawnPositions + 6: GateHealthChase + 7: GateHealth + 8: GateMaxHealth + 9: GateProgressBarColorCurrent + 10: GateProgressBarColorComponent + 11: GateHealthEvent + 12: BastionTargetPositions + 13: SniperPositions + 14: BallSpawnPositions + 15: ZenRespawnTime + 16: TimeMin + 17: TimeSec + 18: DefaultCurrentBot + 19: DefaultHeroBotsPool + 20: DefaultHeroBotsPoolCurrentId + 21: IsDebug + 22: BotOrisaParent + 23: IsStoryHeroes + 24: BotOrisaChild + 25: GateRepairPosition + 26: BotOrisaTargetPosition + 27: BotEchoRespawnPosition + 28: BotEchoTeleportPositions + 29: UpgradeGateMaxHealthValue + 30: UpgradeGateMaxHealthHudId + 31: UpgradePlayerMaxHealthValue + 32: UpgradePlayerMaxHealthHudId + 33: UpgradeCriticalDamageValue + 34: UpgradeCriticalDamageHudId + 35: UpgradeMaxAmmoValue + 36: UpgradeMaxAmmoHudId + 37: UpgradeMaxAmmoMaxValue + 38: UpgradePlayerMaxHealthMaxValue + 39: UpgradeCriticalDamageMaxValue + 40: UpgradeGateMaxHealthMaxValue + 41: DamageDone + 42: IsDebugAINavigation + 43: GameLogicCountOfUniqueHeroes + 44: IsNewWaveGameLogicProcessing + 45: AutoRepair + 46: UpgradePerkSharpshooterValue + 47: Perk + 48: MaxHealthDone + 49: StartMoney + 50: Time5Min + 51: SelfNanoWorkshopSetting + 52: ShopCamPos + 53: ShopBasePos + 54: ShopPosAngle + 55: activeBoss + 56: bossTrigger + 57: bossRotation + 58: lastBoss + 59: Time10Min + 61: challengeCount + 62: UpgradeBossHealthValue + 112: AllPos + 113: AllDir + 114: firstpos + 115: secondpos + 116: firstpoint2 + 117: secondpoint2 + 118: second + 119: z + 120: Wall_ID + 121: showwalls + 122: is_Grounded + 123: g_beamType + 124: x + 125: NodePositions + 126: NodeConnections + 127: DistanceMatrix + + player: + 0: BotSeePlayer + 1: BotDoesUniqueBehaviour + 2: BotEffects + 3: BotRayCastHitPosition + 4: BotEventPosition + 5: CurrentHero + 6: IsDead + 7: IsRespawning + 8: BotBastionArtilleryDidShotsCount + 9: BotCounter + 10: HasBadStatus + 11: EventHealth + 12: HealOverTimeId + 13: BotIsOrisaChild + 14: BotEchoCapturedPlayer + 15: BotPlayersInRadius + 16: BotLoopIterator2 + 17: BotWidowShotTime + 18: BotWidowTeleportTime + 19: IsNanoed + 20: AbilityHUD + 21: Lucio_Dash_Active + 22: Lucio_Dash_Icon + 23: AnaEntityID + 24: Abilities + 25: Money + 26: HeroTalentText + 27: DamageDealt + 28: PlayerHealth + 29: AbilityCountdown + 30: HP_Pool + 31: Effects_ + 32: Ability_Projectile1 + 33: Ability_End + 34: Storm_Projectile + 35: Storm_EndPoint + 36: Storm_Effects + 37: Feared_until + 38: Modification_Damage + 39: Ability_Projectile2 + 40: Ability_Position + 41: Chain_Reaction_On + 42: Chain_Reaction_Immune + 43: Ability_Active + 44: Ability_Resource + 45: secondWindActive + 46: isInMenu + 47: ReinPin + 48: PlayerFacing + 49: isBoss + 50: Gen_Direction + 51: Gen_Available + 52: Ability_Player + 53: Ability_Countdown + 54: lastSecondWind + 105: filterpos + 106: lastsavedpos + 107: closestbodypos + 108: fullbodypos + 109: prevpos_intersection + 110: active_wall + 111: closestwall + 112: x + 113: intersection_length + 114: thickness + 115: BotCancelPathFinding + 116: BotLoopIterator1 + 117: BotTempArray + 118: BotTargetPlayer + 119: BotTargetPosition + 120: BotClosestNodeIdToTarget + 121: BotClosestNodeIdToBot + 122: BotPrevNodeId + 123: BotNextNodeId + 124: BotNextNodePosition + 125: BotCurrentDistanceToTarget + 126: BotShortestDistanceToTarget + 127: BotIsPathFinding +} + +subroutines +{ + 0: BotBastionArtilleryDamage + 1: BotBastionFlameGunDamage + 2: BotBastionRespawn + 3: GateProgressBarColor + 4: BotZenyattaRespawn + 5: BotWidowRespawn + 6: BotBallRespawn + 7: GameLogicAddNextHeroInGame + 8: BotOrisaRespawn + 9: BotLandingFromSky + 10: BotEchoRespawn + 11: BotEchoDetachPlayer + 12: BotEchoFlyToPlayer + 13: BotEchoFlyToPortal + 14: GameLogicSetBotProperties + 15: DisablePlayer + 16: BotApearFromUnderground + 17: BotReinRespawn + 18: PlayerInit + 19: BotInit + 20: PlayerRespawn + 21: BotRespawn + 22: BotWidowBadStatus + 23: GameLogicWave0 + 24: Refund + 25: EnablePlayer + 124: BotStartPathFinding + 125: BotGetClosestNodeIdToTarget + 126: BotGetNextNodeIdAndPosition + 127: BotResetPathFinding +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("MAP: HAVANA") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Havana); + } + + actions + { + Global.NodePositions = Array(Vector(147.588, 6.425, -46.749), Vector(136.181, 6.425, -57.159), Vector(130.189, 6.425, -63.781), + Vector(123.305, 6.425, -57.983), Vector(125.678, 6.504, -46.633), Vector(114.485, 7.471, -46.699), Vector(138.743, 6.425, + -32.974), Vector(126.498, 6.425, -39.920), Vector(124.572, 10.434, -34.300), Vector(138.605, 5.359, -18.647), Vector(119.009, + 2.331, -31.024), Vector(121.138, 5.228, -19.933), Vector(126.722, 6.425, -29.505), Vector(102.762, 3.157, -33.609), Vector( + 76.030, 7.418, -74.087), Vector(83.720, 9.425, -33.744), Vector(97.439, 7.238, -42.379), Vector(86.252, 12.416, -47.261), + Vector(65.178, 11.425, -73.187), Vector(97.466, 7.269, -50.596), Vector(113.039, 7.424, -37.337), Vector(106.179, 7.450, + -46.143), Vector(90.086, 7.411, -44.653), Vector(78.752, 7.418, -62.140), Vector(82.124, 7.428, -44.229), Vector(90.675, 7.231, + -51.234), Vector(85.717, 4.692, -63.446), Vector(90.830, 4.330, -70.697), Vector(102.425, 2.387, -72.817), Vector(81.443, + 4.425, -81.648), Vector(70.743, 6.418, -81.495), Vector(69.738, 6.419, -96.344), Vector(127.586, 12.643, -63.344), Vector( + 118.911, 13.468, -58.008), Vector(102.885, 1.092, -56.579), Vector(100.009, 2.967, -67.139), Vector(106.703, 0.465, -44.628), + Vector(81.695, 7.418, -52.140), Vector(126.979, 12.393, -55.079), Vector(153.720, 18.578, -21.745), Vector(155.301, 18.619, + -17.595), Vector(133.043, 10.425, -26.625), Vector(114.646, 7.278, -57.336), Vector(95.160, 3.688, -81.194), Vector(78.456, + 5.418, -93.581), Vector(75.455, 5.418, -101.492), Vector(148.071, 9.432, -32.123), Vector(146.706, 9.425, -27.858), Vector( + 144.273, 9.445, -63.119), Vector(144.278, 9.454, -58.447)); + Global.NodeConnections = Array(Array(1, 6, 4, 7), Array(2, 1, 4, 6, 7, 0, 49), Array(1, 3), Array(2, 4, 42), Array(3, 1, 5, 7, 6, + 1, 0), Array(4, 7, 20, 21, 19, 16, 42), Array(7, 1, 4, 1, 9, 12, 0, 46), Array(4, 5, 6, 1, 1, 12, 0), Array(7, 41), Array(6, + 11), Array(11, 13), Array(9, 10, 13), Array(6, 7, 10), Array(10, 16, 36), Array(18, 23, 30), Array(17, 24), Array(13, 19, 22, + 21, 25, 5), Array(15, 22, 25, 23), Array(14), Array(16, 21, 22, 26, 27, 35, 25, 5), Array(5, 13, 10), Array(19, 16, 5, 13, 22, + 34), Array(16, 19, 21, 24, 25), Array(14, 25, 26, 37), Array(22, 15, 37), Array(23, 22, 19, 16, 26, 27, 35, 37), Array(25, 19, + 27, 35, 29), Array(19, 26, 25, 29, 35, 43), Array(35, 34, 43), Array(27, 26, 30, 43, 44), Array(29, 14, 31), Array(30, 29, 45), + Array(33, 38, 1, 48), Array(32, 38, 42), Array(35, 36, 28), Array(28, 19, 25, 27, 26, 34), Array(13, 34), Array(25, 23, 24), + Array(5, 4, 1, 6, 1, 32, 33, 0), Array(40), Array(39), Array(6, 8, 47, 46), Array(3, 5, 34), Array(28, 27, 29, 44), Array(29, + 43, 45), Array(44, 31), Array(6, 47), Array(46, 41), Array(49, 32), Array(1, 0, 6, 48)); + Global.DistanceMatrix = Array(Array(0, 1, 2, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, + 4, 5, 4, 4, 5, 5, 5, 0, 0, 4, 3, 5, 6, 7, 2, 3, 3, 2), Array(1, 0, 1, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, + 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 3, 4, 4, 4, 5, 5, 4, 0, 0, 4, 3, 5, 6, 7, 2, 3, 2, 1), Array(2, 1, 0, 1, 2, 3, 2, 2, 6, 3, 4, 4, + 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 4, 6, 7, 8, 4, 5, 3, 4, 4, 6, 5, 0, 0, 5, 2, 5, 6, 7, 3, 4, 3, 2), Array(2, 2, + 1, 0, 1, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, 5, 6, 2, 3, 3, 5, 6, 0, 0, 5, 1, 4, + 5, 6, 3, 4, 4, 3), Array(1, 1, 2, 1, 0, 1, 1, 1, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, + 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, 2, 3, 3, 2), Array(2, 2, 3, 2, 1, 0, 2, 1, 6, 3, 2, 3, 2, 2, 4, 4, 1, 5, 5, 1, 1, 1, 2, 3, + 3, 2, 2, 2, 3, 3, 4, 5, 5, 6, 2, 2, 3, 3, 6, 0, 0, 5, 1, 3, 4, 5, 3, 4, 4, 3), Array(1, 1, 2, 2, 1, 2, 0, 1, 4, 1, 2, 2, 1, 3, + 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 4, 5, 4, 4, 4, 5, 5, 0, 0, 3, 3, 5, 6, 7, 1, 2, 3, 2), Array(1, 1, 2, 2, + 1, 1, 1, 0, 5, 2, 2, 3, 1, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, + 2, 3, 3, 2), Array(2, 2, 3, 3, 2, 2, 2, 1, 0, 3, 3, 4, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, + 5, 5, 6, 0, 0, 1, 3, 5, 6, 7, 2, 2, 4, 3), Array(2, 2, 3, 3, 2, 3, 1, 2, 5, 0, 2, 1, 2, 2, 6, 6, 3, 7, 7, 4, 4, 4, 4, 5, 5, 4, + 5, 5, 5, 6, 7, 8, 5, 6, 4, 5, 3, 5, 6, 0, 0, 4, 4, 6, 7, 8, 2, 3, 4, 3), Array(4, 4, 5, 5, 4, 3, 3, 4, 7, 2, 0, 1, 4, 1, 5, 5, + 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 7, 8, 3, 4, 2, 4, 8, 0, 0, 6, 4, 5, 6, 7, 4, 5, 6, 5), Array(3, 3, 4, 4, 3, 3, + 2, 3, 6, 1, 1, 0, 3, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 6, 7, 3, 4, 2, 4, 7, 0, 0, 5, 4, 5, 6, 7, 3, 4, + 5, 4), Array(2, 2, 3, 3, 2, 2, 1, 1, 5, 2, 1, 2, 0, 2, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, 3, 5, + 6, 0, 0, 4, 3, 5, 6, 7, 2, 3, 4, 3), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 3, 1, 2, 4, 0, 4, 4, 1, 5, 5, 2, 3, 2, 2, 3, 3, 2, 3, 3, + 3, 4, 5, 6, 7, 8, 2, 3, 1, 3, 8, 0, 0, 7, 3, 4, 5, 6, 5, 6, 6, 5), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 5, 6, 6, 4, 0, 4, 3, 5, + 1, 3, 5, 4, 3, 1, 3, 2, 2, 3, 4, 2, 1, 2, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 3, 3, 3, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, + 5, 10, 7, 5, 6, 6, 4, 3, 0, 3, 1, 4, 3, 5, 3, 2, 2, 1, 2, 3, 3, 4, 4, 4, 5, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 4, 5, 6, 7, 8, + 8, 7), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 3, 3, 0, 4, 4, 1, 2, 1, 1, 2, 2, 1, 2, 2, 3, 3, 4, 5, 6, 7, 2, 2, 2, 2, + 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 1, 2, 0, 3, 2, 4, 2, 1, 1, 2, 1, 2, 2, + 3, 3, 3, 4, 8, 9, 3, 2, 4, 2, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 6, 7, 7, 5, 1, 5, 4, 6, + 0, 4, 6, 5, 4, 2, 4, 3, 3, 4, 5, 3, 2, 3, 10, 11, 5, 4, 6, 3, 11, 0, 0, 10, 6, 4, 4, 4, 8, 9, 9, 8), Array(3, 3, 4, 3, 2, 1, 3, + 2, 7, 4, 3, 4, 3, 2, 3, 3, 1, 4, 4, 0, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 3, 4, 6, 7, 2, 1, 3, 2, 7, 0, 0, 6, 2, 2, 3, 4, 4, 5, 5, + 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 3, 1, 2, 3, 1, 5, 5, 2, 6, 6, 2, 0, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 6, 7, 3, 3, 2, 4, 7, + 0, 0, 6, 2, 4, 5, 6, 4, 5, 5, 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 4, 3, 1, 4, 5, 1, 2, 0, 1, 3, 2, 2, 2, 2, 2, + 3, 4, 5, 6, 7, 1, 2, 2, 3, 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 3, 2, 1, 3, 4, + 1, 3, 1, 0, 2, 1, 1, 2, 2, 3, 3, 4, 5, 7, 8, 2, 2, 3, 2, 8, 0, 0, 7, 3, 3, 4, 5, 5, 6, 6, 5), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, + 6, 4, 5, 5, 3, 1, 3, 2, 4, 2, 2, 4, 3, 2, 0, 2, 1, 1, 2, 3, 2, 2, 3, 8, 9, 3, 2, 4, 1, 9, 0, 0, 8, 4, 3, 3, 4, 6, 7, 7, 6), + Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 3, 1, 2, 2, 4, 2, 4, 2, 1, 2, 0, 2, 3, 3, 4, 4, 4, 5, 8, 9, 3, 3, 4, 1, 9, 0, + 0, 8, 4, 4, 5, 6, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 2, 3, 1, 4, 3, 1, 3, 2, 1, 1, 2, 0, 1, 1, 2, 2, + 3, 4, 7, 8, 2, 1, 3, 1, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, + 3, 2, 2, 2, 3, 1, 0, 1, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 2, 2, 3, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, + 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 0, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 1, 2, 3, 5, 6, 6, 5), Array( + 5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 4, 5, 3, 6, 5, 2, 4, 3, 3, 3, 4, 2, 2, 2, 0, 2, 3, 4, 8, 9, 1, 1, 2, 3, 9, 0, 0, 8, + 4, 1, 2, 3, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 2, 5, 3, 6, 3, 2, 4, 3, 3, 3, 4, 2, 1, 1, 2, 0, 1, 2, + 8, 9, 3, 2, 4, 3, 9, 0, 0, 8, 4, 1, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 1, 5, 4, 6, 2, 3, 5, 4, + 4, 2, 4, 3, 2, 2, 3, 1, 0, 1, 9, 10, 4, 3, 5, 3, 10, 0, 0, 9, 5, 2, 2, 2, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, + 7, 6, 5, 2, 6, 4, 7, 3, 3, 5, 4, 4, 3, 5, 3, 2, 2, 3, 1, 1, 0, 9, 10, 4, 3, 5, 4, 10, 0, 0, 9, 5, 2, 2, 1, 7, 8, 8, 7), Array( + 2, 1, 2, 3, 2, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 4, 5, 6, 7, 0, 1, 3, 4, 4, 5, 1, 0, 0, 5, + 2, 5, 6, 7, 3, 4, 1, 2), Array(2, 2, 3, 2, 2, 2, 2, 3, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, + 1, 0, 2, 3, 3, 5, 1, 0, 0, 5, 1, 4, 5, 6, 3, 4, 2, 3), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 5, 3, 4, 5, 2, 4, 5, 3, 6, 5, 2, 4, 3, + 3, 3, 4, 2, 2, 2, 1, 3, 4, 5, 8, 9, 0, 1, 1, 3, 9, 0, 0, 8, 4, 2, 3, 4, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, + 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 1, 1, 2, 3, 4, 7, 8, 1, 0, 2, 2, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(5, 5, + 6, 5, 4, 3, 5, 4, 9, 4, 2, 3, 5, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 8, 9, 1, 2, 0, 4, 9, 0, 0, 8, 4, 3, + 4, 5, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 2, 2, 3, 3, 2, 4, 3, 2, 1, 1, 1, 2, 2, 3, 3, 3, 4, 8, 9, + 3, 2, 4, 0, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(1, 1, 2, 2, 1, 1, 1, 2, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, + 4, 3, 3, 3, 4, 4, 5, 6, 1, 1, 3, 3, 4, 4, 0, 0, 0, 4, 2, 4, 5, 6, 2, 3, 2, 2), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(2, 2, 3, 3, 2, 3, 1, 2, 1, 2, 3, 3, 2, + 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 0, 4, 6, 7, 8, 1, 1, 4, 3), Array(3, 3, 2, + 1, 2, 1, 3, 2, 7, 4, 3, 4, 3, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 6, 7, 1, 2, 2, 4, 7, 0, 0, 6, 0, 3, 4, + 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 3, 5, 3, 6, 4, 2, 4, 3, 3, 3, 4, 2, 2, 1, 1, 1, 2, 3, 8, 9, 2, + 2, 3, 3, 9, 0, 0, 8, 4, 0, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 3, 6, 4, 7, 4, 3, 5, 4, 4, 4, 5, + 3, 2, 2, 2, 1, 2, 2, 9, 10, 3, 3, 4, 4, 10, 0, 0, 9, 5, 1, 0, 1, 7, 8, 8, 7), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 7, 8, 7, 6, + 3, 7, 5, 8, 4, 4, 6, 5, 5, 4, 6, 4, 3, 3, 3, 2, 2, 1, 10, 11, 4, 4, 5, 5, 11, 0, 0, 10, 6, 2, 1, 0, 8, 9, 9, 8), Array(2, 2, 3, + 3, 2, 3, 1, 2, 3, 2, 3, 3, 2, 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 2, 4, 6, 7, + 8, 0, 1, 4, 3), Array(3, 3, 4, 4, 3, 4, 2, 3, 2, 3, 4, 4, 3, 5, 8, 8, 5, 9, 9, 5, 5, 5, 6, 7, 7, 6, 6, 6, 7, 7, 8, 9, 6, 7, 6, + 6, 6, 7, 7, 0, 0, 1, 5, 7, 8, 9, 1, 0, 5, 4), Array(2, 2, 3, 4, 3, 3, 2, 3, 6, 3, 4, 4, 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, + 5, 5, 5, 5, 6, 7, 8, 1, 2, 4, 5, 5, 6, 2, 0, 0, 5, 3, 6, 7, 8, 3, 4, 0, 1), Array(1, 1, 2, 3, 2, 3, 1, 2, 5, 2, 3, 3, 2, 4, 7, + 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 2, 3, 5, 5, 5, 6, 3, 0, 0, 4, 4, 6, 7, 8, 2, 3, 1)); + } +} + +rule("SUBROUTINE: BOT - RESET PATH FINDING") +{ + event + { + Subroutine; + BotResetPathFinding; + } + + actions + { + Event Player.BotTargetPlayer = -1; + Event Player.BotTargetPosition = -1; + Event Player.BotPrevNodeId = -1; + Event Player.BotClosestNodeIdToTarget = -1; + Event Player.BotNextNodeId = -1; + Event Player.BotNextNodePosition = -1; + Event Player.BotIsPathFinding = False; + Event Player.BotCancelPathFinding = False; + Stop Throttle In Direction(Event Player); + disabled Stop Facing(Event Player); + } +} + +rule("SUBROUTINE: BOT - START PATH FINDING") +{ + event + { + Subroutine; + BotStartPathFinding; + } + + actions + { + disabled Abort If(Event Player.BotIsPathFinding == True); + Call Subroutine(BotGetNextNodeIdAndPosition); + disabled Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Event Player.BotIsPathFinding = True; + } +} + +rule("SUBROUTINE: BOT - GET NEXT NODE ID AND POSITION") +{ + event + { + Subroutine; + BotGetNextNodeIdAndPosition; + } + + actions + { + "BOT JUST START FOLLOW PATH OR LOST NEXT NODE" + If(Event Player.BotPrevNodeId == -1); + Event Player.BotClosestNodeIdToBot = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array(Global.NodePositions, + Is In Line of Sight(Position Of(Event Player) + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS) == True), + Distance Between(Position Of(Event Player), Current Array Element))[0]); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + "NEXT NODE IS TARGET (DISTANCE TO TARGET NODE = 1)" + If(Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1); + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToTarget; + "CHECK CONNECTIONS OF REACHED NODE" + Else; + Event Player.BotShortestDistanceToTarget = 999; + Event Player.BotCurrentDistanceToTarget = Event Player.BotShortestDistanceToTarget; + Event Player.BotTempArray = Global.NodeConnections[Event Player.BotClosestNodeIdToBot]; + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotTempArray), 1); + Event Player.BotCurrentDistanceToTarget = Global.DistanceMatrix[Event Player.BotTempArray[Event Player.BotLoopIterator1]][Event Player.BotClosestNodeIdToTarget]; + If(Event Player.BotCurrentDistanceToTarget < Event Player.BotShortestDistanceToTarget); + Event Player.BotShortestDistanceToTarget = Event Player.BotCurrentDistanceToTarget; + Event Player.BotNextNodeId = Event Player.BotTempArray[Event Player.BotLoopIterator1]; + End; + End; + End; + "NEXT NODE IS HIGHER THAN BOT AND BOT DIDN'T REACH CLOSEST NODE" + If(Y Component Of(Position Of(Event Player)) - Y Component Of(Global.NodePositions[Event Player.BotNextNodeId]) + < -3 && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + "BOT CAN SEE TARGET POSITION AND NEXT NODE IS TARGET" + Else If( + Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1 && Is In Line of Sight( + Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotTargetPosition + Vector(0, 2, 0), Barriers Do Not Block LOS)); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Abort; + "BOT CAN'T SEE NEXT NODE AND PREV NODE != REACHED NODE" + Else If(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), + Global.NodePositions[Event Player.BotNextNodeId] + Vector(0, 2, 0), Barriers Do Not Block LOS) + == False && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + End; + Event Player.BotNextNodePosition = Global.NodePositions[Event Player.BotNextNodeId]; + } +} + +rule("SUBROUTINE: BOT - GET CLOSEST NODE ID AND POSITION TO TARGET") +{ + event + { + Subroutine; + BotGetClosestNodeIdToTarget; + } + + actions + { + Event Player.BotTargetPosition = Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Event Player.BotTargetPosition; + Event Player.BotClosestNodeIdToTarget = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array( + Global.NodePositions, Is In Line of Sight(Event Player.BotTargetPosition + Vector(0, 2, 0), Current Array Element, + Barriers Do Not Block LOS) == True), Distance Between(Event Player.BotTargetPosition, Current Array Element))[0]); + } +} + +rule("BOT: PATH FINDING - START") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + (Event Player.BotTargetPosition != -1 || Event Player.BotTargetPlayer != -1) == True; + } + + actions + { + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - CANCEL") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotCancelPathFinding == True; + } + + actions + { + Start Rule(BotResetPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - LOST THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + (Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotNextNodePosition + Vector(0, 2.500, 0), + Barriers Do Not Block LOS) == False && Speed Of In Direction(Event Player, Throttle Of(Event Player)) < 2) == True; + } + + actions + { + Wait(0.500, Abort When False); + "RESET PREV NODE ID TO INFORM BOT THAT IT LOST NEXT NODE" + Event Player.BotPrevNodeId = -1; + "TRY FIND NEW NEXT NODE" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodeId), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +rule("BOT: PATH FINDING - REACHED THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotClosestNodeIdToTarget >= 0; + (Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotNextNodePosition), 0, Z Component Of(Event Player.BotNextNodePosition))) < 0.850) == True; + } + + actions + { + Event Player.BotPrevNodeId = Event Player.BotNextNodeId; + Event Player.BotClosestNodeIdToBot = Event Player.BotNextNodeId; + "BOT'S TARGET IS PLAYER" + If(Event Player.BotTargetPlayer != -1); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + Event Player.BotCurrentDistanceToTarget = Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of( + Position Of(Event Player))), Vector(X Component Of(Event Player.BotTargetPosition), 0, Z Component Of( + Event Player.BotTargetPosition))); + "BOT REACHED THE TARGET NODE OR TARGET POSITION" + If(Event Player.BotNextNodeId == Event Player.BotClosestNodeIdToTarget || Event Player.BotCurrentDistanceToTarget <= 0.850); + "BOT DIDN'T REACH TARGET POSITION" + If(Event Player.BotCurrentDistanceToTarget > 0.850); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Skip(6); + "BOT REACHED TARGET" + Else; + Call Subroutine(BotResetPathFinding); + Abort; + End; + End; + "CONTINUE FOLLOW PATH" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: GAME MODE INIT - WORKSHOP SETTINGS") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.IsDebug = False; + Global.IsDebugAINavigation = False; + Global.GateMaxHealth = Workshop Setting Integer(Custom String("DEFEND CASTLE"), Custom String("GATE MAX HEALTH"), 500, 100, 1000, + 0); + Global.IsStoryHeroes = Workshop Setting Toggle(Custom String("DEFEND CASTLE"), Custom String("Story Heroes"), True, 0); + Global.SelfNanoWorkshopSetting = Workshop Setting Toggle(Custom String("Ana Self Nano"), Custom String( + "Ana can nano herself even if there are other players (only if no player targeted)"), False, 0); + } +} + +rule("GLOBAL: GAME MODE INIT - COMMON PROPERTIES") +{ + event + { + Ongoing - Global; + } + + actions + { + Create HUD Text(All Players(All Teams), Null, Null, Custom String( + "DEFEND CASTLE v0.6.c119 BY HUKUTA94#2589\r\nmodified by ShuriZma#2349\r\nDiscord: discord.shurizma.de\r\n{1}", Null, + Custom String( + "Special Thanks to:\r\nShingen#21859 for the Abilities,\r\nLemonAid#11644 for the Hero Talents &\r\nJosbird for teaching me about Menus")), + Right, -1000, Color(White), Color(White), Color(White), Visible To, Default Visibility); + Global.GateRepairPosition = Vector(153, 8, -46.500); + Global.GatePosition = Vector(148.800, 6, -46.400); + Global.BallSpawnPositions = Array(Vector(104, 7, -46), Vector(106, 2, -31)); + Global.SniperPositions = Array(Vector(154, 18, -22.600), Vector(86, 12, -46.600), Vector(80.880, 11.300, -71.600), Vector(98, 9, + -19)); + Global.ZenSpawnPositions = Array(Vector(79.500, 5, -100), Vector(90, 4, -88), Vector(65, 11, -70), Vector(85, 4, -68), Vector(96, + 2, -73), Vector(84, 7, -47), Vector(95, 9, -34), Vector(108, 1.700, -28), Vector(113, 7, -37), Vector(123, 5, -19), Vector(144, + 5, -19), Vector(123, 6, -39), Vector(123, 6, -61), Vector(129, 6, -30.500), Vector(135, 6, -63)); + Global.PlayerSpawnPositions = Array(Vector(153.300, 10, -63.800), Vector(153.300, 10, -61.700), Vector(153.300, 10, -31.700), + Vector(153.300, 10, -29.600)); + Global.BigBossSpawnPositions = Array(Vector(78, 4, -84), Vector(95, 4, -82)); + Global.BastionTargetPositions = Array(Vector(131, 12, -62), Vector(115, 7, -46), Objective Position(2), Vector(136, 10, -27)); + Global.SpawnPositionMaxId = 2; + Global.BotOrisaTargetPosition = Vector(104, 7, -46); + Global.BotEchoRespawnPosition = Vector(130, 23, -44); + Global.BotEchoTeleportPositions = Array(Vector(88, 23, -79), Vector(108, 18, -27)); + Global.DefaultHeroBotsPool = Array(Hero(Zenyatta), Hero(Widowmaker), Null, Hero(Bastion), Hero(Echo), Hero(Bastion)); + Global.ZenRespawnTime = 10; + Global.GameLogicCountOfUniqueHeroes = 5; + Global.lastBoss = Array(Null, Null, Null, Null); + Create Effect(All Players(Team 1), Ring, Color(Sky Blue), Vector(186, 11, -46.500), 9, Visible To Position and Radius); + } +} + +disabled rule("PLAYER: DEBUG - PRESS INTERACT") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Host Player == True; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + disabled Modify Player Score(Event Player, 10); + disabled Global.GateHealth -= 5; + disabled Start Rule(GateProgressBarColor, Restart Rule); + Global.TimeSec = 59; + Set Status(Event Player, Null, Phased Out, 9999); + disabled Set Ultimate Charge(Event Player, 100); + disabled Kill(Event Player, Null); + disabled Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: DEBUG - AI NAVIGATION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.IsDebugAINavigation == True; + } + + actions + { + For Global Variable(LoopIterator1, 0, Count Of(Global.NodePositions), 1); + Create Effect(All Players(All Teams), Sphere, Color(Red), Global.NodePositions[Global.LoopIterator1], 0.850, Visible To); + Create In-World Text(All Players(All Teams), Custom String("NODE {0}", Global.LoopIterator1), + Global.NodePositions[Global.LoopIterator1], 1.200, Clip Against Surfaces, Visible To, Color(White), Default Visibility); + End; + } +} + +disabled rule("GLOBAL: DEBUG - CREATE BOTS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + Create Dummy Bot(Hero(Bastion), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + Create Dummy Bot(Hero(Orisa), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +disabled rule("PLAYER: DEBUG - INFOS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + Host Player == Event Player; + Has Spawned(Event Player) == True; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Create HUD Text(Event Player, Custom String("POS {0}\r\nFACING {1}", Position Of(Event Player), Facing Direction Of(Event Player)), + Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + Create HUD Text(Event Player, Custom String("SERVER PERFORMANCE\r\nLOAD {0}%\r\nPEAK {1}%\r\nAVG {2}%", Server Load, + Server Load Peak, Server Load Average), Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create Progress Bar HUD Text(Event Player, 45, Custom String("45 / 100 KILLS"), Left, -99, Color(Blue), Color(White), + Visible To Values and Color, Default Visibility); + disabled Create HUD Text(Event Player, Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Null, Custom String( + "LEVEL 1 - 50 AMMO CLIP"), Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + "ЭФФЕКТ С ОФФСЕТОМ ОТ ПОЗИЦИИ ГЛАЗ" + disabled Create Beam Effect(All Players(All Teams), Bad Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + Facing Direction Of( + Event Player) * 3, Eye Position(Event Player) + Facing Direction Of(Event Player) * 50, Color(Purple), + Visible To Position and Radius); + } +} + +disabled rule("=== TEAM UPGRADES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: TEAM UPGRADES - INIT") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.UpgradeMaxAmmoMaxValue[0] = 250; + Global.UpgradeMaxAmmoMaxValue[1] = 500; + Global.UpgradeMaxAmmoMaxValue[2] = 1000; + Global.UpgradeCriticalDamageMaxValue[0] = 10; + Global.UpgradeCriticalDamageMaxValue[1] = 10; + Global.UpgradeCriticalDamageMaxValue[2] = 10; + Global.UpgradePlayerMaxHealthMaxValue[0] = 2500; + Global.UpgradePlayerMaxHealthMaxValue[1] = 5000; + Global.UpgradePlayerMaxHealthMaxValue[2] = 10000; + Global.UpgradeGateMaxHealthMaxValue[0] = Round To Integer(Global.GateMaxHealth + Global.GateMaxHealth * 0.500, Up); + Global.UpgradeGateMaxHealthMaxValue[1] = Global.UpgradeGateMaxHealthMaxValue[0] + Global.UpgradeGateMaxHealthMaxValue[0]; + Global.UpgradeGateMaxHealthMaxValue[2] = Global.UpgradeGateMaxHealthMaxValue[1] + Global.UpgradeGateMaxHealthMaxValue[1]; + Abort If(Global.IsDebug == False); + Global.UpgradeMaxAmmoMaxValue[0] = 1; + Global.UpgradeCriticalDamageMaxValue[0] = 1; + Global.UpgradePlayerMaxHealthMaxValue[0] = 1; + Global.UpgradeGateMaxHealthMaxValue[0] = 1; + Global.UpgradeMaxAmmoMaxValue[1] = 1; + Global.UpgradeCriticalDamageMaxValue[1] = 1; + Global.UpgradePlayerMaxHealthMaxValue[1] = 1; + Global.UpgradeGateMaxHealthMaxValue[1] = 1; + Global.UpgradeMaxAmmoMaxValue[2] = 1; + Global.UpgradeCriticalDamageMaxValue[2] = 1; + Global.UpgradePlayerMaxHealthMaxValue[2] = 1; + Global.UpgradeGateMaxHealthMaxValue[2] = 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GATE'S MAX HEALTH UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Global.GateMaxHealth = Global.UpgradeGateMaxHealthMaxValue[0]; + Global.GateHealth = Global.GateMaxHealth; + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Right, 1, Color( + Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X GATE REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[1]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X GATE REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X GATE REPAIR"), Right, 2, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X AUTO-REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[2]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[2] = Last Text ID; + Global.GateHealth = Global.GateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 3 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X AUTO-REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X AUTO-REPAIR"), Right, 3, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.UpgradeGateMaxHealthHudId[2] = Last Text ID; + Global.GateHealth = Global.GateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - PLAYER'S MAX HEALTH - DEALT HEALING") +{ + event + { + Player Received Healing; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + disabled Healer != Event Player; + Global.UpgradePlayerMaxHealthValue < Global.UpgradePlayerMaxHealthMaxValue[2]; + } + + actions + { + Global.UpgradePlayerMaxHealthValue += Event Healing; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +50%"), Right, 4, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("Up You Go: You respawn twice as fast"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[1]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.MaxHealthDone = 50; + All Players(Team 1).PlayerHealth = 100 + Global.MaxHealthDone + All Players(Team 1).Abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).PlayerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK UP YOU GO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("UP YOU GO UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String("Up You Go"), + Right, 5, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +100%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[2]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[2] = Last Text ID; + Set Respawn Max Time(All Players(Team 1), 5); + Heal(All Players(Team 1), Null, 9999); + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.Perk[2] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[17] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH 2 UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +100%"), Right, 6, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[2] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.MaxHealthDone = 150; + All Players(Team 1).PlayerHealth = 100 + Global.MaxHealthDone + All Players(Team 1).Abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).PlayerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Hero Of(Victim) == Hero(Widowmaker); + Global.UpgradeCriticalDamageValue < Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradeCriticalDamageValue += 1; + Small Message(All Players(Team 1), Custom String("CRITICAL DAMAGE CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - CRITICAL DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("CRITICAL DAMAGE 150% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "CRITICAL DAMAGE 150%"), Right, 7, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String( + "Sharpshooter: Deal 40% more damage to enemies that are further than 15 meters away"), Custom String("KILL ECHO {0}/{1}", + Global.UpgradePerkSharpshooterValue, Global.UpgradeCriticalDamageMaxValue[1]), Left, 14, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - UNLOCKED") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.500); + } +} + +rule("PLAYER: UPGRADE - PERK SHARPSHOOTER - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Echo); + Global.UpgradePerkSharpshooterValue < Global.UpgradeCriticalDamageMaxValue[1]; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradePerkSharpshooterValue += 1; + Small Message(All Players(Team 1), Custom String("SHARPSHOOTER CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - PERK SHARPSHOOTER - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("SHARPSHOOTER UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Sharpshooter"), Right, 8, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("-10% BOSS HEALTH"), Custom String("KILL Bosses {0}/{1}", + Global.UpgradeBossHealthValue, Global.UpgradeCriticalDamageMaxValue[2]), Left, 14, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[2] = Last Text ID; + Global.Perk[0] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[18] = Last Text ID; + Global.challengeCount += 1; + } +} + +disabled rule("PLAYER: UPGRADE - -10% BOSS HEALTH - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]; + Global.UpgradeBossHealthValue < Global.UpgradeCriticalDamageMaxValue[2]; + Victim.isBoss == 1; + } + + actions + { + Global.UpgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - -10% BOSS HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("-10% BOSS HEALTH UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "-10% BOSS HEALTH"), Right, 9, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[2] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - MAX AMMO - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Zenyatta); + Global.UpgradeMaxAmmoValue < Global.UpgradeMaxAmmoMaxValue[2]; + } + + actions + { + If(Event Player.isBoss == 1); + Global.UpgradeMaxAmmoValue += 10; + Else; + Global.UpgradeMaxAmmoValue += 1; + End; + } +} + +rule("GLOBAL: UPGRADE - MAX AMMO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("MAX AMMO 200% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "MAX AMMO 200%"), Right, 10, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("Bulletstorm: Your weapon can hold unlimited ammo"), + Custom String("KILL {2}: {0}/{1}", Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[1], Hero(Zenyatta)), Left, 15, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0) * 2); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1) * 2); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0)); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1)); + End; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK BULLETSTORM - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("BULLETSTORM UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Bulletstorm"), Right, 11, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("+50% DAMAGE"), Custom String("KILL {2}: {0}/{1}", + Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[2], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[2] = Last Text ID; + Global.Perk[1] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[19] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - +50% DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("+50% DAMAGE UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "+50% DAMAGE"), Right, 12, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[2] = Last Text ID; + Global.DamageDone = 50; + All Players(Team 1).DamageDealt = 100 + Global.DamageDone + All Players(Team 1).Abilities[13] * 5; + Set Damage Dealt(All Players(Team 1), All Players(Team 1).DamageDealt); + Global.challengeCount += 1; + } +} + +disabled rule("=== GAME PHASES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: ASEMBLING PHASE - MAKE CHALLENGES HUDS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Assembling Heroes == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Disable Inspector Recording; + Set Match Time(20); + End; + Create In-World Text(All Players(Team 1), Custom String(" {0}\r\nREPAIR\r\n {1}", Hero Icon String(Hero(Torbjörn)), + Ability Icon String(Hero(Bastion), Button(Secondary Fire))), Global.GatePosition + Vector(0, 1.400, 0), 1.200, Do Not Clip, + Visible To, Color(White), Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("TEAM CHALLENGES"), Left, 11, Color(White), Color(Blue), Color( + White), Visible To, Default Visibility); + "UPGRADE - GATE'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String( + "GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Custom String("REPAIR GATE {0}/{1} HP", + Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[0]), Left, 12, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 2, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - PLAYER'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +50%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[0]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 4, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - CRITICAL DAMAGE" + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("CRITICAL DAMAGE 150%"), Custom String( + "KILL WIDOW WITH HEADSHOT: {0}/{1}", Global.UpgradeCriticalDamageValue, Global.UpgradeCriticalDamageMaxValue[0]), Left, 14, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 6, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - MAX AMMO" + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("MAX AMMO 200%"), Custom String("KILL {2}: {0}/{1}", + Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[0], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Custom String("HOLD {0} - Reload to open the shop", Input Binding String(Button(Reload))), + Null, Null, Top, 1000, Color(Yellow), Color(White), Color(White), Visible To and String, Default Visibility); + } +} + +rule("GLOBAL: SETUP PHASE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Set Match Time(20); + End; + Set Objective Description(All Players(All Teams), Custom String("DEFEND GATE"), Visible To and String); + } +} + +rule("GLOBAL: GAME IN PROGRESS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + } + + actions + { + Set Match Time(3599); + Pause Match Time; + Disable Built-In Game Mode Scoring; + Disable Built-In Game Mode Announcer; + Disable Built-In Game Mode Completion; + Disable Game Mode HUD(All Players(All Teams)); + Disable Game Mode In-World UI(All Players(All Teams)); + Global.GateHealth = Global.GateMaxHealth; + Global.GateHealthChase = Global.GateHealth; + Global.GateProgressBarColorComponent = 255; + Global.GateProgressBarColorCurrent = Color(White); + Create Progress Bar HUD Text(All Players(Team 1), Global.GateHealthChase * 100 / Global.GateMaxHealth, Custom String( + "GATE {0}/{1}", Global.GateHealth, Global.GateMaxHealth), Top, 1, Global.GateProgressBarColorCurrent, Color(White), + Visible To Values and Color, Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("SURVIVED TIME: {0}:{1}", Global.TimeMin, + Global.TimeSec < 10 ? Custom String("0{0}", Global.TimeSec) : Global.TimeSec), Top, 2, Color(White), Color(White), Color( + White), Visible To and String, Default Visibility); + Start Rule(GameLogicWave0, Do Nothing); + } +} + +disabled rule("=== GAME - MAIN LOGIC ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: DEFEAT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.IsDebug == False; + Global.GateHealth <= 0; + } + + actions + { + Declare Team Victory(Team 2); + } +} + +rule("GLOBAL: TIMER - MAIN GAME LOOP") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + disabled Global.GateHealth > 0; + } + + actions + { + Wait(1, Ignore Condition); + Global.TimeSec += 1; + If(Global.TimeSec == 60); + Global.TimeSec = 0; + Global.TimeMin += 1; + Global.Time5Min = Round To Integer(Global.TimeMin / 5, Down); + Global.Time10Min = Round To Integer(Global.TimeMin / 10, Down); + Global.SpawnPositionMaxId += 1; + disabled Start Rule(GameLogicAddNextHeroInGame, Restart Rule); + Else If(Global.TimeSec == 30); + Global.SpawnPositionMaxId += 1; + End; + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GAME LOGIC - ADD NEXT HERO IN GAME") +{ + event + { + Subroutine; + GameLogicAddNextHeroInGame; + } + + actions + { + "REDUCE RESPAWN TIME FOR ZENS" + disabled Global.ZenRespawnTime -= 1.500; + disabled Global.ZenRespawnTime = Max(1, Global.ZenRespawnTime); + disabled Set Respawn Max Time(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Global.DefaultHeroBotsPool[0]), + Global.ZenRespawnTime); + "ALL HEROES WAS ADDED IN GAME" + Abort If(Global.DefaultHeroBotsPoolCurrentId == Count Of(Global.DefaultHeroBotsPool) - 1); + Global.DefaultHeroBotsPoolCurrentId += 1; + "ВРЕМЕННЫЙ КОСТЫЛЬ ЧТОБЫ ЭХО ЗАМЕНИЛА ХАМСТЕРА" + If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Hero(Echo)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Abort; + End; + "ABORT IF NEXT HERO IN ARRAY ORDER IS NULL" + Abort If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Null); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId], Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("SUBROUTINE: GAME LOGIC - SET BOT PROPERTIES") +{ + event + { + Subroutine; + GameLogicSetBotProperties; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + If(Global.TimeMin >= 10); + If(Filtered Array(Global.lastBoss, Current Array Element == Hero Of(Event Player)) == False); + If(Global.activeBoss == False); + If(Global.bossTrigger < Global.TimeMin); + Global.bossTrigger = Global.TimeMin; + Global.activeBoss = Event Player; + Event Player.isBoss = 1; + Big Message(All Players(Team 1), Custom String("BOSS SPAWNED - {0}", Hero Of(Event Player))); + End; + End; + End; + End; + "PROPERTIES BY DEFAULT" + Set Gravity(Event Player, 100); + Set Damage Dealt(Event Player, 100); + Set Respawn Max Time(Event Player, 10); + Start Scaling Player(Event Player, 1, False); + "INDIVIDUAL HERO'S PROPERTIES" + If(Hero Of(Event Player) == Hero(Zenyatta)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 30); + Set Max Health(Event Player, 5 * (100 + Global.TimeMin * 10) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 1.500, False); + Else; + If(20 + 3 * Number Of Players(Team 1) + 3 * Global.TimeMin > 75); + Set Move Speed(Event Player, 75); + Else; + Set Move Speed(Event Player, 20 + 3 * Count Of(All Players(Team 1)) + 3 * Global.TimeMin); + End; + Set Max Health(Event Player, 100 + Global.TimeMin * 10); + End; + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 20); + Set Max Health(Event Player, 5 * (70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + If(30 + Global.TimeMin + 2.500 * Global.Time5Min > 50); + Set Move Speed(Event Player, 50); + Else; + Set Move Speed(Event Player, 30 + Global.TimeMin + 2.500 * Global.Time5Min); + End; + Set Ultimate Charge(Event Player, 0); + Set Max Health(Event Player, 70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + If(Event Player.isBoss == 1); + Set Damage Dealt(Event Player, 2 * (85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min)); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 5 * (100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Event Player.BotCounter = 0; + Set Damage Dealt(Event Player, 85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Bastion)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 50); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Start Scaling Player(Event Player, 3, False); + Set Max Health(Event Player, 5 * (155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Else; + Set Move Speed(Event Player, 80); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Start Scaling Player(Event Player, 2, False); + Set Max Health(Event Player, 155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Orisa)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 5 * (220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Set Move Speed(Event Player, 30 + 5 * Global.Time5Min); + Else; + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min); + Set Move Speed(Event Player, 90 + 5 * Global.Time5Min); + End; + Else If(Hero Of(Event Player) == Hero(Echo)); + If(Event Player.isBoss == 1); + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 70 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 5 * (90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 130 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.500, False); + Set Move Speed(Event Player, 70); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 5 * (55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Else; + disabled Start Scaling Player(Event Player, 0.850, False); + Set Move Speed(Event Player, 110); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin); + End; + End; + Wait(0.250, Ignore Condition); + "FILL HEALTH" + Heal(Event Player, Null, 100000); + } +} + +disabled rule("=== GATE ===") +{ + event + { + Ongoing - Global; + } +} + +rule("TORB: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Has Spawned(Event Player) == True; + Weapon(Event Player) == 2; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500; + Is Game In Progress == True; + } + + actions + { + Small Message(Event Player, Custom String("REPAIR +2% ULTIMATE")); + "UPGRADE - GATE'S MAX HEALTH" + If(Global.UpgradeGateMaxHealthValue < Global.UpgradeGateMaxHealthMaxValue[2]); + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 100 - Number Of Players(Team 1) * 20; + Else; + Global.UpgradeGateMaxHealthValue += 50 - Number Of Players(Team 1) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 50 - Number Of Players(Team 1) * 10; + Else; + Global.UpgradeGateMaxHealthValue += 25 - Number Of Players(Team 1) * 5; + End; + End; + End; + "HEAL GATE" + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 100 - Number Of Players(Team 1) * 20; + Else; + Global.GateHealth += 50 - Number Of Players(Team 1) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 50 - Number Of Players(Team 1) * 10; + Else; + Global.GateHealth += 25 - Number Of Players(Team 1) * 5; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + "CHARGE ULTIMATE" + Else; + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + End; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(Is Using Ability 2(Event Player) == True ? 0.350 : 0.700, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Brig: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 5; + Is Game In Progress == True; + } + + actions + { + Small Message(Event Player, Custom String("REPAIR +2% ULTIMATE")); + "UPGRADE - GATE'S MAX HEALTH" + If(Global.UpgradeGateMaxHealthValue < Global.UpgradeGateMaxHealthMaxValue[2]); + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 100 - Number Of Players(Team 1) * 20; + Else; + Global.UpgradeGateMaxHealthValue += 50 - Number Of Players(Team 1) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 50 - Number Of Players(Team 1) * 10; + Else; + Global.UpgradeGateMaxHealthValue += 25 - Number Of Players(Team 1) * 5; + End; + End; + End; + "HEAL GATE" + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 100 - Number Of Players(Team 1) * 20; + Else; + Global.GateHealth += 50 - Number Of Players(Team 1) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 50 - Number Of Players(Team 1) * 10; + Else; + Global.GateHealth += 25 - Number Of Players(Team 1) * 5; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + "CHARGE ULTIMATE" + Else; + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + End; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Rein: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + Is Game In Progress == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Small Message(Event Player, Custom String("REPAIR +2% ULTIMATE")); + "UPGRADE - GATE'S MAX HEALTH" + If(Global.UpgradeGateMaxHealthValue < Global.UpgradeGateMaxHealthMaxValue[2]); + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 100 - Number Of Players(Team 1) * 20; + Else; + Global.UpgradeGateMaxHealthValue += 50 - Number Of Players(Team 1) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 50 - Number Of Players(Team 1) * 10; + Else; + Global.UpgradeGateMaxHealthValue += 25 - Number Of Players(Team 1) * 5; + End; + End; + End; + "HEAL GATE" + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 100 - Number Of Players(Team 1) * 20; + Else; + Global.GateHealth += 50 - Number Of Players(Team 1) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 50 - Number Of Players(Team 1) * 10; + Else; + Global.GateHealth += 25 - Number Of Players(Team 1) * 5; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + "CHARGE ULTIMATE" + Else; + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + End; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.850, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GATE PROGRESS BAR COLOR") +{ + event + { + Subroutine; + GateProgressBarColor; + } + + actions + { + Stop Chasing Global Variable(GateHealthChase); + Chase Global Variable Over Time(GateHealthChase, Global.GateHealth, 0.100, Destination and Duration); + "GATE WAS DAMAGED" + If(Global.GateHealth < Global.GateHealthEvent); + For Global Variable(LoopIterator1, 0, 3, 1); + Global.GateProgressBarColorCurrent = Color(Red); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(White); + Wait(0.030, Ignore Condition); + End; + "GATE WAS REPAIRED" + Else; + Global.GateProgressBarColorCurrent = Color(Green); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(Yellow); + Wait(0.030, Ignore Condition); + End; + Global.GateHealthEvent = Global.GateHealth; + Global.GateProgressBarColorComponent = Global.GateHealth * 255 / Global.GateMaxHealth; + Global.GateProgressBarColorCurrent = Custom Color(255, Global.GateProgressBarColorComponent, Global.GateProgressBarColorComponent, + 255); + } +} + +disabled rule("=== COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("ALL: INIT") +{ + event + { + Player Joined Match; + All; + All; + } + + actions + { + "ALL (COMMON) INIT" + Event Player.IsDead = True; + Disable Kill Feed(Event Player); + Disable Game Mode In-World UI(Event Player); + Disable Death Spectate Target HUD(Event Player); + "BOT INIT" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotInit); + "PLAYER INIT" + Else; + Call Subroutine(PlayerInit); + End; + } +} + +rule("SUBROUTINE: BOT - INIT") +{ + event + { + Subroutine; + BotInit; + } + + actions + { + "INIT VARS" + Event Player.HasBadStatus = False; + Event Player.IsRespawning = False; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEventPosition = Vector(9999, 999, 9999); + "DISABLE ALL FOR BOT" + Disable Hero HUD(Event Player); + Disable Messages(Event Player); + Disable Text Chat(Event Player); + Disable Scoreboard(Event Player); + Disable Game Mode HUD(Event Player); + Disable Death Spectate All Players(Event Player); + Disable Voice Chat(Event Player, True, True, True); + "INIT AI NAVIGATION VARS" + Call Subroutine(BotResetPathFinding); + } +} + +rule("SUBROUTINE: PLAYER - INIT") +{ + event + { + Subroutine; + PlayerInit; + } + + actions + { + "STORY HEROES" + If(Global.IsStoryHeroes); + Reset Player Hero Availability(Event Player); + Set Player Allowed Heroes(Event Player, Array(Hero(Ana), Hero(Brigitte), Hero(Mercy), Hero(Lúcio), Hero(Moira), Hero(Baptiste), + Hero(Ashe), Hero(D.Va), Hero(Genji), Hero(Hanzo), Hero(Widowmaker), Hero(Cassidy), Hero(Reinhardt), Hero(Soldier: 76), Hero( + Torbjörn), Hero(Tracer), Hero(Winston), Hero(Pharah))); + End; + "TEAM CHALLENGE - PLAYER'S MAX HEALTH" + If(Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0]); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + End; + If(Is Game In Progress); + Disable Game Mode HUD(Event Player); + End; + } +} + +rule("ALL: RESPAWN") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + (Hero Of(Event Player) != Event Player.CurrentHero || Event Player.IsDead == True) == True; + } + + actions + { + Event Player.IsDead = False; + "BOT RESPAWN" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotRespawn); + If(Global.IsDebugAINavigation); + Create Beam Effect(All Players(All Teams), Good Beam, Eye Position(Event Player), Event Player.BotNextNodePosition, Color(Green), + Visible To Position and Radius); + End; + "PLAYER RESPAWN" + Else; + Call Subroutine(PlayerRespawn); + End; + "MUST BE AFTER ALL RESPAWN SUBROUTINES!" + Event Player.CurrentHero = Hero Of(Event Player); + } +} + +rule("SUBROUTINE: BOT - RESPAWN") +{ + event + { + Subroutine; + BotRespawn; + } + + actions + { + "RESET COMMON PROPERTIES" + Event Player.IsRespawning = True; + Enable Nameplates(Event Player, All Players(Team 1)); + Call Subroutine(BotResetPathFinding); + disabled If(Hero Of(Event Player) != Event Player.CurrentHero); + Call Subroutine(GameLogicSetBotProperties); + disabled End; + "INDIVIDUAL HERO'S RESPAWN SCRIPTS" + If(Hero Of(Event Player) == Hero(Bastion)); + Call Subroutine(BotBastionRespawn); + Else If(Hero Of(Event Player) == Hero(Zenyatta)); + Call Subroutine(BotZenyattaRespawn); + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + Call Subroutine(BotWidowRespawn); + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Call Subroutine(BotBallRespawn); + Else If(Hero Of(Event Player) == Hero(Orisa)); + Call Subroutine(BotOrisaRespawn); + Else If(Hero Of(Event Player) == Hero(Echo)); + Call Subroutine(BotEchoRespawn); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Call Subroutine(BotReinRespawn); + End; + Event Player.IsRespawning = False; + } +} + +rule("SUBROUTINE: PLAYER - RESPAWN") +{ + event + { + Subroutine; + PlayerRespawn; + } + + actions + { + "TEAM CHALLENGE - MAX AMMO" + If(Hero Of(Event Player) != Event Player.CurrentHero && Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]); + Set Max Ammo(Event Player, 0, Ammo(Event Player, 0) * 2); + Set Max Ammo(Event Player, 1, Ammo(Event Player, 1) * 2); + Set Ammo(Event Player, 0, Max Ammo(Event Player, 0)); + Set Ammo(Event Player, 1, Max Ammo(Event Player, 1)); + End; + "MUST BE AFTER TEAM CHALLENGE MAX AMMO!" + disabled Event Player.CurrentHero = Hero Of(Event Player); + "PLAYER RESPAWN" + Set Status(Event Player, Null, Phased Out, 3); + Set Facing(Event Player, Vector(-1, 0, 0), To World); + Teleport(Event Player, Global.PlayerSpawnPositions[Slot Of(Event Player) == Count Of(Global.PlayerSpawnPositions) ? Random Integer( + 0, Count Of(Global.PlayerSpawnPositions) - 1) : Slot Of(Event Player)]); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + } +} + +rule("PLAYER: DEATH") +{ + event + { + Player Died; + Team 1; + All; + } + + actions + { + If(Hero Of(Event Player) == Hero(Roadhog)); + Event Player.Abilities[8] -= 1; + Wait(Global.Perk[2] ? 5 : 10, Ignore Condition); + Event Player.Abilities[8] += 1; + End; + disabled If(Event Player.lastSecondWind > 0); + disabled Event Player.lastSecondWind = 0; + disabled End; + Event Player.IsDead = True; + } +} + +rule("BOT: DEATH") +{ + event + { + Player Died; + Team 2; + All; + } + + actions + { + If(Event Player.isBoss == 1); + If(Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]); + If(Global.UpgradeBossHealthValue < Global.UpgradeCriticalDamageMaxValue[2]); + Global.UpgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + End; + End; + Event Player.isBoss = 0; + Global.activeBoss = Null; + Big Message(All Players(Team 1), Custom String("BOSS DIED - {0}", Hero Of(Event Player))); + End; + Event Player.IsDead = True; + Event Player.HasBadStatus = False; + Event Player.BotDoesUniqueBehaviour = False; + Disable Nameplates(Event Player, All Players(Team 1)); + disabled Stop Holding Button(Event Player, Button(Ability 1)); + disabled Stop Holding Button(Event Player, Button(Primary Fire)); + disabled Stop Holding Button(Event Player, Button(Secondary Fire)); + "BOT HAS 1 EFFECT IN VAR (NOT ARRAY)" + Skip If(!Entity Exists(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects); + "BOT HAS MORE THEN 1 EFFECT IN VAR (ARRAY)" + Skip If(Count Of(Event Player.BotEffects) == 0, 3); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects[Event Player.BotLoopIterator1]); + End; + } +} + +disabled rule("=== BOT COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BAD STATUS") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + Event Player.HasBadStatus = True; + "PROCESS BAD STATUS" + If(Hero Of(Event Player) == Hero(Widowmaker)); + Start Rule(BotWidowBadStatus, Do Nothing); + End; + Wait Until(!Has Status(Event Player, Knocked Down) && !Has Status(Event Player, Asleep) && !Has Status(Event Player, Frozen) + && !Has Status(Event Player, Stunned), 15); + Event Player.HasBadStatus = False; + } +} + +rule("SUBROUTINE: BOT - LANDING FROM SKY") +{ + event + { + Subroutine; + BotLandingFromSky; + } + + actions + { + Stop Throttle In Direction(Event Player); + "SET RESPAWN POSITION" + Event Player.BotEventPosition = Random Value In Array(Global.BigBossSpawnPositions); + "CREATE EFFECTS" + disabled Create Effect(All Players(All Teams), Light Shaft, Color(Red), Event Player.BotEventPosition, 3, Visible To); + disabled Event Player.BotEffects = Last Created Entity; + "RESPAWN IN LIGHT SHAFT EFFECT" + Teleport(Event Player, Event Player.BotEventPosition + Vector(0, 25, 0)); + Wait(0.020, Ignore Condition); + "SLOW LANDING" + Set Gravity(Event Player, 50); + While(Is In Air(Event Player) == True); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Position Of(Event Player) + Vector(0, -2.700, 0), 2); + Wait(0.250, Ignore Condition); + End; + Set Gravity(Event Player, 100); + disabled Destroy Effect(Event Player.BotEffects); + "LANDING EFFECTS" + Play Effect(All Players(All Teams), Wrecking Ball Piledriver Impact Effect, Custom Color(105, 87, 46, 255), Position Of( + Event Player), 8); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Sound, Color(White), Position Of(Event Player), 150); + } +} + +rule("SUBROUTINE: BOT - APPEAR FROM UNDERGROUND") +{ + event + { + Subroutine; + BotApearFromUnderground; + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1); + Wait(0.200, Ignore Condition); + Set Gravity(Event Player, 20); + Disable Movement Collision With Environment(Event Player, True); + Teleport(Event Player, Global.ZenSpawnPositions[Random Integer(Min(Global.TimeMin, Count Of(Global.ZenSpawnPositions) - 10), Min( + Global.SpawnPositionMaxId, Count Of(Global.ZenSpawnPositions) - 4))] + Vector(0, -1.500, 0)); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Sigma Accretion Impact Effect, Custom Color(220, 175, 100, 255), Eye Position(Event Player), + 3); + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(Gray), Eye Position(Event Player), 50); + Apply Impulse(Event Player, Up, 3.500, To World, Cancel Contrary Motion); + Wait(0.400, Ignore Condition); + Clear Status(Event Player, Knocked Down); + Set Gravity(Event Player, 100); + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("=== PLAYER MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("PLAYER: DARKNESS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + !Entity Exists(Event Player.BotEffects) == True; + } + + actions + { + Disable Nameplates(Event Player, All Players(All Teams)); + Start Forcing Player Outlines(Event Player, All Players(All Teams), False, Color(White), Default); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 14), 25, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(-5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + } +} + +rule("PLAYER: HEALTH REGEN") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + actions + { + Stop Heal Over Time(Event Player.HealOverTimeId); + Event Player.EventHealth = Health(Event Player); + Wait(4, Ignore Condition); + "TOOK DAMAGE, RESET REGENERATION TIMER" + Loop If(Is Alive(Event Player) && Event Player.EventHealth > Health(Event Player)); + Start Heal Over Time(Event Player, Null, 3, Max Health(Event Player) / 3); + Event Player.HealOverTimeId = Last Heal Over Time ID; + } +} + +disabled rule("=== NERFS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("REINHARDT: ANTI-CHARGE FOR BASTION & ORISA") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Using Ability 1(Event Player) == True; + Hero Of(Ray Cast Hit Player(Eye Position(Event Player) + Vector(0, 2, 0), Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 2, All Living Players(Team 2), Event Player, True)) == (Hero(Bastion) == True || Hero( + Orisa) == True); + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1.500); + } +} + +rule("HOG: ANTI-HOOK FOR BASTION & ORISA") +{ + event + { + Player Dealt Damage; + Team 1; + Roadhog; + } + + conditions + { + Event Ability == Button(Ability 1); + (Hero Of(Victim) == Hero(Bastion) || Hero Of(Victim) == Hero(Orisa)) == True; + } + + actions + { + Set Status(Event Player, Null, Stunned, 0.005); + } +} + +disabled rule("=== ZENYATTA ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ZEN - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Zenyatta; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + } + + actions + { + Set Ammo(Event Player, 0, 0); + Communicate(Event Player, Hello); + disabled Call Subroutine(BotResetPathFinding); + Wait(1.500, Ignore Condition); + Abort If(Is Dead(Event Player) == True); + Kill(Event Player, Null); + } +} + +rule("BOT: ZEN - DEATH") +{ + event + { + Player Died; + Team 2; + Zenyatta; + } + + actions + { + "EFFECT" + Play Effect(All Players(All Teams), Junkrat Frag Launcher Explosion Effect, Color(Red), Eye Position(Event Player), 2.500); + Play Effect(All Players(All Teams), Ashe Dynamite Explosion Sound, Color(Red), Eye Position(Event Player), 70); + "DAMAGE AND APPLY IMPULSE TO PLAYERS" + Event Player.BotPlayersInRadius = Players Within Radius(Position Of(Event Player), 2.500, All Teams, Surfaces And Enemy Barriers); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotPlayersInRadius), 1); + Apply Impulse(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Direction Towards(Position Of(Event Player), + Eye Position(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1])), 5, To World, Incorporate Contrary Motion); + If(Team Of(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1]) == Team 1); + Damage(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Event Player, 50); + End; + End; + "DAMAGE GATE" + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 125; + Else; + Global.GateHealth -= 25; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Respawn(Event Player); + Abort; + End; + "KILLED BY PLAYER" + Teleport(Event Player, Vector(0, -999, 0)); + Wait(2, Ignore Condition); + Respawn(Event Player); + Wait(2, Ignore Condition); + } +} + +rule("SUBROUTINE: ZEN - RESPAWN") +{ + event + { + Subroutine; + BotZenyattaRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WRECKING BALL ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BALL - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + disabled Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Set Ammo(Event Player, 0, 0); + Wait(1, Ignore Condition); + Set Ultimate Charge(Event Player, 100); + Start Holding Button(Event Player, Button(Ultimate)); + Wait Until(Is Using Ultimate(Event Player), 0.600); + Abort If(Is Dead(Event Player)); + Kill(Event Player, Null); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Effect, Color(Orange), Eye Position(Event Player), 6); + Play Effect(All Players(All Teams), DVa Self Destruct Explosion Sound, Color(White), Eye Position(Event Player), 250); + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 300; + Else; + Global.GateHealth -= 150; + End; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Damage(Players Within Radius(Eye Position(Event Player), 7, Team 1, Surfaces And All Barriers), Event Player, 200); + } +} + +rule("BOT: BALL - ALTERNATIVE FORM") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is In Alternate Form(Event Player) == False; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is In Alternate Form(Event Player), 10); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: BALL - DEATH") +{ + event + { + Player Died; + Team 2; + Wrecking Ball; + } + + actions + { + Stop Holding Button(Event Player, Button(Ability 1)); + Stop Holding Button(Event Player, Button(Ultimate)); + } +} + +rule("SUBROUTINE: BALL - RESPAWN") +{ + event + { + Subroutine; + BotBallRespawn; + } + + actions + { + "RESPAWN IN AIR" + Teleport(Event Player, Random Value In Array(Global.BallSpawnPositions) + Vector(0, 20, 0)); + Stop Holding Button(Event Player, Button(Ultimate)); + Wait(0.250, Ignore Condition); + "LANDING" + Start Holding Button(Event Player, Button(Crouch)); + Wait Until(Is On Ground(Event Player), 9999); + Stop Holding Button(Event Player, Button(Crouch)); + "LANDING IMPACT EFFECT" + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(White), Event Player, 150); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Effect, Color(Gray), Position Of(Event Player), 10); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Eye Position(Event Player), 1.500, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + "PATH FINDING TO GATE" + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +disabled rule("=== ECHO ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ECHO - FLY ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is Using Ability 1(Event Player) == False; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), 0); + Press Button(Event Player, Button(Ability 1)); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - BEAM ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Using Ability 1(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == True; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - BAD STATUS - RESET BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.HasBadStatus == True; + disabled (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + Wait Until(Event Player.HasBadStatus, 7); + } +} + +rule("BOT: ECHO - CAN'T SEE PORTAL - APPLY IMPULSE") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == True; + Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Wait(0.300, Abort When False); + Apply Impulse(Event Player, Vector(Random Integer(-1, 1), 1, Random Integer(-1, 1)), 20, To World, Incorporate Contrary Motion); + Wait(1, Ignore Condition); + If(!Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + Event Player.BotTargetPosition = Global.BotEchoRespawnPosition; + Start Rule(BotStartPathFinding, Restart Rule); + Else; + Call Subroutine(BotResetPathFinding); + End; + Loop If Condition Is True; + } +} + +disabled rule("BOT: ECHO - MAIN LOGIC - BACKUP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(!Event Player.BotIsPathFinding); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Is In Line of Sight(Eye Position(Event Player), + Eye Position(Current Array Element), Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), + Position Of(Current Array Element)))[0]; + End; + "NO PLAYERS IN VIEW RANGE" + disabled If(Event Player.BotSeePlayer == Null); + disabled Stop Throttle In Direction(Event Player); + disabled End; + "FLY TO PLAYER" + If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + > 4 && Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + "ACTIVATE FOCUS BEAM" + Else If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + < 4 && Event Player.BotDoesUniqueBehaviour == False && Event Player.HasBadStatus == False); + Event Player.BotDoesUniqueBehaviour = True; + Set Status(Event Player.BotSeePlayer, Event Player, Stunned, 1); + Set Status(Event Player.BotSeePlayer, Event Player, Hacked, 99999); + Attach Players(Event Player.BotSeePlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + "TELEPORT PLAYER TO AWAY" + Else If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotSeePlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotSeePlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotSeePlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + "BEGIN TO FLY TO THE PORTAL" + Else If(Event Player.BotDoesUniqueBehaviour == True); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + End; + "TELEPORT PLAYER SO FAR" + If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotEchoCapturedPlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotEchoCapturedPlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + End; + "BEGIN TO FLY TO THE PORTAL WITH A PLAYER" + If(Event Player.BotDoesUniqueBehaviour); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotEchoCapturedPlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - DEFEND PORTAL") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + } + + actions + { + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPlayer); + } +} + +rule("BOT: ECHO - PATH FINDING TO PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Call Subroutine(BotStartPathFinding); + } +} + +rule("BOT: ECHO - ATTACH PLAYER BY BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotEchoCapturedPlayer == Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 3; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Event Player.BotEchoCapturedPlayer = Event Player.BotSeePlayer; + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Stunned, 0.700); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Hacked, 10); + Attach Players(Event Player.BotEchoCapturedPlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - PLAYER DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Dead(Event Player.BotEchoCapturedPlayer) != Null; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - DEATH") +{ + event + { + Player Died; + Team 2; + Echo; + } + + actions + { + Call Subroutine(BotEchoDetachPlayer); + Stop Holding Button(Event Player, Button(Jump)); + Wait(5, Ignore Condition); + Teleport(Event Player, Vector(0, 999, 0)); + Start Forcing Player To Be Hero(Event Player, Hero(Orisa)); + } +} + +rule("SUBROUTINE: ECHO - RESPAWN") +{ + event + { + Subroutine; + BotEchoRespawn; + } + + actions + { + Event Player.BotCounter = 0; + Event Player.BotEffects = Empty Array; + Create Effect(All Players(All Teams), Good Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Energy Sound, Color(White), Global.BotEchoRespawnPosition, 200, Visible To); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Chase Player Variable Over Time(Event Player, BotCounter, 3, 0.800, Destination and Duration); + Play Effect(All Players(All Teams), Sombra EMP Explosion Effect, Color(Sky Blue), Global.BotEchoRespawnPosition, 12); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Null, Global.BotEchoRespawnPosition, 100); + Wait(3, Ignore Condition); + Teleport(Event Player, Global.BotEchoRespawnPosition); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Global.BotEchoRespawnPosition, 2.500); + Play Effect(All Players(All Teams), Debuff Impact Sound, Null, Global.BotEchoRespawnPosition, 100); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PLAYER") +{ + event + { + Subroutine; + BotEchoFlyToPlayer; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Stop Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PORTAL") +{ + event + { + Subroutine; + BotEchoFlyToPortal; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - DETACH PLAYER") +{ + event + { + Subroutine; + BotEchoDetachPlayer; + } + + actions + { + Detach Players(Event Player.BotEchoCapturedPlayer); + Clear Status(Event Player.BotEchoCapturedPlayer, Hacked); + "IF PLAYER INSIDE THE WALL" + If(Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotEchoCapturedPlayer), Barriers Do Not Block LOS)); + Teleport(Event Player.BotEchoCapturedPlayer, Position Of(Event Player)); + End; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEchoCapturedPlayer = Null; + } +} + +disabled rule("=== REINHARDT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: REIN - SET PLAYER AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + disabled Event Player.BotIsPathFinding == False; + "BOT IS FAR FROM GATES" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Global.GatePosition), 0, Z Component Of(Global.GatePosition))) > 20; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET CLOSEST PLAYER TO BOT AS TARGET AND FOLLOW HIM" + Event Player.BotTargetPlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - SET GATE AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "BOT DOESN'T FOLLOW PLAYER" + Event Player.BotTargetPlayer == -1; + "CAN'T SEE ANY PLAYER" + disabled Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), !Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET GATE AS TARGET" + Event Player.BotTargetPosition = Global.GatePosition; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - TARGET DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer != -1; + Is Dead(Event Player.BotTargetPlayer) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + } +} + +rule("BOT: REIN - ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) < 4; + "CAN ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) < 4; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + "TARGET IS PLAYER" + Abort If(Event Player.BotTargetPlayer != -1); + If(Event Player.isBoss == 1); + "TARGET IS GATE" + Global.GateHealth -= 25; + Else; + Global.GateHealth -= 5; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: REIN - STOP ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) > 4; + "CAN'T ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) > 4; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + } +} + +rule("BOT: REIN - USE SHIELD") +{ + event + { + Player Took Damage; + Team 2; + Reinhardt; + } + + conditions + { + Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) > 3; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Attacker)), 200, To World, + Direction and Turn Rate); + Start Holding Button(Event Player, Button(Secondary Fire)); + Wait Until(Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) < 3, 3); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("BOT: REIN - CHARGE IN GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer == -1; + Is Using Ability 1(Event Player) == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == True; + Is In View Angle(Event Player, Global.GatePosition, 7.500) == True; + } + + actions + { + disabled Wait(0.800, Abort When False); + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is Using Ability 1(Event Player), 1); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: REIN - DEATH") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("SUBROUTINE: REIN - RESPAWN") +{ + event + { + Subroutine; + BotReinRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WIDOW ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: WIDOW - SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer == Null; + Event Player.HasBadStatus == False; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Event Player.BotWidowShotTime = Total Time Elapsed + (Global.TimeMin >= 9 ? Random Real(2, 5) : Random Real(5, 10)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 9999, To World, + Direction and Turn Rate); + } +} + +rule("BOT: WIDOW - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer != Null; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowShotTime; + } + + actions + { + Press Button(Event Player, Button(Primary Fire)); + Stop Facing(Event Player); + Event Player.BotSeePlayer = Null; + } +} + +rule("BOT: WIDOW - Aim Sound") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Alive(Event Player) == True; + Is In Line of Sight(Eye Position(Players On Hero(Hero(Widowmaker), Team 2)), Eye Position(Event Player), Barriers Do Not Block LOS) + == True; + Is Alive(Players On Hero(Hero(Widowmaker), Team 2)) == True; + Players On Hero(Hero(Widowmaker), Team 2).BotSeePlayer == True; + } + + actions + { + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 100); + Wait(1, Abort When False); + Loop If Condition Is True; + } +} + +rule("BOT: WIDOW - TELEPORT TO NEW POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowTeleportTime; + } + + actions + { + Event Player.BotWidowTeleportTime = Total Time Elapsed + 28; + Event Player.BotWidowShotTime = Total Time Elapsed + Random Real(1, 1.600); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Event Player, 1); + Wait(0.016, Ignore Condition); + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + } +} + +rule("BOT: WIDOW - DEATH") +{ + event + { + Player Died; + Team 2; + Widowmaker; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + Wait(0.250, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - RESPAWN") +{ + event + { + Subroutine; + BotWidowRespawn; + } + + actions + { + "RESPAWN ON RANDOM SNIPER POSITION" + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Wait(0.700, Ignore Condition); + Start Holding Button(Event Player, Button(Secondary Fire)); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait Until(Is Dead(Event Player), 99999); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - BAD STATUS") +{ + event + { + Subroutine; + BotWidowBadStatus; + } + + actions + { + Stop Facing(Event Player); + Destroy Effect(Event Player.BotEffects); + Wait Until(!Event Player.HasBadStatus, 15); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + } +} + +disabled rule("=== BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("BOT: BASTION - FLAME GUN") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 50) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 8; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Stop Holding Button(Event Player, Button(Primary Fire)); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Update Every Frame(Eye Position(Event Player) + World Vector Of( + Vector(-1, -1.200, 1.800), Event Player, Rotation)), 1, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Start Rule(BotBastionFlameGunDamage, Do Nothing); + Wait(1.100, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(4, Ignore Condition); + Loop If Condition Is True; + } +} + +disabled rule("BOT: BASTION - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + disabled Event Player.BotSeePlayer == Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - CAN'T SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == False; + } + + actions + { + Event Player.BotSeePlayer = Null; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - MOVE TO BASTION'S TARGET (POSITION)") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotTargetPosition = Random Value In Array(Filtered Array(Global.BastionTargetPositions, Distance Between(Position Of( + Event Player), Current Array Element) > 3.500)); + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("BOT: BASTION - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + "SEE THE PLAYER" + If(Event Player.BotSeePlayer != Null); + Stop Holding Button(Event Player, Button(Secondary Fire)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer) - Vector(0, 0.500, + 0)), 100, To World, Direction and Turn Rate); + "SELF REPAIRING" + Else If(!Is Firing Secondary(Event Player) && Health(Event Player) < Max Health(Event Player)); + Start Holding Button(Event Player, Button(Secondary Fire)); + End; + "START FOLLOW PATH" + disabled If(!Event Player.BotIsPathFinding && !Event Player.BotDoesUniqueBehaviour); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled Wait(0.050, Ignore Condition); + disabled Event Player.BotTargetPosition = Random Value In Array(Global.BastionTargetPositions); + disabled Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Event Player.BotTargetPosition + Vector(0, 2, 0)), 100, + To World, Direction and Turn Rate); + disabled Start Rule(BotStartPathFinding, Do Nothing); + "REACHED PATH TARGET" + disabled Else If(Distance Between(Position Of(Event Player), Event Player.BotTargetPosition) <= 3); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled End; + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - ARTILLERY") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 30) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) > 18; + Distance Between(Eye Position(Event Player), Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Up * 99, Null, Event Player, False)) >= 35; + } + + actions + { + "TRYING TO CAPTURE TARGET" + Wait(0.800, Abort When False); + "CAPTURE TARGET" + Event Player.BotDoesUniqueBehaviour = True; + Stop Throttle In Direction(Event Player); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Update Every Frame(Eye Position(Event Player)), + Update Every Frame(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 1000, All Living Players(Team 1), Event Player, True)), Color(Sky Blue), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait(1.400, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Event Player.BotEventPosition = Position Of(Event Player.BotSeePlayer); + "SHOOT FROM ARTILLERY" + Event Player.BotBastionArtilleryDidShotsCount = 0; + For Player Variable(Event Player, BotLoopIterator1, 0, 4, 1); + Event Player.BotBastionArtilleryDidShotsCount += 1; + Play Effect(All Players(All Teams), Wrecking Ball Minefield Explosion Sound, Color(White), Eye Position(Event Player), 250); + Play Effect(All Players(All Teams), Pharah Barrage Explosion Effect, Color(Orange), Eye Position(Event Player) + World Vector Of( + Vector(0, 1.400, -0.700), Event Player, Rotation), 2); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) + World Vector Of(Vector(0, 1.400, + -0.700), Event Player, Rotation), Eye Position(Event Player) + World Vector Of(Vector(Random Real(-1, 1), Random Integer(40, + 80), Random Real(0.500, 1.500)), Event Player, Rotation), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + If(Is Dead(Event Player)); + Break; + End; + End; + disabled Call Subroutine(BotResetPathFinding); + disabled Start Rule(BotStartPathFinding, Do Nothing); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Wait(1.500, Ignore Condition); + Start Rule(BotBastionArtilleryDamage, Do Nothing); + Wait(4, Ignore Condition); + } +} + +rule("BOT: BASTION - PRIMARY FIRE") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 40) == True; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Stop Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Bastion; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + For Player Variable(Event Player, BotLoopIterator1, 0, 3, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Effect, Color(White), Event Player, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player, 100); + Wait(0.250, Ignore Condition); + End; + } +} + +rule("SUBROUTINE: BASTION - RESPAWN") +{ + event + { + Subroutine; + BotBastionRespawn; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + Call Subroutine(BotLandingFromSky); + Set Ammo(Event Player, 0, 0); + Wait Until(!Is Reloading(Event Player), 99999); + Event Player.BotTargetPosition = Objective Position(2); + } +} + +rule("SUBROUTINE: BASTION - ARTILLERY DAMAGE") +{ + event + { + Subroutine; + BotBastionArtilleryDamage; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = False; + "EXPLOSIONS OF ARTILLERY" + For Player Variable(Event Player, BotLoopIterator2, 0, Event Player.BotBastionArtilleryDidShotsCount, 1); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotEventPosition + Vector(0, 50, 0), + Event Player.BotEventPosition + Vector(Random Integer(-4, 4), -15, Random Integer(-4, 4)), Null, Event Player, True); + Damage(Players Within Radius(Event Player.BotEventPosition, 8, Team 1, Surfaces And Enemy Barriers), Event Player, 50); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Pharah Rocket Launcher Explosion Effect, Color(Orange), Event Player.BotEventPosition, 5); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Event Player.BotEventPosition, + Event Player.BotEventPosition + Vector(0, 60, 0), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + End; + } +} + +disabled rule("SUBROUTINE: BASTION - FLAME GUN DAMAGE") +{ + event + { + Subroutine; + BotBastionFlameGunDamage; + } + + actions + { + Event Player.BotRayCastHitPosition = Eye Position(Event Player) + World Vector Of(Vector(-1, -1.200, 1.800), Event Player, + Rotation); + "FIRE PARTICLES OF FLAME GUN" + For Player Variable(Event Player, BotLoopIterator1, 1, 13, 3); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotRayCastHitPosition, + Event Player.BotRayCastHitPosition + Facing Direction Of(Event Player) * Event Player.BotLoopIterator1, Null, Event Player, + True); + Damage(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Surfaces And Enemy Barriers), Event Player, 20); + Set Status(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Off), Event Player, Burning, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.BotEventPosition, 2.500); + Wait(0.200, Ignore Condition); + End; + Event Player.BotDoesUniqueBehaviour = False; + } +} + +disabled rule("=== ORISA + BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ORISA-BASTION - REACHED TARGET POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotIsPathFinding == True; + Distance Between(Position Of(Event Player), Global.BotOrisaTargetPosition) < 1.500; + } + + actions + { + Call Subroutine(BotResetPathFinding); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Vector(X Component Of(Global.GatePosition), -999, + Z Component Of(Global.GatePosition))), 80, To World, Direction and Turn Rate); + Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + disabled Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element) && Is In Line of Sight(Eye Position(Event Player), Position Of(Current Array Element), + Barriers Do Not Block LOS)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + Press Button(Event Player, Button(Ability 1)); + Wait Until(Y Component Of(Facing Direction Of(Event Player)) < -0.300, 99999); + Press Button(Event Player, Button(Ability 2)); + Wait(0.800, Ignore Condition); + Global.BotOrisaChild.BotDoesUniqueBehaviour = False; + Disallow Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ORISA-BASTION - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + While(Is Alive(Event Player)); + disabled Create Effect(All Players(All Teams), Bad Aura, Color(Purple), Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3.200, 1, Visible To Position and Radius); + disabled Event Player.BotEffects = Last Created Entity; + Wait(1.500, Ignore Condition); + disabled Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Press Button(Event Player, Button(Primary Fire)); + Press Button(Event Player, Button(Reload)); + Event Player.BotRayCastHitPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Facing Direction Of(Event Player) * 999, All Players(Team 1), All Players(Team 2), True); + "ANTI-SHIELD BUG" + Event Player.BotRayCastHitPosition = Event Player.BotRayCastHitPosition + Direction Towards(Event Player.BotRayCastHitPosition, + Eye Position(Event Player)) * 0.200; + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3, Event Player.BotRayCastHitPosition, Color(Purple), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Damage(Players Within Radius(Event Player.BotRayCastHitPosition, 4, Team 1, Surfaces And All Barriers), Event Player, 0.040); + Play Effect(All Players(All Teams), Pharah Concussive Blast Effect, Color(Purple), Event Player.BotRayCastHitPosition, 4); + Play Effect(All Players(All Teams), Pharah Concussive Blast Sound, Color(Purple), Event Player.BotRayCastHitPosition, 250); + Play Effect(All Players(All Teams), Bad Explosion, Color(Purple), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 3.300, 2); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Color(Purple), Eye Position(Event Player), 170); + If(Distance Between(Event Player.BotRayCastHitPosition, Global.GatePosition) < 4 && Is In Line of Sight( + Event Player.BotRayCastHitPosition, Global.GatePosition, Enemy Barriers Block LOS)); + Global.GateHealth -= 80; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Wait(0.150, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.060, Ignore Condition); + Wait Until(!Is Reloading(Event Player), 2.500); + End; + } +} + +rule("BOT: ORISA-BASTION - CAN'T SEE THE TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: ORISA-BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Orisa; + } + + actions + { + Allow Button(Event Player, Button(Ability 2)); + Kill(Global.BotOrisaChild, Null); + Detach Players(Global.BotOrisaChild); + Clear Status(Global.BotOrisaChild, Phased Out); + Set Damage Dealt(Global.BotOrisaChild, 100); + Global.BotOrisaChild.BotIsOrisaChild = False; + Global.BotOrisaChild = Null; + Global.BotOrisaParent = Null; + Start Forcing Player To Be Hero(Event Player, Hero(Widowmaker)); + } +} + +rule("SUBROUTINE: ORISA - RESPAWN") +{ + event + { + Subroutine; + BotOrisaRespawn; + } + + actions + { + Global.BotOrisaParent = Event Player; + "WAITING FOR ANY BASTION TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero(Bastion)), + 99999); + "SETUP BASTION AS CHILD" + Global.BotOrisaChild = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Bastion))[0]; + Global.BotOrisaChild.BotIsOrisaChild = True; + Global.BotOrisaChild.BotDoesUniqueBehaviour = True; + Wait(2, Ignore Condition); + Respawn(Global.BotOrisaChild); + Start Scaling Player(Global.BotOrisaChild, 1.800, False); + Set Damage Dealt(Global.BotOrisaChild, 2000); + Set Status(Global.BotOrisaChild, Null, Phased Out, 9999); + Disable Nameplates(Global.BotOrisaChild, All Players(All Teams)); + Set Facing(Global.BotOrisaChild, Vector(X Component Of(Facing Direction Of(Event Player)), 9999, Z Component Of( + Facing Direction Of(Event Player))), To World); + Start Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Wait Until(Is In Alternate Form(Global.BotOrisaChild), 5); + Stop Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Teleport(Global.BotOrisaChild, Position Of(Event Player)); + Attach Players(Global.BotOrisaChild, Global.BotOrisaParent, Vector(0, 1.800, 0.230)); + disabled Wait(1, Ignore Condition); + disabled Stop Holding Button(Global.BotOrisaChild, Button(Primary Fire)); + disabled Wait(0.250, Ignore Condition); + Call Subroutine(BotLandingFromSky); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 0 - ZENS, REINS, BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 0; + } + + actions + { + "CREATE BOTS - ZEN" + While(Count Of(All Players(Team 2)) < 15); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "BALL" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "REPLACE DEAD ZEN TO REIN" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) != 3); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 1 - WIDOW") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 1; + } + + actions + { + Global.IsNewWaveGameLogicProcessing = True; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Global.IsNewWaveGameLogicProcessing = False; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 3 - BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 3; + } + + actions + { + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 5 - REINS WAVE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 5; + } + + actions + { + "PREPARE WAVE - DESTROY WIDOW AND BALLS" + Destroy Dummy Bot(Team 2, Slot Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))[0])); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))[0]; + Kill(Global.DefaultCurrentBot, Null); + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + "BOSS WAVE" + Big Message(All Players(All Teams), Custom String("BOSS WAVE - {1} {0}", Hero Icon String(Hero(Reinhardt)), Hero(Reinhardt))); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) < 6); + Wait Until(Is True For Any(All Players(Team 2), Distance Between(Position Of(Current Array Element), Global.GatePosition) + > 15 && Hero Of(Current Array Element) == Hero(Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + disabled Wait(0.200, Ignore Condition); + disabled Set Max Health(Global.DefaultCurrentBot, 50); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) > 3); + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Reinhardt)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Reinhardt))[0]; + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(All Players(Team 2)) < 15); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Big Message(All Players(All Teams), Custom String("BOSS WAVE FINISHED!")); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 7 - BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 7; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 9 - ECHO, +1 BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 9; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Echo))) == 0); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + "FILL EMPTY SLOTS BY ZENS" + While(Count Of(All Players(Team 2)) < 14); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("Ana Nano Variable") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + } + + actions + { + Player Closest To Reticle(Event Player, Team 1).IsNanoed = 1; + } +} + +rule("IsNanoed") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.IsNanoed == True; + } + + actions + { + If(Is Dead(Event Player)); + Event Player.IsNanoed = 0; + End; + Wait(8, Ignore Condition); + Event Player.IsNanoed = 0; + } +} + +rule("money on kill") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + actions + { + If(Hero Of(Victim) == Hero(Zenyatta)); + All Players(Team 1).Money[0] += 5 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 5 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Reinhardt)); + All Players(Team 1).Money[0] += 15 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 15 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Wrecking Ball)); + All Players(Team 1).Money[0] += 20 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 20 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Widowmaker)); + All Players(Team 1).Money[0] += 25 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 25 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Bastion)); + All Players(Team 1).Money[0] += 50 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 50 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Echo)); + All Players(Team 1).Money[0] += 75 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 75 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Orisa)); + All Players(Team 1).Money[0] += 100 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 100 * (Victim.isBoss ? 3 : 1); + End; + } +} + +rule("Abilities and Hero Talents by Shingen and LemonAid") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.DamageDealt = 100; + Event Player.PlayerHealth = 100; + Event Player.Money[0] = 2400 + Global.StartMoney; + If(Custom String("{0}", Event Player) == Custom String("ShuriZma")); + Create HUD Text(Event Player, Custom String("Serverload: {0}, AVG {1}, Peak {2}", Server Load, Server Load Average, + Server Load Peak), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create HUD Text(Event Player, Custom String("Last SW: {0}, SW Active {1}", Event Player.lastSecondWind, + Event Player.secondWindActive), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + End; + } +} + +rule("Team 1 (Ability): Headhunter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[1] == True; + Event Was Critical Hit == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[1] * 40 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Ambush") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[2] == True; + Event Ability != Null; + (Y Component Of(Position Of(Event Player)) - Y Component Of(Position Of(Victim)) >= 3 || Absolute Value(Horizontal Angle Towards( + Victim, Event Player)) >= 90) == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[2] * 30 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Quick Fix") +{ + event + { + Player Earned Elimination; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[3] == True; + } + + actions + { + Heal(Event Player, Null, Event Player.Abilities[3] * 50); + Set Move Speed(Event Player, 100 + Event Player.Abilities[3] * 20); + Wait(5, Restart When True); + Set Move Speed(Event Player, 100); + } +} + +rule("Team 1 (Ability): Heavyweight") +{ + event + { + Player Dealt Knockback; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[4] == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[4] * 25 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Charged") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[5] == True; + Ultimate Charge Percent(Event Player) < Event Player.Abilities[5] * 20; + } + + actions + { + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + If(Is Duplicating(Event Player)); + Wait(0.016, Ignore Condition); + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + End; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Team 1 (Ability): Haste Primary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Primary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Primary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Primary Fire))); + } +} + +rule("Team 1 (Ability): Haste Secondary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Secondary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Secondary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Secondary Fire))); + } +} + +rule("Team 1 (Ability): Haste Ability 1") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 1)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 1))); + } +} + +rule("Team 1 (Ability): Haste Ability 2") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 2)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 2))); + } +} + +rule("Team 1 (Ability): Haste Jump") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Jump)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Jump), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Jump))); + } +} + +rule("Team 1 (Ability): Haste Crouch") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Crouch)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Crouch), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Crouch))); + } +} + +rule("Team 2 (Ability): Heavy Impact") +{ + event + { + Player Took Damage; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[7] == True; + } + + actions + { + Abort If(Random Real(-0.020, 1) > Event Damage / Max Health(Event Player)); + Set Status(Event Player, Attacker, Stunned, 1 * Attacker.Abilities[7]); + Wait(5, Ignore Condition); + } +} + +rule("Team 1 (Ability): Binding Heal") +{ + event + { + Player Dealt Healing; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[10] == True; + Healee != Event Player; + } + + actions + { + Set Player Health(Event Player, Health(Event Player) + Event Player.Abilities[10] * 0.250 * Event Healing); + } +} + +rule("Team 1 (Ability): Resilience") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[11] == True; + Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300; + } + + actions + { + Set Damage Received(Event Player, 70); + Wait Until(!(Event Player.Abilities[11] && Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Auto Repair") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.AutoRepair == True; + Global.GateHealth < Global.GateMaxHealth; + } + + actions + { + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2]); + Global.GateHealth += 10 * Global.AutoRepair; + Global.UpgradeGateMaxHealthValue += 10 * Global.AutoRepair; + Else; + Global.GateHealth += 5 * Global.AutoRepair; + Global.UpgradeGateMaxHealthValue += 5 * Global.AutoRepair; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(5, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ana Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ana), Button(Ability 1)), Custom String( + "Sleep Paralysis: Slept enemies cannot be woken up by damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Ana), Button(Ability 2)), Custom String( + "Multinade: Ana throws multiple Biotic Grenades")); + } +} + +rule("Brigitte Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Brigitte), Button(Ability 1)), Custom String( + "Heavy Iron: Hitting enemies with Whip Flail will root them in pace")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Brigitte), Button(Ultimate)), Custom String( + "Endeavor: Gain a health, damage and speed boost when your barrier breaks")); + } +} + +rule("Mercy Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mercy), Button(Ability 2)), Custom String( + "Angelic blessing: Healing an ally slowly charges their ultimate")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mercy), Button(Ultimate)), Custom String( + "Holy light missiles: Unleash blasts of holy light missiles during valkyrie")); + } +} + +rule("Lúcio Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Lúcio), Button(Secondary Fire)), Custom String( + "Healing Wave: Soundwave heals allies for 30% of their max HP")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Lúcio), Button(Ability 1)), Custom String( + "Reverse Amp: Amp It Up inflicts the opposite effect of the currently played song to enemies")); + } +} + +rule("Moira Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Moira), Button(Secondary Fire)), Custom String( + "Hose: Biotic Grasp primary will damage and push enemies back")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Moira), Button(Ability 2)), Custom String( + "Flourish: Biotic Orbs are 3x more effective")); + } +} + +rule("Baptiste Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String( + "Corrode: Regenerative Burst will damage and poison enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Breakthrough: Immortality Field HP threshold increased to 100%; allies inside gain ultimate")); + } +} + +rule("Ashe Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ashe), Button(Ability 2)), Custom String( + "Wildfire: Shooting a burning enemy ignites other nearby enemies")); + Event Player.HeroTalentText[2] = Array(Icon String(Fire), Custom String( + "Flare trigger: Coach gun instantly damages all burning enemies")); + } +} + +rule("D.Va Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(D.Va), Button(Secondary Fire)), Custom String( + "Voltage Grid: Defense Matrix will damage and root enemies it's casted over")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(D.Va), Button(Ability 1)), Custom String( + "Shooting Star: Boosters set enemies on fire")); + } +} + +rule("Genji Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Genji), Button(Ability 1)), Custom String( + "Venomous Strike: Swift Strike poisons enemies; heal for poison damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Genji), Button(Ultimate)), Custom String( + "Dragon's Breath: Dragonblade fires large explosive energy charges")); + } +} + +rule("Hanzo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Hanzo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "Stormbreak: Enemies eliminated by hanzo unleash a thundercloud")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Hanzo), Button(Ability 2)), Custom String( + "Punch II: Storm Arrows deal more damage and stun and knockback enemies")); + } +} + +rule("Widowmaker Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Widowmaker; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Widowmaker), Button(Ultimate)), Custom String( + "Kiss Of Death: Scoped critical hits against enemies below 30% health explode and instantly die")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Widowmaker), Button(Ability 2)), Custom String( + "Epidemic: Enemies hurt by Venom Mine unleash toxic pulses; heal for dealt damage")); + } +} + +rule("McCree Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Cassidy), Button(Ability 2)), Custom String( + "Panic: Flashbang puts enemies in fear; deal +120% more damage to enemies in fear")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Cassidy), Button(Ultimate)), Custom String( + "Clocked: Deadeye deals more damage and knocks enemies down")); + } +} + +rule("Reinhardt Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reinhardt), Button(Ability 2)), Custom String( + "Fire Blast: Fire Strike explodes as it deals damage, setting enemies on fire")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reinhardt), Button(Ultimate)), Custom String( + "Epicenter: Earthshatter travels in all directions")); + } +} + +rule("Soldier: 76 Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ultimate)), Custom String( + "Triple Threat: 2 more rockets are fired alongside Helix Rockets")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Soldier: 76), Button(Ability 1)), Custom String( + "Shoulder Check: Sprinting into enemies will damage and tackle them to the ground")); + } +} + +rule("Torbjörn Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Torbjörn), Button(Ability 2)), Custom String( + "Melting point: Unleash heatwaves during overload and molten core")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Torbjörn), Button(Ultimate)), Custom String( + "Roots Of Magma: Enemies trapped in Molten Core blots cannot move")); + } +} + +rule("Tracer Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Tracer), Button(Ability 2)), Custom String( + "Vortex: Recall pulls and roots enemies towards the activation point")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Tracer), Button(Ultimate)), Custom String( + "Chain Reaction: Pulse Bomb creates chain explosions on enemies damaged by it")); + } +} + +rule("Winston Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Winston), Button(Ability 2)), Custom String( + "Blast Barrier: Barrier Projector damages enemies inside the area")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Winston), Button(Ultimate)), Custom String( + "Next Generation: Eliminations during Primal Rage add +15% ultimate charge towards the next")); + } +} + +rule("Pharah Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Pharah; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ability 2)), Custom String( + "Head Trauma: Concussive Blast stuns and damages enemies for 25% of their max health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Pharah), Button(Ability 1)), Custom String( + "Thunderbird: Gain 150 shields and deal 4x the damage to barriers and objects")); + } +} + +rule("Bastion Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Bomblets: Bullets shot during sentry configuration are explosive")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ability 1)), Custom String( + "Tesla: A powerful mounted laser will autmotically attack one enemy at a time")); + } +} + +rule("Doomfist Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Jump)), Custom String( + "Phase Shifter: Immune to damage while any ability is active")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Doomfist), Button(Ultimate)), Custom String( + "Fissure: Meteor Strike leaves a large fissure behind that burns enemies over it")); + } +} + +rule("Echo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Focusing Optics: Focusing Beam damage ramp starts at 90% health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Streamline: Fire many more sticky bombs per burst")); + } +} + +rule("Junkrat Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Junkrat; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Fire), Custom String("Pyromania: All explosive attacks inflict fire damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Junkrat), Button(Ability 2)), Custom String( + "Short Fused: Steel Trap sets off violent explosions once triggered")); + } +} + +rule("Mei Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mei), Button(Ultimate)), Custom String( + "Cold Snap: Instantly freeze neaerby enemies once Cryo-Freeze expires")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mei), Button(Ability 2)), Custom String( + "Icebound: While Ice Wall is up, Icicles freeze and deal much more damage")); + } +} + +rule("Orisa Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Orisa), Button(Ability 1)), Custom String( + "Immovable Object: During Fortify, become immune and convert 50% of taken damage to healing")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Orisa), Button(Secondary Fire)), Custom String( + "Unstoppable Force: Halt! is much larger and pushes enemies. When triggered, it explodes violently")); + } +} + +rule("Reaper Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reaper), Button(Ability 1)), Custom String( + "shadow streak: shadow step creates a beam that damages enemies who cross")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reaper), Button(Ultimate)), Custom String( + "Loom: Traumatize enemies in front of you when using Wraith Form")); + } +} + +rule("Roadhog Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String("Stench: Roadhog constantly damages enemies nearby")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Roadhog), Button(Ability 1)), Custom String( + "Rusted Anchor: Hook deals more damage; Eliminations will reset hook cooldown")); + } +} + +rule("Sigma Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sigma), Button(Ability 1)), Custom String( + "Gravity Well: Kinetic Grasp gives invincibility")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sigma), Button(Ultimate)), Custom String( + "Gravity Channels: Gravitic Flux damages enemies for 75% of max hp instead of 50%")); + } +} + +rule("Sombra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sombra), Button(Secondary Fire)), Custom String( + "Malware: Enemies hacked or in fear take +100% more damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sombra), Button(Ultimate)), Custom String( + "Glitch: EMP leaves behind a large hack zone ")); + } +} + +rule("Symmetra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Symmetra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "High Voltage: Enemies eliminated by Symmetra explode and damage other enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ultimate)), Custom String( + "Energy Source: While Photon Barrier is active, all players regenerate health and gain ultimate")); + } +} + +rule("Wrecking Ball Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ultimate)), Custom String( + "Mirror Ball: Reflect 100% of taken damage to nearby enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ability 2)), Custom String( + "Distort: Adaptive Shields damages and hacks nearby enemies")); + } +} + +rule("Zarya Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zarya; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Zarya), Button(Ability 1)), Custom String( + "Augment: Health and barrier hp increased by 50%; barrier sized doubled")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Perpetual Energy: secondary inflicts burn damage that continues to last until the enemy dies")); + } +} + +rule("Zenyatta Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Vigor: The ally under the effect of Harmony Orb is immune to damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Zenyatta), Button(Ultimate)), Custom String( + "Perfect Balance: Transcendence damages enemies in a large proximity")); + } +} + +rule("Ana: Sleep Paralysis") +{ + event + { + Player Dealt Damage; + Team 1; + Ana; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Black), Victim, 1); + Wait(0.250, Ignore Condition); + Set Status(Victim, Null, Knocked Down, 5); + } +} + +rule("Ana: Multinade") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.AbilityCountdown = 4; + While(Event Player.AbilityCountdown > 0); + Wait(0.030, Ignore Condition); + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Cancel Primary Action(Event Player); + Wait(0.050, Ignore Condition); + Press Button(Event Player, Button(Ability 2)); + Event Player.AbilityCountdown -= 1; + End; + Wait(2, Ignore Condition); + } +} + +rule("Brigitte: Heavy Iron") +{ + event + { + Player Dealt Damage; + Team 1; + Brigitte; + } + + conditions + { + (Event Ability == Button(Primary Fire) || Event Ability == Button(Ability 1)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Victim, 1.500); + Set Status(Victim, Null, Rooted, 0.500); + Set Environment Credit Player(Victim, Event Player); + } +} + +rule("Brigitte: Endeavor") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Ability Cooldown(Event Player, Button(Secondary Fire)) >= 0.100; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Eye Position(Event Player), 15); + Heal(Players Within Radius(Event Player, 15, Team Of(Event Player), Off), Event Player, 200); + Event Player.DamageDealt *= 2.500; + Set Move Speed(Event Player, 100 * 1.750); + Add Health Pool To Player(Event Player, Armor, Max Health(Event Player) / 2, False, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(Is Dead(Event Player), 6); + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Move Speed(Event Player, 100); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Mercy: Angelic Blessing") +{ + event + { + Player Dealt Healing; + All; + Mercy; + } + + conditions + { + Event Player.Abilities[8] == True; + Healee != Event Player; + Normalized Health(Healee) < True; + } + + actions + { + Set Ultimate Charge(Healee, Ultimate Charge Percent(Healee) + 1); + Wait(0.400, Ignore Condition); + } +} + +rule("Mercy: Aurora") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ultimate(Event Player) == True; + } + + actions + { + Wait(1.500, Ignore Condition); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(All Teams), Event Player, True); + Create Beam Effect(All Players(All Teams), Mercy Heal Beam, Event Player, Event Player.Ability_Projectile1, Color(White), + Visible To Position and Radius); + Event Player.Effects_[3] = Last Created Entity; + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 70, Destination and Rate); + While(Event Player.Ability_End != Event Player.Ability_Projectile1); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Event Player.Ability_Projectile1, 1); + Wait(0.032, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[3]); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 120); + Loop If Condition Is True; + } +} + +rule("Lucio: Healing Wave") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4); + Heal(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 4, 4, Team Of(Event Player), Surfaces), + Event Player, Max Health(Filtered Array(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4, Team Of(Event Player), Surfaces), Is Alive(Current Array Element))) * 0.300); + } +} + +rule("Lucio: Reverse Amp") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + If(Is Using Ability 1(Event Player)); + Set Status(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Rooted, 4); + Else; + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 16.250); + End; + Play Effect(All Players(All Teams), Ring Explosion, Is Using Ability 1(Event Player) ? Color(Green) : Color(Yellow), Event Player, + 1); + Wait(0.400, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Hose") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Event Player.Abilities[8] == True; + Ability Resource(Event Player, Button(Primary Fire)) > False; + } + + actions + { + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Facing Direction Of(Event Player), 15, To World, + Cancel Contrary Motion); + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && !Is In Line of Sight(Current Array Element, Event Player, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Up, 8, To World, Cancel Contrary Motion); + Start Damage Over Time(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), + Distance Between(Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS)), Event Player, 1, 15); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Flourish - Damage") +{ + event + { + Player Dealt Damage; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("[Moira] Flourish - Healing") +{ + event + { + Player Dealt Healing; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Heal(Healee, Event Player, Event Healing * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Healee, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("Baptiste: Corrode") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 20); + Wait(0.200, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 12); + } +} + +rule("Baptiste: Breakthrough") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Status(Event Player, Unkillable) == True; + (Event Player.Abilities[12] ? Players On Hero(Hero(Baptiste), Team Of(Event Player)) : Empty Array).Abilities[12] == True; + } + + actions + { + Heal(Event Player, Event Player, 10000); + Set Status(Event Player, Null, Invincible, 0.800); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ashe: Firebourne") +{ + event + { + Player Dealt Damage; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability == Button(Primary Fire); + Has Status(Victim, Burning) == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Null, Burning, 10); + Start Damage Over Time(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Event Player, 10, 15); + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 5); + Wait(0.250, Ignore Condition); + } +} + +rule("Ashe: Taunt") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Damage(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, Burning)), + Event Player, 125); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Frozen, + 0.016); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Stunned, + 2); + } +} + +rule("D.Va: Voltage Grid") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 2, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 5, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 8, 0.500); + Wait(0.300, Ignore Condition); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Wait(0.016, Ignore Condition); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Loop If Condition Is True; + } +} + +rule("D.Va: Shooting Star") +{ + event + { + Player Dealt Knockback; + Team 1; + D.Va; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, 40); + Set Status(Victim, Null, Burning, 3); + Start Damage Over Time(Victim, Event Player, 3, 35); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 1); + } +} + +rule("Genji: Venomous Strike") +{ + event + { + Player Dealt Damage; + Team 1; + Genji; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 3, 25); + Start Damage Over Time(Victim, Event Player, 3, 25); + Damage(Victim, Event Player, 25); + Heal(Event Player, Event Player, 25); + } +} + +rule("Genji: Dragon's Breath") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is Firing Primary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Good Aura, Color(Lime Green), Event Player.Ability_Projectile1, 1, + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 80, Destination and Rate); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True); + Wait Until(Event Player.Ability_End == Event Player.Ability_Projectile1, 1); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Green), Event Player.Ability_Projectile1, 100); + Play Effect(All Players(All Teams), Bad Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Green), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 100); + } +} + +rule("[Hanzo] Stormbreak (Storm_Effects6)") +{ + event + { + Player Died; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[8] == True; + Hero Of(Attacker) == Hero(Hanzo); + } + + actions + { + Event Player.Storm_Projectile = Eye Position(Event Player); + Event Player.Storm_EndPoint = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Up * 12, Null, + All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Storm_Projectile, Event Player.Storm_EndPoint, 4, Destination and Rate); + Create Effect(All Players(All Teams), Cloud, Color(White), Vector(False, -0.500, False) + Event Player.Storm_Projectile, 4, + Visible To Position and Radius); + Event Player.Storm_Effects[3] = Last Created Entity; + Create Effect(All Players(All Teams), Bad Aura, Color(White), Event Player.Storm_Projectile, 3, Visible To Position and Radius); + Event Player.Storm_Effects[4] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(White), Event Player.Storm_Projectile, 3.500, Visible To Position and Radius); + Event Player.Storm_Effects[5] = Last Created Entity; + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Storm_Projectile, Ray Cast Hit Position( + Event Player.Storm_Projectile, Vector(0.100, 0, 0) + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), + False), Color(Aqua), Visible To Position and Radius); + Event Player.Storm_Effects[6] = Last Created Entity; + While(Distance Between(Event Player.Storm_Projectile, Event Player.Storm_EndPoint) > 1); + Wait(0.600, Ignore Condition); + Damage(Players Within Radius(Ray Cast Hit Position(Event Player.Storm_Projectile, Event Player.Storm_Projectile + Down * 1000, + Null, All Players(All Teams), False), 3, Team Of(Event Player), Surfaces), Attacker, 50); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + End; + Destroy Effect(Event Player.Storm_Effects[3]); + Destroy Effect(Event Player.Storm_Effects[4]); + Destroy Effect(Event Player.Storm_Effects[5]); + Destroy Effect(Event Player.Storm_Effects[6]); + } +} + +rule("Hanzo: Punch II") +{ + event + { + Player Dealt Damage; + Team 1; + Hanzo; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + Hero Of(Victim) != Hero(Torbjörn); + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.800); + Apply Impulse(Victim, Facing Direction Of(Event Player), 12, To World, Cancel Contrary Motion); + Apply Impulse(Victim, Up, 5, To World, Cancel Contrary Motion); + Set Environment Credit Player(Victim, Event Player); + Set Status(Victim, Null, Stunned, 1); + } +} + +rule("Widowmaker: Kiss Of Death") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + (Normalized Health(Victim) <= 0.300 || Event Damage >= Normalized Health(Victim) + Event Damage) == True; + Is Firing Secondary(Event Player) == True; + Event Ability == Button(Primary Fire); + Event Player.Abilities[8] == True; + Event Damage >= 40; + Event Was Critical Hit == True; + } + + actions + { + Kill(Victim, Event Player); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 2), Victim, 3); + Damage(Players Within Radius(Victim, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage * 1.500); + } +} + +rule("Widowmaker: Epidemic") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 8); + Play Effect(All Players(All Teams), Good Explosion, Color(Purple), Victim, 4); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Victim, 16); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Victim, 3); + Start Damage Over Time(Players Within Radius(Victim, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, 50); + Start Heal Over Time(Event Player, Event Player, 3, 50); + Wait(0.500, Ignore Condition); + } +} + +rule("McCree: Panic") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Victim.Feared_until = Total Time Elapsed + 3.500; + } +} + +rule("McCree: Panic - Damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), + Event Player.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 220, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("McCree: Clocked") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Damage(Victim, Event Player, Event Damage * 1.500); + Set Status(Victim, Null, Knocked Down, 3); + } +} + +rule("Reinhardt: Fire Blast") +{ + event + { + Player Dealt Damage; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Start Damage Over Time(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, 20); + Set Status(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Burning, 5); + } +} + +rule("Reinhardt: Epicenter") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is On Ground(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, Knocked Down, 2.500); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 10); + Damage(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, 50); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 20); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 30); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 40); + Wait(5, Ignore Condition); + } +} + +rule("[Soldier: 76] Rocket Assault Rifle") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile2 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(-2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Projectile1 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Position = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, + 0), Event Player, Rotation); + Event Player.Ability_End = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, 0), + Event Player, Rotation); + Chase Player Variable At Rate(Event Player, Ability_Position, Event Player.Ability_Projectile1, 60, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_End, Event Player.Ability_Projectile2, 60, Destination and Rate); + Wait Until(Event Player.Ability_Position == 0 && Event Player.Ability_End == 0, 2.500); + } +} + +rule("[Soldier: 76] First Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile1 != Event Player.Ability_Position; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_Position, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_Position, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_Position, 2.500); + Stop Chasing Player Variable(Event Player, Ability_Position); + Wait(0.016, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 80); + Stop Chasing Player Variable(Event Player, Ability_Position); + Event Player.Ability_Position = 0; + Event Player.Ability_Projectile1 = 0; + Wait(0.016, Ignore Condition); + } +} + +rule("[Soldier: 76] Second Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile2 != Event Player.Ability_End; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_End, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_End, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_End, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_End, 2.500); + Stop Chasing Player Variable(Event Player, Ability_End); + Damage(Players Within Radius(Event Player.Ability_End, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Event Player.Ability_End = 0; + Event Player.Ability_Projectile2 = 0; + } +} + +rule("Soldier: 76 - Init rockets") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile1 = Event Player.Ability_Position; + Event Player.Ability_Projectile2 = Event Player.Ability_End; + } +} + +rule("[Soldier: 76] Shoulder Check") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 3; + Is Alive(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) == True; + } + + actions + { + Damage(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Event Player, 55); + Set Status(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Null, Knocked Down, 1.500); + Apply Impulse(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Facing Direction Of(Event Player), 15, + To World, Cancel Contrary Motion); + Apply Impulse(Event Player, Vector(0, 8, 15), 15, To Player, Cancel Contrary Motion); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Closest Player To(Event Player, Opposite Team Of(Team Of( + Event Player))), 1); + Set Ability Cooldown(Event Player, Button(Melee), 0); + Press Button(Event Player, Button(Melee)); + Wait(1, Ignore Condition); + } +} + +rule("Torbjorn: Melting Point") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Event Player.Abilities[8] == True; + (Is Using Ability 2(Event Player) || Is Using Ultimate(Event Player)) == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Event Player, 8); + Play Effect(All Players(All Teams), Bad Explosion, Color(Yellow), Event Player, 8); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 16); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, + 25); + Set Status(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Off), Null, Burning, 3); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player, 100); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Torbjorn: Roots of Magma") +{ + event + { + Player Dealt Damage; + Team 1; + Torbjörn; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Set Status(Victim, Null, Rooted, 1); + Wait(1, Ignore Condition); + } +} + +rule("Tracer: Vortex") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, 0); + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 10); + Play Effect(All Players(All Teams), Ring Explosion, Color(Red), Position Of(Event Player), 24); + Play Effect(All Players(All Teams), Ring Explosion, Color(Yellow), Position Of(Event Player), 18); + Play Effect(All Players(All Teams), Ring Explosion, Color(Green), Position Of(Event Player), 12); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player), 6); + Set Environment Credit Player(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player); + } +} + +rule("Tracer: Vortex 2") +{ + event + { + Player Received Healing; + Team 2; + All; + } + + conditions + { + Healer.Abilities[8] == True; + Hero Of(Healer) == Hero(Tracer); + Is Using Ability 2(Healer) == True; + Event Ability == Null; + Event Damage <= 20; + } + + actions + { + Apply Impulse(Event Player, Up, 5, To World, Cancel Contrary Motion); + Wait(0.100, Ignore Condition); + Apply Impulse(Event Player, Direction Towards(Event Player, Healer), Distance Between(Event Player, Healer) * 3.500, To World, + Cancel Contrary Motion); + Set Status(Event Player, Null, Rooted, 1.300); + } +} + +rule("Tracer: Chain Reaction") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is True For Any(Filtered Array(All Players(Team Of(Event Player)), Current Array Element.Chain_Reaction_On), Distance Between( + Event Player, Current Array Element) <= 8 && True) == True; + Event Player.Chain_Reaction_Immune == False; + Event Player.Chain_Reaction_On == False; + Is Alive(Event Player) == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Event Player.Chain_Reaction_On = True; + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player, 3); + } +} + +rule("Tracer: Chain Reaction 2") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Event Player.Chain_Reaction_On == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Aqua), Event Player, 3); + Damage(Event Player, Players On Hero(Hero(Tracer), Opposite Team Of(Team Of(Event Player))), 200); + Wait(0.500, Ignore Condition); + Event Player.Chain_Reaction_Immune = True; + Event Player.Chain_Reaction_On = False; + Wait(2, Ignore Condition); + Event Player.Chain_Reaction_Immune = False; + } +} + +rule("Tracer: Chain Reaction 3") +{ + event + { + Player Dealt Damage; + Team 1; + Tracer; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Damage > 20; + Event Player.Abilities[12] == True; + } + + actions + { + Victim.Chain_Reaction_On = True; + } +} + +rule("[Winston] Electric Field") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 65); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Orb, Color(White), Event Player.Ability_Projectile1, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Stop Chasing Player Variable(Event Player, Ability_Resource); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Down * 1000, Null, + All Players(All Teams), False); + Wait(0.100, Ignore Condition); + Event Player.Ability_Resource = 5; + Wait(0.250, Ignore Condition); + Chase Player Variable At Rate(Event Player, Ability_Resource, 20, 7, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, Event Player.Ability_Resource, + Destination and Rate); + Wait(8.650, Restart When True); + Event Player.Ability_Active = False; + } +} + +rule("[Winston] Electric Field 2") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 33); + Play Effect(All Players(All Teams), Ring Explosion, Color(Blue), Event Player.Ability_Projectile1, 10); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 80); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Event Player.Ability_Projectile1, 12); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player.Ability_Projectile1, 125); + } +} + +rule("Winston: Next Generation") +{ + event + { + Player Earned Elimination; + Team 1; + Winston; + } + + conditions + { + Ultimate Charge Percent(Event Player) <= 80; + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 15); + } +} + +rule("Pharah: Head Trauma") +{ + event + { + Player Dealt Knockback; + Team 1; + Pharah; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Victim != Event Player; + } + + actions + { + Damage(Victim, Event Player, Max Health(Victim) * 0.300); + Set Status(Victim, Event Player, Knocked Down, 1); + Play Effect(All Players(All Teams), Good Explosion, Color(Team 1), Victim, 1); + } +} + +rule("Pharah: Thunderbird") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[12] == True; + Hero Of(Event Player) == Hero(Pharah); + } + + actions + { + Event Player.DamageDealt *= 4; + Start Damage Modification(All Players(All Teams), Event Player, 25, Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Add Health Pool To Player(Event Player, Shields, 150, True, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(!Event Player.Abilities[12] || Hero Of(Event Player) != Hero(Pharah), 99999); + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Stop Damage Modification(Event Player.Modification_Damage[1]); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + } +} + +rule("Orisa: Unstoppable Force") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Direction = Facing Direction Of(Event Player); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Sphere, Color(Green), Event Player.Ability_Projectile1, 4, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player) + Facing Direction Of(Event Player) * 0.500; + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 100, Null, All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 25, Destination and Rate); + Wait(0.250, Ignore Condition); + Wait Until((!Event Player.Gen_Available && Is Button Held(Event Player, Button(Secondary Fire))) || ( + Event Player.Ability_Projectile1 == Event Player.Ability_End), 99999); + Stop Chasing Player Variable(Event Player, Ability_Projectile1); + Wait(0.500, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, + 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Orisa: Availability for Halt!") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Available = True; + Wait Until(!Is Button Held(Event Player, Button(Secondary Fire)), 99999); + Event Player.Gen_Available = False; + } +} + +rule("Orisa: Drag effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Player.Ability_Active == True; + } + + actions + { + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Is Alive(Event Player) ? Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of( + Event Player)), Surfaces) : Empty Array, Event Player.Ability_Projectile1), 8, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Event Player.Ability_Projectile1, Event Player.Ability_End), 20, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Up, 5, + To Player, Cancel Contrary Motion); + Wait(0.200, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Orisa: Immoveable Object - Reduce dmg") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Damage Received(Event Player, 100 * 0.003); + Wait Until(!Is Using Ability 1(Event Player), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Orisa: Immovable Object - Healing") +{ + event + { + Player Took Damage; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Event Player, Null, Event Damage * 3); + } +} + +rule("[Reaper] Shadow Streak (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Event Player.Ability_Position = Position Of(Event Player) + Vector(0, 1, 0); + Wait(2, Abort When False); + Event Player.Ability_End = Position Of(Event Player) + Vector(0, 1, 0); + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Ability_End, Event Player.Ability_Position, Color(Black), + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player) || Is Using Ability 2(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage start to end (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players(Opposite Team Of(Team Of( + Event Player))), Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_Position, + Event Player.Ability_End, All Living Players(All Teams), Event Player, True), 1); + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage end to start (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Players(Opposite Team Of(Team Of(Event Player))), + Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_End, + Event Player.Ability_Position, All Living Players(All Teams), Event Player, True), 1); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Reaper: Loom") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Hacked, 1.500); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Rooted, 1.500); + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Event Player, 45); + } +} + +rule("Sigma: Gravity Well") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, 25); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Null, Rooted, 2); + Set Status(Event Player, Null, Invincible, 1); + Play Effect(Event Player, Ring Explosion, Color(Blue), Eye Position(Event Player), 50); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Sigma: Gravity Channels") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ultimate(Event Player)), Event Player, 150, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[12], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Echo: Focusing Optics") +{ + event + { + Player Dealt Damage; + Team 1; + Echo; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Normalized Health(Victim) > 0.500; + Normalized Health(Victim) <= 0.900; + Is Duplicating(Event Player) == False; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 3); + Play Effect(All Players(All Teams), Bad Explosion, Color(Violet), Victim, 0.500); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Wait(0.700, Abort When False); + Cancel Primary Action(Event Player); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Set Projectile Speed(Event Player, 100); + Wait(0.150, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Bomblets") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Is In Alternate Form(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Orange), Null + Ray Cast Hit Position(Eye Position(Event Player), + Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, All Living Players(Opposite Team Of(Team Of( + Event Player))), All Players(Team Of(Event Player)), True), 2); + Damage(Players Within Radius(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 2, + Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 12); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Taser - Loop damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is True For Any(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive(Current Array Element) + && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status(Current Array Element, + Phased Out) && Distance Between(Event Player, Current Array Element) <= 25) == True; + Is Alive(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Explosion Sound, Color(White), Event Player.Ability_Player, 80); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Event Player.Ability_Player, 1); + Event Player.Ability_Player = Filtered Array(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive( + Current Array Element) && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status( + Current Array Element, Phased Out) && Distance Between(Event Player, Current Array Element) <= 25); + Damage(Players Within Radius(Event Player.Ability_Player, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 30); + Wait(0.450, Ignore Condition); + Loop If Condition Is True; + Event Player.Ability_Player = Null; + } +} + +rule("Bastion: Taser - Visual beam") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player + Vector(False, 1, False), + Event Player.Ability_Player != Null ? Event Player.Ability_Player : Event Player, Color(Aqua), + Visible To Position Radius and Color); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[12], 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Sombra: Malware") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, + Hacked) || Current Array Element.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 200, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Sombra: Glitch") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Ability_Active = True; + Event Player.Ability_Position = Position Of(Event Player); + Create Effect(All Players(All Teams), Sphere, Color(Purple), Event Player.Ability_Position, 15, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait(8, Ignore Condition); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Sombra: Glitch - Loop") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Ability_Active == True; + } + + actions + { + Set Status(Players Within Radius(Event Player.Ability_Position, 15, Opposite Team Of(Team Of(Event Player)), Off), Null, Hacked, + 0.750); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Mei: Cold Snap") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Event Player, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Is Using Ability 1(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Damage(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Frozen, 2); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Rooted, 2); + Play Effect(All Players(All Teams), Ring Explosion, Color(White), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Sky Blue), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player) + Vector(0, 1, 0), 20); + } +} + +rule("Mei: Icebound") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Aqua), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Set Projectile Speed(Event Player, 200); + Wait Until(!Is Firing Secondary(Event Player), 99999); + Destroy Effect(Event Player.Effects_[2]); + Set Projectile Speed(Event Player, 100); + } +} + +rule("Mei: Icebound - Icicles hit") +{ + event + { + Player Dealt Damage; + Team 1; + Mei; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 1.250); + Set Status(Victim, Null, Frozen, 1); + Set Status(Victim, Null, Rooted, 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Victim, 1); + } +} + +rule("Wrecking Ball: Mirror Ball") +{ + event + { + Player Took Damage; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 4.500, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage); + Wait(0.100, Ignore Condition); + } +} + +rule("Wrecking Ball: Distort") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Set Status(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Hacked, Count Of( + Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces)) * 1.500); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Violet), Position Of(Event Player), 125); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Sound, Color(Purple), Position Of(Event Player), 16); + Play Effect(All Players(All Teams), Explosion Sound, Color(Violet), Position Of(Event Player), 80); + } +} + +rule("Symmetra: High voltage") +{ + event + { + Player Dealt Final Blow; + Team 1; + Symmetra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Victim, 10); + Play Effect(All Players(All Teams), Bad Explosion, Color(Aqua), Victim, 8); + Damage(Players Within Radius(Victim, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 150); + } +} + +rule("Symmetra: Energy Source") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is True For Any(Players On Hero(Hero(Symmetra), Team Of(Event Player)), Is Using Ultimate(Current Array Element) + && Current Array Element.Abilities[12]) == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 1, 40); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Event Player, 0.100); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Junkrat: Pyromania") +{ + event + { + Player Dealt Knockback; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability != Button(Melee); + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 2, 30); + Set Status(Victim, Null, Burning, 2); + } +} + +rule("Junkrat: Short Fused") +{ + event + { + Player Dealt Damage; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + } + + actions + { + Event Player.Ability_Countdown = 4; + While(Event Player.Ability_Countdown > 0); + Event Player.Ability_Countdown -= 1; + Event Player.Ability_Position = Position Of(Victim) + Vector(Random Real(-2, 2), Random Real(-2, 2), Random Real(-2, 2)); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 4); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Position, 4); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 35); + Set Status(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player, Stunned, 0.800); + Wait(0.200, Ignore Condition); + End; + } +} + +rule("Zenyatta: Vigor") +{ + event + { + Player Dealt Healing; + Team 1; + Zenyatta; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Healee, Null, Invincible, 1); + Wait(0.800, Ignore Condition); + } +} + +rule("Zenyatta: Perfect Balance") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Over Time(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 0.750, 200); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player, 24); + Wait(0.600, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Stench") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Violet), Event Player, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Roadhog: Stench effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 8; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 9); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Rusted Anchor") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ability 1(Event Player)), Event Player, 400, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Roadhog: Rusted Anchor - Reset cooldown") +{ + event + { + Player Earned Elimination; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ability 1(Event Player), 3); + Set Ability Cooldown(Event Player, Button(Ability 1), False); + } +} + +rule("Zarya: Augment") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Scaling Barriers(Event Player, 2, True); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5 + 50; + Set Max Health(Event Player, Event Player.PlayerHealth); + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Zarya), 99999); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Stop Scaling Barriers(Event Player); + } +} + +rule("Zarya: Perpetual Energy") +{ + event + { + Player Dealt Knockback; + Team 1; + Zarya; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Event Player.Abilities[12] == True; + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 9999, 15); + Set Status(Victim, Null, Burning, 9999); + } +} + +rule("Doomfist: Phase Shifter") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + (Is Firing Secondary(Event Player) || Is Using Ability 1(Event Player) || Is Using Ability 2(Event Player)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Event Player, Null, Phased Out, 1); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ultimate(Event Player), 99999); + Event Player.Ability_Position = Position Of(Event Player); + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player), 8); + Event Player.Ability_Active = False; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player.Ability_Position, 16); + While(Event Player.Ability_Active == True); + Damage(Players Within Radius(Event Player.Ability_Position, 8, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 34); + Wait(0.235, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[1]); + Destroy Effect(Event Player.Effects_[2]); + } +} + +rule("Team 1 (Perk): Sharpshooter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Global.Perk[0] == True; + Event Ability != Null; + Distance Between(Event Player, Victim) >= 10; + } + + actions + { + Damage(Victim, Event Player, 50 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Perk): Bulletstorm") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.Perk[1] == True; + (Ammo(Event Player, 0) < Max Ammo(Event Player, 0) || Ammo(Event Player, 1) < Max Ammo(Event Player, 1)) == True; + } + + actions + { + Set Ammo(Event Player, 0, 1000); + Set Ammo(Event Player, 1, 1000); + } +} + +rule("Team 1 Challenges") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + If(Global.Perk[2] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[17] = Last Text ID; + End; + If(Global.Perk[0] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[18] = Last Text ID; + End; + If(Global.Perk[1] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[19] = Last Text ID; + End; + If(Global.MaxHealthDone == 50); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + End; + } +} + +rule("Remove Auto Repair when Player leaves") +{ + event + { + Player Left Match; + Team 1; + All; + } + + actions + { + Global.AutoRepair -= Event Player.Abilities[16]; + } +} + +rule("Refund") +{ + event + { + Subroutine; + Refund; + } + + actions + { + "Refund Money" + Event Player.Money[0] += Event Player.Money[1]; + Event Player.Money[1] = 0; + "Reset Headhunter" + Event Player.Abilities[1] = 0; + "Reset Ambush" + Event Player.Abilities[2] = 0; + "Reset QuickFix" + Event Player.Abilities[3] = 0; + "Reset HeavyWeight" + Event Player.Abilities[4] = 0; + "Reset Charged" + Event Player.Abilities[5] = 0; + "Reset Haste" + Event Player.Abilities[6] = 0; + "Reset HeavyImpact" + Event Player.Abilities[7] = 0; + "Reset HeroTalent1" + Event Player.Abilities[8] = 0; + "Reset SecondWind" + Event Player.Abilities[9] = 0; + "Reset BindingHeal" + Event Player.Abilities[10] = 0; + "Reset Resilience" + Event Player.Abilities[11] = 0; + "Reset HeroTalent2" + Event Player.Abilities[12] = 0; + "Reset Damage" + Event Player.Abilities[13] = 0; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + "Reset Health" + Event Player.Abilities[14] = 0; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + If(Global.MaxHealthDone == 0); + End; + "Reset Healing" + Event Player.Abilities[15] = 0; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + "Reset AutoRepair" + Global.AutoRepair -= Event Player.Abilities[16]; + Event Player.Abilities[16] = 0; + } +} + +rule("Lucio Dash HUD Creation") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + } + + actions + { + If(Event Player.Lucio_Dash_Active == False); + Event Player.Lucio_Dash_Active = True; + Create HUD Text(Event Player, Null, Null, Custom String("{0} Slam on ground - Press: {1}", Ability Icon String(Hero(Wrecking Ball), + Button(Crouch)), Input Binding String(Button(Crouch))), Left, 1000, Color(White), Color(White), Color(White), + Visible To and String, Default Visibility); + Event Player.Lucio_Dash_Icon = Last Text ID; + End; + } +} + +rule("Lucio Dash Remove HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) != Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + } + + actions + { + Destroy HUD Text(Event Player.Lucio_Dash_Icon); + Event Player.Lucio_Dash_Active = False; + } +} + +rule("Lucio Dash") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + Is On Ground(Event Player) == False; + Is Button Held(Event Player, Button(Crouch)) == True; + } + + actions + { + Apply Impulse(Event Player, Down, 20, To World, Cancel Contrary Motion); + } +} + +rule("Ana Self-Nano") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + Ultimate Charge Percent(Event Player) == 100; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Abort If(Global.SelfNanoWorkshopSetting == False && Number Of Players(Team 1) > 1); + Wait(0.100, Ignore Condition); + If(Is Using Ultimate(Event Player) == False); + Create Dummy Bot(Hero(Ana), Team Of(Event Player), -1, Position Of(Event Player) + Backward, Eye Position(Event Player)); + Event Player.AnaEntityID = Last Created Entity; + Wait(0.100, Ignore Condition); + Set Ultimate Charge(Event Player.AnaEntityID, 100); + Start Facing(Event Player.AnaEntityID, Direction Towards(Eye Position(Event Player.AnaEntityID), Position Of(Event Player) + Up), + 1000, To World, Direction and Turn Rate); + Set Invisible(Event Player.AnaEntityID, All); + Set Status(Event Player.AnaEntityID, Null, Phased Out, 9999); + Wait(0.150, Ignore Condition); + Press Button(Event Player.AnaEntityID, Button(Ultimate)); + Set Ultimate Charge(Event Player, 0); + Wait(0.150, Ignore Condition); + Teleport(Event Player.AnaEntityID, Position Of(First Of(Spawn Points(Team Of(Event Player))))); + Wait(10, Ignore Condition); + Destroy Dummy Bot(Team Of(Event Player), Slot Of(Event Player.AnaEntityID)); + End; + } +} + +rule("Reinhard Charge Cancel") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + } + + actions + { + Wait(0.600, Ignore Condition); + Wait Until(Is Button Held(Event Player, Button(Ability 1)), 5); + Set Status(Event Player, Null, Rooted, 0.001); + Wait Until(Event Player.ReinPin, 1); + If(Event Player.ReinPin != 0); + Apply Impulse(Event Player.ReinPin, Facing Direction Of(Event Player), 15, To World, Cancel Contrary Motion); + End; + } +} + +disabled rule("Map Editor Walls") +{ + event + { + Ongoing - Global; + } +} + +rule("Initial Global") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Empty Array; + Global.AllDir = Empty Array; + Global.firstpos = Empty Array; + Global.secondpos = Empty Array; + Global.firstpoint2 = Empty Array; + Global.secondpoint2 = Empty Array; + Global.second = Empty Array; + Global.z = Empty Array; + Global.Wall_ID = Empty Array; + Global.g_beamType = Empty Array; + } +} + +rule("Initial Player") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.filterpos = 0; + Event Player.lastsavedpos = 0; + Event Player.closestbodypos = 0; + Event Player.fullbodypos = 0; + Event Player.prevpos_intersection = 0; + Event Player.active_wall = Empty Array; + Event Player.closestwall = Empty Array; + } +} + +rule("Collision Logic") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Event Player.lastsavedpos = (Eye Position(Event Player) + Position Of(Event Player)) / 2; + Wait(0.016, Ignore Condition); + Event Player.closestwall = Filtered Array(Global.AllPos, Distance Between(Global.AllPos[Current Array Index], Event Player) + <= Distance Between(Global.AllPos[Current Array Index], Global.firstpos[Current Array Index]) + || Event Player.active_wall[Current Array Index] == 1 || (Dot Product(Direction Towards(Current Array Element, + Event Player.lastsavedpos), Global.AllDir[Current Array Index]) > 0) != (Dot Product(Direction Towards(Current Array Element, + Event Player), Global.AllDir[Current Array Index]) > 0)); + For Player Variable(Event Player, x, 0, Count Of(Event Player.closestwall), 1); + Global.z = Index Of Array Value(Global.AllPos, Event Player.closestwall[Event Player.x]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3 || Global.Wall_ID[Global.z] == 5); + If(Y Component Of(Global.firstpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.firstpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.firstpos[Global.z]; + Else If(Y Component Of(Global.secondpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.secondpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.secondpos[Global.z]; + Else; + Event Player.closestbodypos = Position Of(Event Player); + End; + Event Player.fullbodypos = Vector(X Component Of(Eye Position(Event Player)), Y Component Of(Event Player.closestbodypos), + Z Component Of(Eye Position(Event Player))); + Event Player.filterpos = Event Player.fullbodypos + Global.AllDir[Global.z] * Dot Product( + Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) / Dot Product(Global.AllDir[Global.z], + Global.AllDir[Global.z]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3); + If((Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.lastsavedpos), Global.AllDir[Global.z]) > 0) != ( + Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.fullbodypos), Global.AllDir[Global.z]) > 0)); + Event Player.intersection_length = Dot Product(Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) + / Dot Product(Direction Towards(Event Player.lastsavedpos, Event Player.fullbodypos), Global.AllDir[Global.z]); + Event Player.prevpos_intersection = Event Player.fullbodypos + Direction Towards(Event Player.lastsavedpos, + Event Player.fullbodypos) * Vector(1, Empty Array, 1) * Event Player.intersection_length; + If(Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of( + Global.firstpos[Global.z]), Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], + Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of( + Global.firstpos[Global.z]), Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), + Direction Towards(Global.firstpos[Global.z], Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards( + Global.secondpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.prevpos_intersection)) + >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.secondpos[Global.z], Event Player.prevpos_intersection)) >= 0); + Cancel Primary Action(Event Player); + Teleport(Event Player, Event Player.prevpos_intersection + Direction Towards(Event Player.prevpos_intersection, + Event Player.lastsavedpos) * Vector(1, Empty Array, 1) * 2); + End; + End; + End; + Event Player.thickness = 0; + If(Global.Wall_ID[Global.z] == 5); + Event Player.thickness = 4; + Else; + Event Player.thickness = 1; + End; + If(Distance Between(Event Player.fullbodypos, Event Player.filterpos) <= Event Player.thickness && Dot Product(Direction Towards( + Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], Event Player.filterpos)) + >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.firstpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector( + X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), Z Component Of( + Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product( + Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), Y Component Of( + Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], + Event Player.filterpos)) >= 0); + If(!Global.is_Grounded); + Set Gravity(Event Player, 100); + End; + If(Event Player.active_wall[Global.z] == False); + Event Player.active_wall[Global.z] = 1; + If((Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3) && Global.is_Grounded == False); + Set Gravity(Event Player, 100); + Else If(Global.Wall_ID[Global.z] == 5); + Disable Movement Collision With Environment(Event Player, False); + End; + End; + If(Global.Wall_ID[Global.z] == 1); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos) * Vector(1, Empty Array, 1), 0.001, + To World, Cancel Contrary Motion); + Set Move Speed(Event Player, 100 - Dot Product(Direction Towards(Eye Position(Event Player), Eye Position(Event Player) + + World Vector Of(Throttle Of(Event Player), Event Player, Rotation)), Direction Towards(Event Player.filterpos, + Event Player.fullbodypos) * -1) * 100); + Else If(Global.Wall_ID[Global.z] == 3); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos), Speed Of(Event Player), To World, + Cancel Contrary Motion); + End; + Else; + Event Player.active_wall[Global.z] = 0; + Set Move Speed(Event Player, 100); + End; + End; + End; + Loop; + } +} + +rule("Reset") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Count Of(Filtered Array(Event Player.active_wall, Current Array Element != 0)) == 0; + } + + actions + { + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("Effect Creation") +{ + event + { + Ongoing - Global; + } + + actions + { + Wait(5, Ignore Condition); + If(Global.showwalls); + For Global Variable(x, 0, Count Of(Global.AllPos), 1); + If(Global.Wall_ID[Global.x] == 5); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Else; + Skip(Array(14, 0, 5, 10)[Index Of Array Value(Array(1, 2, 3), Global.g_beamType[Global.x]) + 1]); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(9); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(4); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + End; + Wait(0.016, Ignore Condition); + End; + End; + } +} + +rule("Wall Data") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Array(Vector(155.968, 12.470, -30.507), Vector(155.962, 12.472, -62.500), Vector(81.153, 6.453, -103.851), Vector( + 69.148, 6.474, -104.548)); + Global.AllDir = Array(Vector(-1, 0, -0.002), Vector(1, 0, -0.001), Vector(0, 0, 1), Vector(0.001, 0, 1)); + Global.firstpos = Array(Vector(155.971, 11.047, -31.771), Vector(155.964, 11.050, -61.229), Vector(79.761, 5.030, -103.852), + Vector(67.738, 5.022, -104.547)); + Global.secondpos = Array(Vector(155.965, 13.894, -29.242), Vector(155.960, 13.894, -63.771), Vector(82.544, 7.876, -103.851), + Vector(70.558, 7.925, -104.550)); + Global.firstpoint2 = Array(Vector(155.971, 13.894, -31.771), Vector(155.964, 13.894, -61.229), Vector(79.761, 7.876, -103.852), + Vector(67.738, 7.925, -104.547)); + Global.secondpoint2 = Array(Vector(155.965, 11.047, -29.242), Vector(155.960, 11.050, -63.771), Vector(82.544, 5.030, -103.851), + Vector(70.558, 5.022, -104.550)); + Global.z = 3; + Global.g_beamType = Array(1, 1, 1, 1); + Global.showwalls = True; + Global.Wall_ID = Array(5, 5, 5, 5); + } +} + +disabled rule("NEW SHOP") +{ + event + { + Ongoing - Global; + } +} + +rule("Setting Shop Position") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.ShopCamPos = 900 * Up; + Global.ShopPosAngle[1] = Direction From Angles(Horizontal Angle From Direction(Forward), Vertical Angle From Direction(Forward) + - 90); + Global.ShopPosAngle[0] = Cross Product(Global.ShopPosAngle[1], Forward); + Global.ShopBasePos = Global.ShopCamPos - 9 * Global.ShopPosAngle[1] + 142 * Forward; + } +} + +rule("Create Shop Buttons") +{ + event + { + Ongoing - Global; + } + + actions + { + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] + 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] - 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Refund"), + Global.ShopBasePos + 45 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 3, Do Not Clip, Visible To, Color(Green), + Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("[{0}] Leave", + Input Binding String(Button(Reload))), Global.ShopBasePos + 45 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 3, + Do Not Clip, Visible To and String, Color(Green), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("{0}$\n", Local Player.Money[0]), + Global.ShopBasePos + 36.500 * Global.ShopPosAngle[1], 3, Do Not Clip, Visible To and String, Color(White), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("▲"), Update Every Frame( + Global.ShopBasePos - (4 + Vertical Facing Angle Of(Local Player)) * Global.ShopPosAngle[1] + Horizontal Facing Angle Of( + Local Player) * Global.ShopPosAngle[0]), 4, Do Not Clip, Visible To Position and Color, Custom Color( + 245 + 10 * Sine From Radians(4 * Total Time Elapsed), 205 + 50 * Sine From Radians(4 * Total Time Elapsed), + 200 * Sine From Radians(4 * Total Time Elapsed), 255), Default Visibility); + "Headhunter" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[1] ? Custom String("Headhunter II\n  800$") : Custom String("Headhunter I\n  800$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[1] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Ambush" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[2] ? Custom String("Ambush II\n 800$") : Custom String("Ambush I\n 800$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[2] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Quick Fix" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[3] ? Custom String("Quick Fix II\n  700$") : Custom String("Quick Fix I\n  700$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[3] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavyweight" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[4] ? Custom String("Heavyweight II\n  1000$") : Custom String("Heavyweight I\n  1000$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[4] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Charged" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[5] ? Custom String("Charged II\n  700$") : Custom String("Charged I\n  700$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[5] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Haste" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[6] ? Custom String("Haste II\n 700$") : Custom String("Haste I\n 700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[6] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavy Impact" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[7] ? Custom String("Heavy Impact II\n  1000$") : Custom String("Heavy Impact I\n  1000$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[7] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 1" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 1\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[8] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "Second Wind" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[9] ? Custom String("Second Wind II\n   900$") : Custom String("Second Wind I\n   900$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[9] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Binding Heal" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[10] ? Custom String("Binding Heal II\n   700$") : Custom String("Binding Heal I\n   700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[10] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Resilience" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[11] ? Custom String("Resilience II\n  800$") : Custom String("Resilience I\n  800$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[11] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 2" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 2\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[12] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "PlusDamage" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Damage\n  400$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealth" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Health\n 400$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Healing\n  400$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, Visible To and String, + Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "+{0} Auto-Repair\n    400$", Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Global.AutoRepair < 5 ? Color(Green) : Color(Gray), Default Visibility); + "Use Update Every Frame to avoid showing the String when the cursor is out of bounds, resulting in 0\r\n ROW 0" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -33.750 ? Array(Custom String("Leave Buy Menu\n"), Custom String( + ""), Custom String(""), Custom String("Refund your money\n"))[Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) + / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, + Color(White), Default Visibility); + "ROW 1" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 22.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -11.250 ? Array(Custom String("Increase your damage by 5%\n"), + Local Player.Abilities[9] ? Custom String( + "Second Wind II: 60% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds") + : Custom String( + "Second Wind I: 30% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds"), + Local Player.Abilities[5] ? Custom String("Charged II: Ultimates cost 40% less\n") : Custom String( + "Charged I: Ultimates cost 20% less\n"), Local Player.Abilities[1] ? Custom String( + "Headhunter II: Critical hits deal 80% more damage\n") : Custom String("Headhunter I: Critical hits deal 40% more damage\n")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 2" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 36.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 11.250 ? Array(Custom String("Increase your health by 5%\n"), + Local Player.Abilities[10] ? Custom String("Binding Heal II: Heal yourself for 50% the amount when healing allies\n") + : Custom String("Binding Heal I: Heal yourself for 25% the amount when healing allies\n"), + Local Player.Abilities[6] ? Custom String( + " Haste II: Ability cooldown is reduced by 50%\nDoes not affect abilities with multiple charges") : Custom String( + " Haste I: Ability cooldown is reduced by 25%\nDoes not affect abilities with multiple charges"), + Local Player.Abilities[2] ? Custom String("Ambush II: Deal 60% more damage when attacking enemies from behind or above\n") + : Custom String("Ambush I: Deal 30% more damage when attacking enemies from behind or above\n"))[Round To Integer(( + Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 3" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 83.750) < 72.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 33.750 ? Array(Custom String("Increase your healing by 5%\n"), + Local Player.Abilities[11] ? Custom String("Resilience II: Take 30% less damage while below 60% health\n") : Custom String( + "Resilience I: Take 30% less damage while below 30% health\n"), Local Player.Abilities[7] ? Custom String( + "Heavy Impact II: Every hit has a chance to stun the enemy for 2 seconds\n") : Custom String( + "Heavy Impact I: Every hit has a chance to stun the enemy for 1 second\n"), Local Player.Abilities[3] ? Custom String( + "Quick Fix II: Eliminations restore 100 HP and shortly increase speed by 40%\n") : Custom String( + "Quick Fix I: Eliminations restore 50 HP and shortly increase speed by 20%\n"))[Round To Integer((Horizontal Facing Angle Of( + Local Player) + 90) / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, + Visible To and String, Color(White), Default Visibility); + "ROW 4" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 133) < 99.250 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 56.250 ? Array(Custom String( + "Increase your auto-repair by {0}/5s\n", Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Custom String("{0}", Local Player.HeroTalentText[2][1]), Custom String("{0}", Local Player.HeroTalentText[1][1]), + Local Player.Abilities[4] ? Custom String( + "Heavyweight II: Your knock back attacks deal 50% more damage and knock back\n            You receive 33% less knock back") + : Custom String( + "Heavyweight I: Your knock back attacks deal 25% more damage and knock back\n            You receive 20% less knock back")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + } +} + +rule("Toggle Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + !Is Dummy Bot(Event Player) == True; + Is Button Held(Event Player, Button(Reload)) == True; + !Is Communicating Any Emote(Event Player) == True; + } + + actions + { + If(Event Player.isInMenu == False); + Wait Until(!Is Button Held(Event Player, Button(Reload)), 0.500); + If(!Is Button Held(Event Player, Button(Reload))); + Abort; + End; + End; + Event Player.isInMenu = !Event Player.isInMenu; + } +} + +rule("Open Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == True; + } + + actions + { + Event Player.PlayerFacing = Facing Direction Of(Event Player); + Start Camera(Event Player, Global.ShopCamPos, Global.ShopCamPos + Forward, 0); + Disable Hero HUD(Event Player); + Call Subroutine(DisablePlayer); + Set Aim Speed(Event Player, 200); + } +} + +rule("Close Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == False; + } + + actions + { + Stop Camera(Event Player); + Enable Hero HUD(Event Player); + Call Subroutine(EnablePlayer); + Set Aim Speed(Event Player, 100); + Set Facing(Event Player, Event Player.PlayerFacing, To World); + } +} + +rule("Subroutine: Disable Player") +{ + event + { + Subroutine; + DisablePlayer; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + Set Primary Fire Enabled(Event Player, False); + Set Secondary Fire Enabled(Event Player, False); + Set Ability 1 Enabled(Event Player, False); + Set Ability 2 Enabled(Event Player, False); + Set Melee Enabled(Event Player, False); + Set Jump Enabled(Event Player, False); + Set Crouch Enabled(Event Player, False); + Disallow Button(Event Player, Button(Ultimate)); + } +} + +rule("Subroutine: Enable Player") +{ + event + { + Subroutine; + EnablePlayer; + } + + actions + { + Stop Forcing Throttle(Event Player); + Set Primary Fire Enabled(Event Player, True); + Set Secondary Fire Enabled(Event Player, True); + Set Ability 1 Enabled(Event Player, True); + Set Ability 2 Enabled(Event Player, True); + Set Melee Enabled(Event Player, True); + Set Jump Enabled(Event Player, True); + Set Crouch Enabled(Event Player, True); + Allow Button(Event Player, Button(Ultimate)); + } +} + +rule("Buy Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Primary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + Event Player.isInMenu = !Event Player.isInMenu; + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Money[1] != 0); + Call Subroutine(Refund); + Else; + Small Message(Local Player, Custom String("You don't have anything to refund!")); + End; + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[13] += 1; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 2); + If(Event Player.Money[0] >= 900); + Event Player.Money[0] -= 900; + Event Player.Money[1] += 900; + Event Player.Abilities[9] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[5] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[1] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[14] += 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[10] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[6] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[2] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[15] += 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[11] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[7] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[3] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Global.AutoRepair != 5); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Global.AutoRepair += 1; + Event Player.Abilities[16] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[12] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[8] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[4] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + End; + } +} + +rule("Refund Single Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Secondary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[13] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[13] -= 1; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 0); + Event Player.Money[0] += 900; + Event Player.Money[1] -= 900; + Event Player.Abilities[9] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[5] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[1] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[14] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[14] -= 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[10] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[6] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[2] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[15] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[15] -= 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[11] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[7] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[3] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[16] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Global.AutoRepair -= 1; + Event Player.Abilities[16] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[12] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[8] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[4] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + End; + } +} + +rule("Create Player HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Custom String("{0}{1}", + Event Player, Event Player.isInMenu ? Custom String("(In Shop)") : Custom String("")), Custom String("{0}{1}", Is Alive( + Event Player) ? Custom String("{0} HP", Round To Integer(Health(Event Player), Up)) : Custom String("Dead"), Custom String( + ", {0}$", Event Player.Money)), Left, Local Player == Event Player ? -1 : Slot Of(Event Player), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), + Visible To Sort Order String and Color, Default Visibility); + Create HUD Text(Event Player.Abilities[13] || Global.DamageDone ? Event Player : Null, Null, Null, Custom String("+{0}% Damage", + Global.DamageDone + Event Player.Abilities[13] * 5), Left, 913, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[9] ? Event Player : Null, Null, Null, Custom String("Second Wind {0}", + Event Player.Abilities[9] == 1 ? Custom String("I") : Custom String("II")), Left, 908, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[5] ? Event Player : Null, Null, Null, Custom String("Charged {0}", + Event Player.Abilities[5] == 1 ? Custom String("I") : Custom String("II")), Left, 905, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[1] ? Event Player : Null, Null, Null, Custom String("Headhunter {0}", + Event Player.Abilities[1] == 1 ? Custom String("I") : Custom String("II")), Left, 901, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[14] || Global.MaxHealthDone ? Event Player : Null, Null, Null, Custom String("+{0}% Health", + Global.MaxHealthDone + Event Player.Abilities[14] * 5), Left, 914, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[10] ? Event Player : Null, Null, Null, Custom String("Binding Heal {0}", + Event Player.Abilities[10] == 1 ? Custom String("I") : Custom String("II")), Left, 909, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[6] ? Event Player : Null, Null, Null, Custom String("Haste {0}", + Event Player.Abilities[6] == 1 ? Custom String("I") : Custom String("II")), Left, 906, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[2] ? Event Player : Null, Null, Null, Custom String("Ambush {0}", + Event Player.Abilities[2] == 1 ? Custom String("I") : Custom String("II")), Left, 902, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[15] ? Event Player : Null, Null, Null, Custom String("+{0}% Healing", + Event Player.Abilities[15] * 5), Left, 915, Color(White), Color(White), Color(Turquoise), Visible To and String, + Default Visibility); + Create HUD Text(Event Player.Abilities[11] ? Event Player : Null, Null, Null, Custom String("Resilience {0}", + Event Player.Abilities[11] == 1 ? Custom String("I") : Custom String("II")), Left, 910, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[7] ? Event Player : Null, Null, Null, Custom String("Heavy Impact {0}", + Event Player.Abilities[7] == 1 ? Custom String("I") : Custom String("II")), Left, 907, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[3] ? Event Player : Null, Null, Null, Custom String("Quick Fix {0}", + Event Player.Abilities[3] == 1 ? Custom String("I") : Custom String("II")), Left, 903, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Global.AutoRepair ? Event Player : Null, Null, Null, Custom String("{0} total Auto-Repair/5s", + Global.AutoRepair * (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5)), Left, 916, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[2][0], Event Player.HeroTalentText[2][1]), Top, 902, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("Hero Talent 2"), Left, 912, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[1][0], Event Player.HeroTalentText[1][1]), Top, 901, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("Hero Talent 1"), Left, 911, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[4] ? Event Player : Null, Null, Null, Custom String("Heavyweight {0}", + Event Player.Abilities[4] == 1 ? Custom String("I") : Custom String("II")), Left, 904, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + } +} + +rule("Rein Pin detect") +{ + event + { + Player Dealt Knockback; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 1); + Has Status(Victim, Stunned) == True; + } + + actions + { + Event Player.ReinPin = Victim; + Wait(1, Ignore Condition); + Event Player.ReinPin = Null; + } +} + +rule("Boss Rotation") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.activeBoss == True; + } + + actions + { + If(Global.bossRotation == 0 || Global.bossRotation == 3); + Global.bossRotation = 1; + Global.lastBoss[1] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 1); + Global.bossRotation = 2; + Global.lastBoss[2] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 2); + Global.bossRotation = 3; + Global.lastBoss[3] = Hero Of(Global.activeBoss); + End; + } +} + +rule("15 minutes hud") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 10; + } + + actions + { + Create HUD Text(All Players(Team 1), Global.activeBoss ? Custom String("Boss: {0}, HP: {1}/{2}", Hero Of(Global.activeBoss), + Health(Global.activeBoss), Max Health(Global.activeBoss)) : Custom String(""), Null, Null, Top, 900, Color(Red), Color(White), + Color(White), Visible To and String, Default Visibility); + } +} + +rule("debug") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + (Is Button Held(Event Player, Button(Primary Fire)) && Is Button Held(Event Player, Button(Crouch))) == True; + } + + actions + { + Global.TimeSec = 59; + } +} + +disabled rule("debug") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + } + + actions + { + Create HUD Text(Local Player, Custom String("{0}", Position Of(Local Player)), Null, Null, Left, 0, Color(Yellow), Color(White), + Color(White), Visible To and String, Default Visibility); + Set Status(Event Player, Null, Invincible, 9999); + Set Status(Event Player, Null, Phased Out, 9999); + } +} + +rule("ending 1 part 1") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + } + + actions + { + Big Message(All Players(Team 1), Custom String("Exfiltration available! (optional - ends the mode)")); + Create In-World Text(All Players(Team 1), Custom String( + "Exfiltration available! Gather here!\n{0}/{1} Players ready to exfiltrate!", Count Of(Filtered Array(All Players(Team 1), + Distance Between(Vector(186, 11, -46.500), Current Array Element) <= 9)), Count Of(All Players(Team 1))), Vector(186, 15, + -46.500), 1.200, Do Not Clip, Visible To and String, Color(Green), Default Visibility); + } +} + +rule("ending 1 part 2") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + Distance Between(Vector(186, 11, -46.500), All Players(Team 1)) <= 9; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GG! YOU DID IT!")); + Destroy All Dummy Bots; + Disable Movement Collision With Environment(All Players(Team 1), True); + Start Accelerating(All Players(Team 1), Up, 100, 5, To World, Direction Rate and Max Speed); + Wait(5, Ignore Condition); + Declare Team Victory(Team 1); + } +} + +rule("Team 1 (Ability): Second Wind save life") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[9] == True; + Event Player.secondWindActive == True; + Health(Event Player) == 1; + } + + actions + { + Small Message(All Players(All Teams), Custom String("{0} received a second wind!", Event Player)); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Green), Event Player, 1); + Clear Status(Event Player, Unkillable); + Set Player Health(Event Player, Max Health(Event Player)); + Event Player.lastSecondWind = 30; + Event Player.secondWindActive = 0; + } +} + +rule("Team 1 (Ability): Second Wind after buying") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[9] == True; + Event Player.secondWindActive == False; + Event Player.lastSecondWind == 0; + } + + actions + { + If(Random Integer(1, 100) > Event Player.Abilities[9] * 30); + Wait(30, Ignore Condition); + Loop; + End; + Set Status(Event Player, Null, Unkillable, 9999); + Event Player.secondWindActive = 1; + } +} + +rule("Team 1 (Ability): Second Wind counter") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Player.lastSecondWind > 0; + } + + actions + { + Wait(1, Ignore Condition); + Event Player.lastSecondWind -= 1; + Loop If Condition Is True; + } +} \ No newline at end of file diff --git a/defendTheCastleExtended/old_versions/c120.ow b/defendTheCastleExtended/old_versions/c120.ow new file mode 100644 index 0000000..ab9f35c --- /dev/null +++ b/defendTheCastleExtended/old_versions/c120.ow @@ -0,0 +1,9309 @@ +settings +{ + main + { + Description: "Defend Castle v0.6.c120 by HuKuTa94#2589 modified by ShuriZma#2349 - J1K6F (Code Version: v090) - Defend the gate, kill enemies and don't allow them to damage the gate! Torb, Brig and Rein can repair the gate but beware! You never know what the enemy might be hiding until now! Special Thanks to: Shingen#21859 for the Abilities, LemonAid#11644 for the Hero Talents & Josbird for teaching me about Menus! Find the Original Mode on: workshop.codes/BQEGS" + Mode Name: "Defend Castle v0.6.c120" + } + + lobby + { + Max Spectators: 0 + Max Team 1 Players: 4 + Max Team 2 Players: 0 + Return To Lobby: Never + Swap Teams After Match: No + } + + modes + { + Escort + { + enabled maps + { + Havana + } + } + + Team Deathmatch + { + enabled maps + { + } + } + + General + { + Game Mode Start: Immediately + Spawn Health Packs: Disabled + } + } + + workshop + { + Ana can nano herself even if there are other players only if no player targeted: On + Story Heroes: Off + } + + extensions + { + Beam Effects + Kinetic Explosion Effects + Explosion Sounds + Play More Effects + Spawn More Dummy Bots + } +} + +variables +{ + global: + 0: GatePosition + 1: ZenSpawnPositions + 2: SpawnPositionMaxId + 3: LoopIterator1 + 4: BigBossSpawnPositions + 5: PlayerSpawnPositions + 6: GateHealthChase + 7: GateHealth + 8: GateMaxHealth + 9: GateProgressBarColorCurrent + 10: GateProgressBarColorComponent + 11: GateHealthEvent + 12: BastionTargetPositions + 13: SniperPositions + 14: BallSpawnPositions + 15: ZenRespawnTime + 16: TimeMin + 17: TimeSec + 18: DefaultCurrentBot + 19: DefaultHeroBotsPool + 20: DefaultHeroBotsPoolCurrentId + 21: IsDebug + 22: BotOrisaParent + 23: IsStoryHeroes + 24: BotOrisaChild + 25: GateRepairPosition + 26: BotOrisaTargetPosition + 27: BotEchoRespawnPosition + 28: BotEchoTeleportPositions + 29: UpgradeGateMaxHealthValue + 30: UpgradeGateMaxHealthHudId + 31: UpgradePlayerMaxHealthValue + 32: UpgradePlayerMaxHealthHudId + 33: UpgradeCriticalDamageValue + 34: UpgradeCriticalDamageHudId + 35: UpgradeMaxAmmoValue + 36: UpgradeMaxAmmoHudId + 37: UpgradeMaxAmmoMaxValue + 38: UpgradePlayerMaxHealthMaxValue + 39: UpgradeCriticalDamageMaxValue + 40: UpgradeGateMaxHealthMaxValue + 41: DamageDone + 42: IsDebugAINavigation + 43: GameLogicCountOfUniqueHeroes + 44: IsNewWaveGameLogicProcessing + 45: AutoRepair + 46: UpgradePerkSharpshooterValue + 47: Perk + 48: MaxHealthDone + 49: StartMoney + 50: Time5Min + 51: SelfNanoWorkshopSetting + 52: ShopCamPos + 53: ShopBasePos + 54: ShopPosAngle + 55: activeBoss + 56: bossTrigger + 57: bossRotation + 58: lastBoss + 59: Time10Min + 61: challengeCount + 62: UpgradeBossHealthValue + 112: AllPos + 113: AllDir + 114: firstpos + 115: secondpos + 116: firstpoint2 + 117: secondpoint2 + 118: second + 119: z + 120: Wall_ID + 121: showwalls + 122: is_Grounded + 123: g_beamType + 124: x + 125: NodePositions + 126: NodeConnections + 127: DistanceMatrix + + player: + 0: BotSeePlayer + 1: BotDoesUniqueBehaviour + 2: BotEffects + 3: BotRayCastHitPosition + 4: BotEventPosition + 5: CurrentHero + 6: IsDead + 7: IsRespawning + 8: BotBastionArtilleryDidShotsCount + 9: BotCounter + 10: HasBadStatus + 11: EventHealth + 12: HealOverTimeId + 13: BotIsOrisaChild + 14: BotEchoCapturedPlayer + 15: BotPlayersInRadius + 16: BotLoopIterator2 + 17: BotWidowShotTime + 18: BotWidowTeleportTime + 19: IsNanoed + 20: AbilityHUD + 21: Lucio_Dash_Active + 22: Lucio_Dash_Icon + 23: AnaEntityID + 24: Abilities + 25: Money + 26: HeroTalentText + 27: DamageDealt + 28: PlayerHealth + 29: AbilityCountdown + 30: HP_Pool + 31: Effects_ + 32: Ability_Projectile1 + 33: Ability_End + 34: Storm_Projectile + 35: Storm_EndPoint + 36: Storm_Effects + 37: Feared_until + 38: Modification_Damage + 39: Ability_Projectile2 + 40: Ability_Position + 41: Chain_Reaction_On + 42: Chain_Reaction_Immune + 43: Ability_Active + 44: Ability_Resource + 45: secondWindActive + 46: isInMenu + 47: ReinPin + 48: PlayerFacing + 49: isBoss + 50: Gen_Direction + 51: Gen_Available + 52: Ability_Player + 53: Ability_Countdown + 54: lastSecondWind + 105: filterpos + 106: lastsavedpos + 107: closestbodypos + 108: fullbodypos + 109: prevpos_intersection + 110: active_wall + 111: closestwall + 112: x + 113: intersection_length + 114: thickness + 115: BotCancelPathFinding + 116: BotLoopIterator1 + 117: BotTempArray + 118: BotTargetPlayer + 119: BotTargetPosition + 120: BotClosestNodeIdToTarget + 121: BotClosestNodeIdToBot + 122: BotPrevNodeId + 123: BotNextNodeId + 124: BotNextNodePosition + 125: BotCurrentDistanceToTarget + 126: BotShortestDistanceToTarget + 127: BotIsPathFinding +} + +subroutines +{ + 0: BotBastionArtilleryDamage + 1: BotBastionFlameGunDamage + 2: BotBastionRespawn + 3: GateProgressBarColor + 4: BotZenyattaRespawn + 5: BotWidowRespawn + 6: BotBallRespawn + 7: GameLogicAddNextHeroInGame + 8: BotOrisaRespawn + 9: BotLandingFromSky + 10: BotEchoRespawn + 11: BotEchoDetachPlayer + 12: BotEchoFlyToPlayer + 13: BotEchoFlyToPortal + 14: GameLogicSetBotProperties + 15: DisablePlayer + 16: BotApearFromUnderground + 17: BotReinRespawn + 18: PlayerInit + 19: BotInit + 20: PlayerRespawn + 21: BotRespawn + 22: BotWidowBadStatus + 23: GameLogicWave0 + 24: Refund + 25: EnablePlayer + 26: GateRepair + 124: BotStartPathFinding + 125: BotGetClosestNodeIdToTarget + 126: BotGetNextNodeIdAndPosition + 127: BotResetPathFinding +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("MAP: HAVANA") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Havana); + } + + actions + { + Global.NodePositions = Array(Vector(147.588, 6.425, -46.749), Vector(136.181, 6.425, -57.159), Vector(130.189, 6.425, -63.781), + Vector(123.305, 6.425, -57.983), Vector(125.678, 6.504, -46.633), Vector(114.485, 7.471, -46.699), Vector(138.743, 6.425, + -32.974), Vector(126.498, 6.425, -39.920), Vector(124.572, 10.434, -34.300), Vector(138.605, 5.359, -18.647), Vector(119.009, + 2.331, -31.024), Vector(121.138, 5.228, -19.933), Vector(126.722, 6.425, -29.505), Vector(102.762, 3.157, -33.609), Vector( + 76.030, 7.418, -74.087), Vector(83.720, 9.425, -33.744), Vector(97.439, 7.238, -42.379), Vector(86.252, 12.416, -47.261), + Vector(65.178, 11.425, -73.187), Vector(97.466, 7.269, -50.596), Vector(113.039, 7.424, -37.337), Vector(106.179, 7.450, + -46.143), Vector(90.086, 7.411, -44.653), Vector(78.752, 7.418, -62.140), Vector(82.124, 7.428, -44.229), Vector(90.675, 7.231, + -51.234), Vector(85.717, 4.692, -63.446), Vector(90.830, 4.330, -70.697), Vector(102.425, 2.387, -72.817), Vector(81.443, + 4.425, -81.648), Vector(70.743, 6.418, -81.495), Vector(69.738, 6.419, -96.344), Vector(127.586, 12.643, -63.344), Vector( + 118.911, 13.468, -58.008), Vector(102.885, 1.092, -56.579), Vector(100.009, 2.967, -67.139), Vector(106.703, 0.465, -44.628), + Vector(81.695, 7.418, -52.140), Vector(126.979, 12.393, -55.079), Vector(153.720, 18.578, -21.745), Vector(155.301, 18.619, + -17.595), Vector(133.043, 10.425, -26.625), Vector(114.646, 7.278, -57.336), Vector(95.160, 3.688, -81.194), Vector(78.456, + 5.418, -93.581), Vector(75.455, 5.418, -101.492), Vector(148.071, 9.432, -32.123), Vector(146.706, 9.425, -27.858), Vector( + 144.273, 9.445, -63.119), Vector(144.278, 9.454, -58.447)); + Global.NodeConnections = Array(Array(1, 6, 4, 7), Array(2, 1, 4, 6, 7, 0, 49), Array(1, 3), Array(2, 4, 42), Array(3, 1, 5, 7, 6, + 1, 0), Array(4, 7, 20, 21, 19, 16, 42), Array(7, 1, 4, 1, 9, 12, 0, 46), Array(4, 5, 6, 1, 1, 12, 0), Array(7, 41), Array(6, + 11), Array(11, 13), Array(9, 10, 13), Array(6, 7, 10), Array(10, 16, 36), Array(18, 23, 30), Array(17, 24), Array(13, 19, 22, + 21, 25, 5), Array(15, 22, 25, 23), Array(14), Array(16, 21, 22, 26, 27, 35, 25, 5), Array(5, 13, 10), Array(19, 16, 5, 13, 22, + 34), Array(16, 19, 21, 24, 25), Array(14, 25, 26, 37), Array(22, 15, 37), Array(23, 22, 19, 16, 26, 27, 35, 37), Array(25, 19, + 27, 35, 29), Array(19, 26, 25, 29, 35, 43), Array(35, 34, 43), Array(27, 26, 30, 43, 44), Array(29, 14, 31), Array(30, 29, 45), + Array(33, 38, 1, 48), Array(32, 38, 42), Array(35, 36, 28), Array(28, 19, 25, 27, 26, 34), Array(13, 34), Array(25, 23, 24), + Array(5, 4, 1, 6, 1, 32, 33, 0), Array(40), Array(39), Array(6, 8, 47, 46), Array(3, 5, 34), Array(28, 27, 29, 44), Array(29, + 43, 45), Array(44, 31), Array(6, 47), Array(46, 41), Array(49, 32), Array(1, 0, 6, 48)); + Global.DistanceMatrix = Array(Array(0, 1, 2, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, + 4, 5, 4, 4, 5, 5, 5, 0, 0, 4, 3, 5, 6, 7, 2, 3, 3, 2), Array(1, 0, 1, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, + 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 3, 4, 4, 4, 5, 5, 4, 0, 0, 4, 3, 5, 6, 7, 2, 3, 2, 1), Array(2, 1, 0, 1, 2, 3, 2, 2, 6, 3, 4, 4, + 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 4, 6, 7, 8, 4, 5, 3, 4, 4, 6, 5, 0, 0, 5, 2, 5, 6, 7, 3, 4, 3, 2), Array(2, 2, + 1, 0, 1, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, 5, 6, 2, 3, 3, 5, 6, 0, 0, 5, 1, 4, + 5, 6, 3, 4, 4, 3), Array(1, 1, 2, 1, 0, 1, 1, 1, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, + 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, 2, 3, 3, 2), Array(2, 2, 3, 2, 1, 0, 2, 1, 6, 3, 2, 3, 2, 2, 4, 4, 1, 5, 5, 1, 1, 1, 2, 3, + 3, 2, 2, 2, 3, 3, 4, 5, 5, 6, 2, 2, 3, 3, 6, 0, 0, 5, 1, 3, 4, 5, 3, 4, 4, 3), Array(1, 1, 2, 2, 1, 2, 0, 1, 4, 1, 2, 2, 1, 3, + 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 4, 5, 4, 4, 4, 5, 5, 0, 0, 3, 3, 5, 6, 7, 1, 2, 3, 2), Array(1, 1, 2, 2, + 1, 1, 1, 0, 5, 2, 2, 3, 1, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, + 2, 3, 3, 2), Array(2, 2, 3, 3, 2, 2, 2, 1, 0, 3, 3, 4, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, + 5, 5, 6, 0, 0, 1, 3, 5, 6, 7, 2, 2, 4, 3), Array(2, 2, 3, 3, 2, 3, 1, 2, 5, 0, 2, 1, 2, 2, 6, 6, 3, 7, 7, 4, 4, 4, 4, 5, 5, 4, + 5, 5, 5, 6, 7, 8, 5, 6, 4, 5, 3, 5, 6, 0, 0, 4, 4, 6, 7, 8, 2, 3, 4, 3), Array(4, 4, 5, 5, 4, 3, 3, 4, 7, 2, 0, 1, 4, 1, 5, 5, + 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 7, 8, 3, 4, 2, 4, 8, 0, 0, 6, 4, 5, 6, 7, 4, 5, 6, 5), Array(3, 3, 4, 4, 3, 3, + 2, 3, 6, 1, 1, 0, 3, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 6, 7, 3, 4, 2, 4, 7, 0, 0, 5, 4, 5, 6, 7, 3, 4, + 5, 4), Array(2, 2, 3, 3, 2, 2, 1, 1, 5, 2, 1, 2, 0, 2, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, 3, 5, + 6, 0, 0, 4, 3, 5, 6, 7, 2, 3, 4, 3), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 3, 1, 2, 4, 0, 4, 4, 1, 5, 5, 2, 3, 2, 2, 3, 3, 2, 3, 3, + 3, 4, 5, 6, 7, 8, 2, 3, 1, 3, 8, 0, 0, 7, 3, 4, 5, 6, 5, 6, 6, 5), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 5, 6, 6, 4, 0, 4, 3, 5, + 1, 3, 5, 4, 3, 1, 3, 2, 2, 3, 4, 2, 1, 2, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 3, 3, 3, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, + 5, 10, 7, 5, 6, 6, 4, 3, 0, 3, 1, 4, 3, 5, 3, 2, 2, 1, 2, 3, 3, 4, 4, 4, 5, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 4, 5, 6, 7, 8, + 8, 7), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 3, 3, 0, 4, 4, 1, 2, 1, 1, 2, 2, 1, 2, 2, 3, 3, 4, 5, 6, 7, 2, 2, 2, 2, + 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 1, 2, 0, 3, 2, 4, 2, 1, 1, 2, 1, 2, 2, + 3, 3, 3, 4, 8, 9, 3, 2, 4, 2, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 6, 7, 7, 5, 1, 5, 4, 6, + 0, 4, 6, 5, 4, 2, 4, 3, 3, 4, 5, 3, 2, 3, 10, 11, 5, 4, 6, 3, 11, 0, 0, 10, 6, 4, 4, 4, 8, 9, 9, 8), Array(3, 3, 4, 3, 2, 1, 3, + 2, 7, 4, 3, 4, 3, 2, 3, 3, 1, 4, 4, 0, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 3, 4, 6, 7, 2, 1, 3, 2, 7, 0, 0, 6, 2, 2, 3, 4, 4, 5, 5, + 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 3, 1, 2, 3, 1, 5, 5, 2, 6, 6, 2, 0, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 6, 7, 3, 3, 2, 4, 7, + 0, 0, 6, 2, 4, 5, 6, 4, 5, 5, 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 4, 3, 1, 4, 5, 1, 2, 0, 1, 3, 2, 2, 2, 2, 2, + 3, 4, 5, 6, 7, 1, 2, 2, 3, 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 3, 2, 1, 3, 4, + 1, 3, 1, 0, 2, 1, 1, 2, 2, 3, 3, 4, 5, 7, 8, 2, 2, 3, 2, 8, 0, 0, 7, 3, 3, 4, 5, 5, 6, 6, 5), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, + 6, 4, 5, 5, 3, 1, 3, 2, 4, 2, 2, 4, 3, 2, 0, 2, 1, 1, 2, 3, 2, 2, 3, 8, 9, 3, 2, 4, 1, 9, 0, 0, 8, 4, 3, 3, 4, 6, 7, 7, 6), + Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 3, 1, 2, 2, 4, 2, 4, 2, 1, 2, 0, 2, 3, 3, 4, 4, 4, 5, 8, 9, 3, 3, 4, 1, 9, 0, + 0, 8, 4, 4, 5, 6, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 2, 3, 1, 4, 3, 1, 3, 2, 1, 1, 2, 0, 1, 1, 2, 2, + 3, 4, 7, 8, 2, 1, 3, 1, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, + 3, 2, 2, 2, 3, 1, 0, 1, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 2, 2, 3, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, + 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 0, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 1, 2, 3, 5, 6, 6, 5), Array( + 5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 4, 5, 3, 6, 5, 2, 4, 3, 3, 3, 4, 2, 2, 2, 0, 2, 3, 4, 8, 9, 1, 1, 2, 3, 9, 0, 0, 8, + 4, 1, 2, 3, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 2, 5, 3, 6, 3, 2, 4, 3, 3, 3, 4, 2, 1, 1, 2, 0, 1, 2, + 8, 9, 3, 2, 4, 3, 9, 0, 0, 8, 4, 1, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 1, 5, 4, 6, 2, 3, 5, 4, + 4, 2, 4, 3, 2, 2, 3, 1, 0, 1, 9, 10, 4, 3, 5, 3, 10, 0, 0, 9, 5, 2, 2, 2, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, + 7, 6, 5, 2, 6, 4, 7, 3, 3, 5, 4, 4, 3, 5, 3, 2, 2, 3, 1, 1, 0, 9, 10, 4, 3, 5, 4, 10, 0, 0, 9, 5, 2, 2, 1, 7, 8, 8, 7), Array( + 2, 1, 2, 3, 2, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 4, 5, 6, 7, 0, 1, 3, 4, 4, 5, 1, 0, 0, 5, + 2, 5, 6, 7, 3, 4, 1, 2), Array(2, 2, 3, 2, 2, 2, 2, 3, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, + 1, 0, 2, 3, 3, 5, 1, 0, 0, 5, 1, 4, 5, 6, 3, 4, 2, 3), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 5, 3, 4, 5, 2, 4, 5, 3, 6, 5, 2, 4, 3, + 3, 3, 4, 2, 2, 2, 1, 3, 4, 5, 8, 9, 0, 1, 1, 3, 9, 0, 0, 8, 4, 2, 3, 4, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, + 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 1, 1, 2, 3, 4, 7, 8, 1, 0, 2, 2, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(5, 5, + 6, 5, 4, 3, 5, 4, 9, 4, 2, 3, 5, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 8, 9, 1, 2, 0, 4, 9, 0, 0, 8, 4, 3, + 4, 5, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 2, 2, 3, 3, 2, 4, 3, 2, 1, 1, 1, 2, 2, 3, 3, 3, 4, 8, 9, + 3, 2, 4, 0, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(1, 1, 2, 2, 1, 1, 1, 2, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, + 4, 3, 3, 3, 4, 4, 5, 6, 1, 1, 3, 3, 4, 4, 0, 0, 0, 4, 2, 4, 5, 6, 2, 3, 2, 2), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(2, 2, 3, 3, 2, 3, 1, 2, 1, 2, 3, 3, 2, + 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 0, 4, 6, 7, 8, 1, 1, 4, 3), Array(3, 3, 2, + 1, 2, 1, 3, 2, 7, 4, 3, 4, 3, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 6, 7, 1, 2, 2, 4, 7, 0, 0, 6, 0, 3, 4, + 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 3, 5, 3, 6, 4, 2, 4, 3, 3, 3, 4, 2, 2, 1, 1, 1, 2, 3, 8, 9, 2, + 2, 3, 3, 9, 0, 0, 8, 4, 0, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 3, 6, 4, 7, 4, 3, 5, 4, 4, 4, 5, + 3, 2, 2, 2, 1, 2, 2, 9, 10, 3, 3, 4, 4, 10, 0, 0, 9, 5, 1, 0, 1, 7, 8, 8, 7), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 7, 8, 7, 6, + 3, 7, 5, 8, 4, 4, 6, 5, 5, 4, 6, 4, 3, 3, 3, 2, 2, 1, 10, 11, 4, 4, 5, 5, 11, 0, 0, 10, 6, 2, 1, 0, 8, 9, 9, 8), Array(2, 2, 3, + 3, 2, 3, 1, 2, 3, 2, 3, 3, 2, 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 2, 4, 6, 7, + 8, 0, 1, 4, 3), Array(3, 3, 4, 4, 3, 4, 2, 3, 2, 3, 4, 4, 3, 5, 8, 8, 5, 9, 9, 5, 5, 5, 6, 7, 7, 6, 6, 6, 7, 7, 8, 9, 6, 7, 6, + 6, 6, 7, 7, 0, 0, 1, 5, 7, 8, 9, 1, 0, 5, 4), Array(2, 2, 3, 4, 3, 3, 2, 3, 6, 3, 4, 4, 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, + 5, 5, 5, 5, 6, 7, 8, 1, 2, 4, 5, 5, 6, 2, 0, 0, 5, 3, 6, 7, 8, 3, 4, 0, 1), Array(1, 1, 2, 3, 2, 3, 1, 2, 5, 2, 3, 3, 2, 4, 7, + 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 2, 3, 5, 5, 5, 6, 3, 0, 0, 4, 4, 6, 7, 8, 2, 3, 1)); + } +} + +rule("SUBROUTINE: BOT - RESET PATH FINDING") +{ + event + { + Subroutine; + BotResetPathFinding; + } + + actions + { + Event Player.BotTargetPlayer = -1; + Event Player.BotTargetPosition = -1; + Event Player.BotPrevNodeId = -1; + Event Player.BotClosestNodeIdToTarget = -1; + Event Player.BotNextNodeId = -1; + Event Player.BotNextNodePosition = -1; + Event Player.BotIsPathFinding = False; + Event Player.BotCancelPathFinding = False; + Stop Throttle In Direction(Event Player); + disabled Stop Facing(Event Player); + } +} + +rule("SUBROUTINE: BOT - START PATH FINDING") +{ + event + { + Subroutine; + BotStartPathFinding; + } + + actions + { + disabled Abort If(Event Player.BotIsPathFinding == True); + Call Subroutine(BotGetNextNodeIdAndPosition); + disabled Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Event Player.BotIsPathFinding = True; + } +} + +rule("SUBROUTINE: BOT - GET NEXT NODE ID AND POSITION") +{ + event + { + Subroutine; + BotGetNextNodeIdAndPosition; + } + + actions + { + "BOT JUST START FOLLOW PATH OR LOST NEXT NODE" + If(Event Player.BotPrevNodeId == -1); + Event Player.BotClosestNodeIdToBot = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array(Global.NodePositions, + Is In Line of Sight(Position Of(Event Player) + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS) == True), + Distance Between(Position Of(Event Player), Current Array Element))[0]); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + "NEXT NODE IS TARGET (DISTANCE TO TARGET NODE = 1)" + If(Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1); + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToTarget; + "CHECK CONNECTIONS OF REACHED NODE" + Else; + Event Player.BotShortestDistanceToTarget = 999; + Event Player.BotCurrentDistanceToTarget = Event Player.BotShortestDistanceToTarget; + Event Player.BotTempArray = Global.NodeConnections[Event Player.BotClosestNodeIdToBot]; + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotTempArray), 1); + Event Player.BotCurrentDistanceToTarget = Global.DistanceMatrix[Event Player.BotTempArray[Event Player.BotLoopIterator1]][Event Player.BotClosestNodeIdToTarget]; + If(Event Player.BotCurrentDistanceToTarget < Event Player.BotShortestDistanceToTarget); + Event Player.BotShortestDistanceToTarget = Event Player.BotCurrentDistanceToTarget; + Event Player.BotNextNodeId = Event Player.BotTempArray[Event Player.BotLoopIterator1]; + End; + End; + End; + "NEXT NODE IS HIGHER THAN BOT AND BOT DIDN'T REACH CLOSEST NODE" + If(Y Component Of(Position Of(Event Player)) - Y Component Of(Global.NodePositions[Event Player.BotNextNodeId]) + < -3 && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + "BOT CAN SEE TARGET POSITION AND NEXT NODE IS TARGET" + Else If( + Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1 && Is In Line of Sight( + Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotTargetPosition + Vector(0, 2, 0), Barriers Do Not Block LOS)); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Abort; + "BOT CAN'T SEE NEXT NODE AND PREV NODE != REACHED NODE" + Else If(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), + Global.NodePositions[Event Player.BotNextNodeId] + Vector(0, 2, 0), Barriers Do Not Block LOS) + == False && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + End; + Event Player.BotNextNodePosition = Global.NodePositions[Event Player.BotNextNodeId]; + } +} + +rule("SUBROUTINE: BOT - GET CLOSEST NODE ID AND POSITION TO TARGET") +{ + event + { + Subroutine; + BotGetClosestNodeIdToTarget; + } + + actions + { + Event Player.BotTargetPosition = Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Event Player.BotTargetPosition; + Event Player.BotClosestNodeIdToTarget = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array( + Global.NodePositions, Is In Line of Sight(Event Player.BotTargetPosition + Vector(0, 2, 0), Current Array Element, + Barriers Do Not Block LOS) == True), Distance Between(Event Player.BotTargetPosition, Current Array Element))[0]); + } +} + +rule("BOT: PATH FINDING - START") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + (Event Player.BotTargetPosition != -1 || Event Player.BotTargetPlayer != -1) == True; + } + + actions + { + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - CANCEL") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotCancelPathFinding == True; + } + + actions + { + Start Rule(BotResetPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - LOST THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + (Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotNextNodePosition + Vector(0, 2.500, 0), + Barriers Do Not Block LOS) == False && Speed Of In Direction(Event Player, Throttle Of(Event Player)) < 2) == True; + } + + actions + { + Wait(0.500, Abort When False); + "RESET PREV NODE ID TO INFORM BOT THAT IT LOST NEXT NODE" + Event Player.BotPrevNodeId = -1; + "TRY FIND NEW NEXT NODE" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodeId), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +rule("BOT: PATH FINDING - REACHED THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotClosestNodeIdToTarget >= 0; + (Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotNextNodePosition), 0, Z Component Of(Event Player.BotNextNodePosition))) < 0.850) == True; + } + + actions + { + Event Player.BotPrevNodeId = Event Player.BotNextNodeId; + Event Player.BotClosestNodeIdToBot = Event Player.BotNextNodeId; + "BOT'S TARGET IS PLAYER" + If(Event Player.BotTargetPlayer != -1); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + Event Player.BotCurrentDistanceToTarget = Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of( + Position Of(Event Player))), Vector(X Component Of(Event Player.BotTargetPosition), 0, Z Component Of( + Event Player.BotTargetPosition))); + "BOT REACHED THE TARGET NODE OR TARGET POSITION" + If(Event Player.BotNextNodeId == Event Player.BotClosestNodeIdToTarget || Event Player.BotCurrentDistanceToTarget <= 0.850); + "BOT DIDN'T REACH TARGET POSITION" + If(Event Player.BotCurrentDistanceToTarget > 0.850); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Skip(6); + "BOT REACHED TARGET" + Else; + Call Subroutine(BotResetPathFinding); + Abort; + End; + End; + "CONTINUE FOLLOW PATH" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: GAME MODE INIT - WORKSHOP SETTINGS") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.IsDebug = False; + Global.IsDebugAINavigation = False; + Global.GateMaxHealth = Workshop Setting Integer(Custom String("DEFEND CASTLE"), Custom String("GATE MAX HEALTH"), 500, 100, 1000, + 0); + Global.IsStoryHeroes = Workshop Setting Toggle(Custom String("DEFEND CASTLE"), Custom String("Story Heroes"), True, 0); + Global.SelfNanoWorkshopSetting = Workshop Setting Toggle(Custom String("Ana Self Nano"), Custom String( + "Ana can nano herself even if there are other players (only if no player targeted)"), False, 0); + } +} + +rule("GLOBAL: GAME MODE INIT - COMMON PROPERTIES") +{ + event + { + Ongoing - Global; + } + + actions + { + Create HUD Text(All Players(All Teams), Null, Null, Custom String( + "DEFEND CASTLE v0.6.c120 BY HUKUTA94#2589\r\nmodified by ShuriZma#2349\r\nDiscord: discord.shurizma.de\r\n{0}", Custom String( + "Special Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents &\nJosbird for teaching me about Menus{0}", + Custom String("{0}", Custom String(" \nPS: SHINGEN PLS COME BACK")))), Right, -1000, Null, Null, Color(White), Visible To, + Default Visibility); + Global.GateRepairPosition = Vector(153, 8, -46.500); + Global.GatePosition = Vector(148.800, 6, -46.400); + Global.BallSpawnPositions = Array(Vector(104, 7, -46), Vector(106, 2, -31)); + Global.SniperPositions = Array(Vector(154, 18, -22.600), Vector(86, 12, -46.600), Vector(80.880, 11.300, -71.600), Vector(98, 9, + -19)); + Global.ZenSpawnPositions = Array(Vector(79.500, 5, -100), Vector(90, 4, -88), Vector(65, 11, -70), Vector(85, 4, -68), Vector(96, + 2, -73), Vector(84, 7, -47), Vector(95, 9, -34), Vector(108, 1.700, -28), Vector(113, 7, -37), Vector(123, 5, -19), Vector(144, + 5, -19), Vector(123, 6, -39), Vector(123, 6, -61), Vector(129, 6, -30.500), Vector(135, 6, -63)); + Global.PlayerSpawnPositions = Array(Vector(153.300, 10, -63.800), Vector(153.300, 10, -61.700), Vector(153.300, 10, -31.700), + Vector(153.300, 10, -29.600)); + Global.BigBossSpawnPositions = Array(Vector(78, 4, -84), Vector(95, 4, -82)); + Global.BastionTargetPositions = Array(Vector(131, 12, -62), Vector(115, 7, -46), Objective Position(2), Vector(136, 10, -27)); + Global.SpawnPositionMaxId = 2; + Global.BotOrisaTargetPosition = Vector(104, 7, -46); + Global.BotEchoRespawnPosition = Vector(130, 23, -44); + Global.BotEchoTeleportPositions = Array(Vector(88, 23, -79), Vector(108, 18, -27)); + Global.DefaultHeroBotsPool = Array(Hero(Zenyatta), Hero(Widowmaker), Null, Hero(Bastion), Hero(Echo), Hero(Bastion)); + Global.ZenRespawnTime = 10; + Global.GameLogicCountOfUniqueHeroes = 5; + Global.lastBoss = Array(Null, Null, Null, Null); + Create Effect(All Players(Team 1), Ring, Color(Sky Blue), Vector(186, 11, -46.500), 9, Visible To Position and Radius); + } +} + +disabled rule("PLAYER: DEBUG - PRESS INTERACT") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Host Player == True; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + disabled Modify Player Score(Event Player, 10); + disabled Global.GateHealth -= 5; + disabled Start Rule(GateProgressBarColor, Restart Rule); + Global.TimeSec = 59; + Set Status(Event Player, Null, Phased Out, 9999); + disabled Set Ultimate Charge(Event Player, 100); + disabled Kill(Event Player, Null); + disabled Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: DEBUG - AI NAVIGATION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.IsDebugAINavigation == True; + } + + actions + { + For Global Variable(LoopIterator1, 0, Count Of(Global.NodePositions), 1); + Create Effect(All Players(All Teams), Sphere, Color(Red), Global.NodePositions[Global.LoopIterator1], 0.850, Visible To); + Create In-World Text(All Players(All Teams), Custom String("NODE {0}", Global.LoopIterator1), + Global.NodePositions[Global.LoopIterator1], 1.200, Clip Against Surfaces, Visible To, Color(White), Default Visibility); + End; + } +} + +disabled rule("GLOBAL: DEBUG - CREATE BOTS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + Create Dummy Bot(Hero(Bastion), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + Create Dummy Bot(Hero(Orisa), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +disabled rule("PLAYER: DEBUG - INFOS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + Host Player == Event Player; + Has Spawned(Event Player) == True; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Create HUD Text(Event Player, Custom String("POS {0}\r\nFACING {1}", Position Of(Event Player), Facing Direction Of(Event Player)), + Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + Create HUD Text(Event Player, Custom String("SERVER PERFORMANCE\r\nLOAD {0}%\r\nPEAK {1}%\r\nAVG {2}%", Server Load, + Server Load Peak, Server Load Average), Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create Progress Bar HUD Text(Event Player, 45, Custom String("45 / 100 KILLS"), Left, -99, Color(Blue), Color(White), + Visible To Values and Color, Default Visibility); + disabled Create HUD Text(Event Player, Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Null, Custom String( + "LEVEL 1 - 50 AMMO CLIP"), Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + "ЭФФЕКТ С ОФФСЕТОМ ОТ ПОЗИЦИИ ГЛАЗ" + disabled Create Beam Effect(All Players(All Teams), Bad Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + Facing Direction Of( + Event Player) * 3, Eye Position(Event Player) + Facing Direction Of(Event Player) * 50, Color(Purple), + Visible To Position and Radius); + } +} + +disabled rule("=== TEAM UPGRADES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: TEAM UPGRADES - INIT") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.UpgradeMaxAmmoMaxValue[0] = 250; + Global.UpgradeMaxAmmoMaxValue[1] = 500; + Global.UpgradeMaxAmmoMaxValue[2] = 1000; + Global.UpgradeCriticalDamageMaxValue[0] = 10; + Global.UpgradeCriticalDamageMaxValue[1] = 10; + Global.UpgradeCriticalDamageMaxValue[2] = 10; + Global.UpgradePlayerMaxHealthMaxValue[0] = 2500; + Global.UpgradePlayerMaxHealthMaxValue[1] = 5000; + Global.UpgradePlayerMaxHealthMaxValue[2] = 10000; + Global.UpgradeGateMaxHealthMaxValue[0] = Round To Integer(Global.GateMaxHealth + Global.GateMaxHealth * 0.500, Up); + Global.UpgradeGateMaxHealthMaxValue[1] = Global.UpgradeGateMaxHealthMaxValue[0] + Global.UpgradeGateMaxHealthMaxValue[0]; + Global.UpgradeGateMaxHealthMaxValue[2] = Global.UpgradeGateMaxHealthMaxValue[1] + Global.UpgradeGateMaxHealthMaxValue[1]; + Abort If(Global.IsDebug == False); + Global.UpgradeMaxAmmoMaxValue[0] = 1; + Global.UpgradeCriticalDamageMaxValue[0] = 1; + Global.UpgradePlayerMaxHealthMaxValue[0] = 1; + Global.UpgradeGateMaxHealthMaxValue[0] = 1; + Global.UpgradeMaxAmmoMaxValue[1] = 1; + Global.UpgradeCriticalDamageMaxValue[1] = 1; + Global.UpgradePlayerMaxHealthMaxValue[1] = 1; + Global.UpgradeGateMaxHealthMaxValue[1] = 1; + Global.UpgradeMaxAmmoMaxValue[2] = 1; + Global.UpgradeCriticalDamageMaxValue[2] = 1; + Global.UpgradePlayerMaxHealthMaxValue[2] = 1; + Global.UpgradeGateMaxHealthMaxValue[2] = 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GATE'S MAX HEALTH UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Global.GateMaxHealth = Global.UpgradeGateMaxHealthMaxValue[0]; + Global.GateHealth = Global.GateMaxHealth; + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Right, 1, Color( + Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X GATE REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[1]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X GATE REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X GATE REPAIR"), Right, 2, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X AUTO-REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[2]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[2] = Last Text ID; + Global.GateHealth = Global.GateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 3 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X AUTO-REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X AUTO-REPAIR"), Right, 3, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.UpgradeGateMaxHealthHudId[2] = Last Text ID; + Global.GateHealth = Global.GateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - PLAYER'S MAX HEALTH - DEALT HEALING") +{ + event + { + Player Received Healing; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + disabled Healer != Event Player; + Global.UpgradePlayerMaxHealthValue < Global.UpgradePlayerMaxHealthMaxValue[2]; + } + + actions + { + Global.UpgradePlayerMaxHealthValue += Event Healing; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +50%"), Right, 4, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("Up You Go: You respawn twice as fast"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[1]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.MaxHealthDone = 50; + All Players(Team 1).PlayerHealth = 100 + Global.MaxHealthDone + All Players(Team 1).Abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).PlayerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK UP YOU GO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("UP YOU GO UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String("Up You Go"), + Right, 5, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +100%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[2]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[2] = Last Text ID; + Set Respawn Max Time(All Players(Team 1), 5); + Heal(All Players(Team 1), Null, 9999); + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.Perk[2] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[17] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH 2 UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +100%"), Right, 6, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[2] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.MaxHealthDone = 150; + All Players(Team 1).PlayerHealth = 100 + Global.MaxHealthDone + All Players(Team 1).Abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).PlayerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Hero Of(Victim) == Hero(Widowmaker); + Global.UpgradeCriticalDamageValue < Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradeCriticalDamageValue += 1; + Small Message(All Players(Team 1), Custom String("CRITICAL DAMAGE CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - CRITICAL DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("CRITICAL DAMAGE 150% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "CRITICAL DAMAGE 150%"), Right, 7, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String( + "Sharpshooter: Deal 40% more damage to enemies that are further than 15 meters away"), Custom String("KILL ECHO {0}/{1}", + Global.UpgradePerkSharpshooterValue, Global.UpgradeCriticalDamageMaxValue[1]), Left, 14, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - UNLOCKED") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.500); + } +} + +rule("PLAYER: UPGRADE - PERK SHARPSHOOTER - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Echo); + Global.UpgradePerkSharpshooterValue < Global.UpgradeCriticalDamageMaxValue[1]; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradePerkSharpshooterValue += 1; + Small Message(All Players(Team 1), Custom String("SHARPSHOOTER CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - PERK SHARPSHOOTER - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("SHARPSHOOTER UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Sharpshooter"), Right, 8, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("-10% BOSS HEALTH"), Custom String("KILL Bosses {0}/{1}", + Global.UpgradeBossHealthValue, Global.UpgradeCriticalDamageMaxValue[2]), Left, 14, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[2] = Last Text ID; + Global.Perk[0] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[18] = Last Text ID; + Global.challengeCount += 1; + } +} + +disabled rule("PLAYER: UPGRADE - -10% BOSS HEALTH - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]; + Global.UpgradeBossHealthValue < Global.UpgradeCriticalDamageMaxValue[2]; + Victim.isBoss == 1; + } + + actions + { + Global.UpgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - -10% BOSS HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("-10% BOSS HEALTH UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "-10% BOSS HEALTH"), Right, 9, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[2] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - MAX AMMO - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Zenyatta); + Global.UpgradeMaxAmmoValue < Global.UpgradeMaxAmmoMaxValue[2]; + } + + actions + { + If(Event Player.isBoss == 1); + Global.UpgradeMaxAmmoValue += 10; + Else; + Global.UpgradeMaxAmmoValue += 1; + End; + } +} + +rule("GLOBAL: UPGRADE - MAX AMMO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("MAX AMMO 200% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "MAX AMMO 200%"), Right, 10, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("Bulletstorm: Your weapon can hold unlimited ammo"), + Custom String("KILL {2}: {0}/{1}", Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[1], Hero(Zenyatta)), Left, 15, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0) * 2); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1) * 2); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0)); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1)); + End; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK BULLETSTORM - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("BULLETSTORM UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Bulletstorm"), Right, 11, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("+50% DAMAGE"), Custom String("KILL {2}: {0}/{1}", + Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[2], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[2] = Last Text ID; + Global.Perk[1] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[19] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - +50% DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("+50% DAMAGE UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "+50% DAMAGE"), Right, 12, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[2] = Last Text ID; + Global.DamageDone = 50; + All Players(Team 1).DamageDealt = 100 + Global.DamageDone + All Players(Team 1).Abilities[13] * 5; + Set Damage Dealt(All Players(Team 1), All Players(Team 1).DamageDealt); + Global.challengeCount += 1; + } +} + +disabled rule("=== GAME PHASES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: ASEMBLING PHASE - MAKE CHALLENGES HUDS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Assembling Heroes == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Disable Inspector Recording; + Set Match Time(20); + End; + Create In-World Text(All Players(Team 1), Custom String(" {0}\r\nREPAIR\r\n {1}", Hero Icon String(Hero(Torbjörn)), + Ability Icon String(Hero(Bastion), Button(Secondary Fire))), Global.GatePosition + Vector(0, 1.400, 0), 1.200, Do Not Clip, + Visible To, Color(White), Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("TEAM CHALLENGES"), Left, 11, Color(White), Color(Blue), Color( + White), Visible To, Default Visibility); + "UPGRADE - GATE'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String( + "GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Custom String("REPAIR GATE {0}/{1} HP", + Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[0]), Left, 12, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 2, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - PLAYER'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +50%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[0]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 4, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - CRITICAL DAMAGE" + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("CRITICAL DAMAGE 150%"), Custom String( + "KILL WIDOW WITH HEADSHOT: {0}/{1}", Global.UpgradeCriticalDamageValue, Global.UpgradeCriticalDamageMaxValue[0]), Left, 14, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 6, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - MAX AMMO" + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("MAX AMMO 200%"), Custom String("KILL {2}: {0}/{1}", + Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[0], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Custom String("HOLD {0} - Reload to open the shop", Input Binding String(Button(Reload))), + Null, Null, Top, 1000, Color(Yellow), Color(White), Color(White), Visible To and String, Default Visibility); + } +} + +rule("GLOBAL: SETUP PHASE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Set Match Time(20); + End; + Set Objective Description(All Players(All Teams), Custom String("DEFEND GATE"), Visible To and String); + } +} + +rule("GLOBAL: GAME IN PROGRESS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + } + + actions + { + Set Match Time(3599); + Pause Match Time; + Disable Built-In Game Mode Scoring; + Disable Built-In Game Mode Announcer; + Disable Built-In Game Mode Completion; + Disable Game Mode HUD(All Players(All Teams)); + Disable Game Mode In-World UI(All Players(All Teams)); + Global.GateHealth = Global.GateMaxHealth; + Global.GateHealthChase = Global.GateHealth; + Global.GateProgressBarColorComponent = 255; + Global.GateProgressBarColorCurrent = Color(White); + Create Progress Bar HUD Text(All Players(Team 1), Global.GateHealthChase * 100 / Global.GateMaxHealth, Custom String( + "GATE {0}/{1}", Global.GateHealth, Global.GateMaxHealth), Top, 1, Global.GateProgressBarColorCurrent, Color(White), + Visible To Values and Color, Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("SURVIVED TIME: {0}:{1}", Global.TimeMin, + Global.TimeSec < 10 ? Custom String("0{0}", Global.TimeSec) : Global.TimeSec), Top, 2, Color(White), Color(White), Color( + White), Visible To and String, Default Visibility); + Start Rule(GameLogicWave0, Do Nothing); + } +} + +disabled rule("=== GAME - MAIN LOGIC ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: DEFEAT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.IsDebug == False; + Global.GateHealth <= 0; + } + + actions + { + Declare Team Victory(Team 2); + } +} + +rule("GLOBAL: TIMER - MAIN GAME LOOP") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + disabled Global.GateHealth > 0; + } + + actions + { + Wait(1, Ignore Condition); + Global.TimeSec += 1; + If(Global.TimeSec == 60); + Global.TimeSec = 0; + Global.TimeMin += 1; + Global.Time5Min = Round To Integer(Global.TimeMin / 5, Down); + Global.Time10Min = Round To Integer(Global.TimeMin / 10, Down); + Global.SpawnPositionMaxId += 1; + disabled Start Rule(GameLogicAddNextHeroInGame, Restart Rule); + Else If(Global.TimeSec == 30); + Global.SpawnPositionMaxId += 1; + End; + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GAME LOGIC - ADD NEXT HERO IN GAME") +{ + event + { + Subroutine; + GameLogicAddNextHeroInGame; + } + + actions + { + "REDUCE RESPAWN TIME FOR ZENS" + disabled Global.ZenRespawnTime -= 1.500; + disabled Global.ZenRespawnTime = Max(1, Global.ZenRespawnTime); + disabled Set Respawn Max Time(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Global.DefaultHeroBotsPool[0]), + Global.ZenRespawnTime); + "ALL HEROES WAS ADDED IN GAME" + Abort If(Global.DefaultHeroBotsPoolCurrentId == Count Of(Global.DefaultHeroBotsPool) - 1); + Global.DefaultHeroBotsPoolCurrentId += 1; + "ВРЕМЕННЫЙ КОСТЫЛЬ ЧТОБЫ ЭХО ЗАМЕНИЛА ХАМСТЕРА" + If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Hero(Echo)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Abort; + End; + "ABORT IF NEXT HERO IN ARRAY ORDER IS NULL" + Abort If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Null); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId], Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("SUBROUTINE: GAME LOGIC - SET BOT PROPERTIES") +{ + event + { + Subroutine; + GameLogicSetBotProperties; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + If(Global.TimeMin >= 10); + If(Filtered Array(Global.lastBoss, Current Array Element == Hero Of(Event Player)) == False); + If(Global.activeBoss == False); + If(Global.bossTrigger < Global.TimeMin); + Global.bossTrigger = Global.TimeMin; + Global.activeBoss = Event Player; + Event Player.isBoss = 1; + Big Message(All Players(Team 1), Custom String("BOSS SPAWNED - {0}", Hero Of(Event Player))); + End; + End; + End; + End; + "PROPERTIES BY DEFAULT" + Set Gravity(Event Player, 100); + Set Damage Dealt(Event Player, 100); + Set Respawn Max Time(Event Player, 10); + Start Scaling Player(Event Player, 1, False); + "INDIVIDUAL HERO'S PROPERTIES" + If(Hero Of(Event Player) == Hero(Zenyatta)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 30); + Set Max Health(Event Player, 5 * (100 + Global.TimeMin * 10) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 1.500, False); + Else; + If(20 + 3 * Number Of Players(Team 1) + 3 * Global.TimeMin > 75); + Set Move Speed(Event Player, 75); + Else; + Set Move Speed(Event Player, 20 + 3 * Count Of(All Players(Team 1)) + 3 * Global.TimeMin); + End; + Set Max Health(Event Player, 100 + Global.TimeMin * 10); + End; + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 20); + Set Max Health(Event Player, 5 * (70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + If(30 + Global.TimeMin + 2.500 * Global.Time5Min > 50); + Set Move Speed(Event Player, 50); + Else; + Set Move Speed(Event Player, 30 + Global.TimeMin + 2.500 * Global.Time5Min); + End; + Set Ultimate Charge(Event Player, 0); + Set Max Health(Event Player, 70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + If(Event Player.isBoss == 1); + Set Damage Dealt(Event Player, 2 * (85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min)); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 5 * (100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Event Player.BotCounter = 0; + Set Damage Dealt(Event Player, 85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Bastion)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 50); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Start Scaling Player(Event Player, 3, False); + Set Max Health(Event Player, 5 * (155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Else; + Set Move Speed(Event Player, 80); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Start Scaling Player(Event Player, 2, False); + Set Max Health(Event Player, 155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Orisa)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 5 * (220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Set Move Speed(Event Player, 30 + 5 * Global.Time5Min); + Else; + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min); + Set Move Speed(Event Player, 90 + 5 * Global.Time5Min); + End; + Else If(Hero Of(Event Player) == Hero(Echo)); + If(Event Player.isBoss == 1); + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 70 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 5 * (90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 130 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.500, False); + Set Move Speed(Event Player, 70); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 5 * (55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Else; + disabled Start Scaling Player(Event Player, 0.850, False); + Set Move Speed(Event Player, 110); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin); + End; + End; + Wait(0.250, Ignore Condition); + "FILL HEALTH" + Heal(Event Player, Null, 100000); + } +} + +disabled rule("=== GATE ===") +{ + event + { + Ongoing - Global; + } +} + +rule("Subroutine: GATE REPAIR") +{ + event + { + Subroutine; + GateRepair; + } + + actions + { + Small Message(Event Player, Custom String("REPAIR +2% ULTIMATE")); + "UPGRADE - GATE'S MAX HEALTH" + If(Global.UpgradeGateMaxHealthValue < Global.UpgradeGateMaxHealthMaxValue[2]); + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.UpgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.UpgradeGateMaxHealthValue += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + End; + End; + "HEAL GATE" + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.GateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.GateHealth += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + "CHARGE ULTIMATE" + Else; + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + End; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + } +} + +rule("TORB: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Has Spawned(Event Player) == True; + Weapon(Event Player) == 2; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(Is Using Ability 2(Event Player) == True ? 0.350 : 0.700, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Brig: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 5; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Rein: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + Is Game In Progress == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Call Subroutine(GateRepair); + Wait(0.850, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GATE PROGRESS BAR COLOR") +{ + event + { + Subroutine; + GateProgressBarColor; + } + + actions + { + Stop Chasing Global Variable(GateHealthChase); + Chase Global Variable Over Time(GateHealthChase, Global.GateHealth, 0.100, Destination and Duration); + "GATE WAS DAMAGED" + If(Global.GateHealth < Global.GateHealthEvent); + For Global Variable(LoopIterator1, 0, 3, 1); + Global.GateProgressBarColorCurrent = Color(Red); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(White); + Wait(0.030, Ignore Condition); + End; + "GATE WAS REPAIRED" + Else; + Global.GateProgressBarColorCurrent = Color(Green); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(Yellow); + Wait(0.030, Ignore Condition); + End; + Global.GateHealthEvent = Global.GateHealth; + Global.GateProgressBarColorComponent = Global.GateHealth * 255 / Global.GateMaxHealth; + Global.GateProgressBarColorCurrent = Custom Color(255, Global.GateProgressBarColorComponent, Global.GateProgressBarColorComponent, + 255); + } +} + +disabled rule("=== COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("ALL: INIT") +{ + event + { + Player Joined Match; + All; + All; + } + + actions + { + "ALL (COMMON) INIT" + Event Player.IsDead = True; + Disable Kill Feed(Event Player); + Disable Game Mode In-World UI(Event Player); + Disable Death Spectate Target HUD(Event Player); + "BOT INIT" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotInit); + "PLAYER INIT" + Else; + Call Subroutine(PlayerInit); + End; + } +} + +rule("SUBROUTINE: BOT - INIT") +{ + event + { + Subroutine; + BotInit; + } + + actions + { + "INIT VARS" + Event Player.HasBadStatus = False; + Event Player.IsRespawning = False; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEventPosition = Vector(9999, 999, 9999); + "DISABLE ALL FOR BOT" + Disable Hero HUD(Event Player); + Disable Messages(Event Player); + Disable Text Chat(Event Player); + Disable Scoreboard(Event Player); + Disable Game Mode HUD(Event Player); + Disable Death Spectate All Players(Event Player); + Disable Voice Chat(Event Player, True, True, True); + "INIT AI NAVIGATION VARS" + Call Subroutine(BotResetPathFinding); + } +} + +rule("SUBROUTINE: PLAYER - INIT") +{ + event + { + Subroutine; + PlayerInit; + } + + actions + { + "STORY HEROES" + If(Global.IsStoryHeroes); + Reset Player Hero Availability(Event Player); + Set Player Allowed Heroes(Event Player, Array(Hero(Ana), Hero(Brigitte), Hero(Mercy), Hero(Lúcio), Hero(Moira), Hero(Baptiste), + Hero(Ashe), Hero(D.Va), Hero(Genji), Hero(Hanzo), Hero(Widowmaker), Hero(Cassidy), Hero(Reinhardt), Hero(Soldier: 76), Hero( + Torbjörn), Hero(Tracer), Hero(Winston), Hero(Pharah))); + End; + "TEAM CHALLENGE - PLAYER'S MAX HEALTH" + If(Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0]); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + End; + If(Is Game In Progress); + Disable Game Mode HUD(Event Player); + End; + } +} + +rule("ALL: RESPAWN") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + (Hero Of(Event Player) != Event Player.CurrentHero || Event Player.IsDead == True) == True; + } + + actions + { + Event Player.IsDead = False; + "BOT RESPAWN" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotRespawn); + If(Global.IsDebugAINavigation); + Create Beam Effect(All Players(All Teams), Good Beam, Eye Position(Event Player), Event Player.BotNextNodePosition, Color(Green), + Visible To Position and Radius); + End; + "PLAYER RESPAWN" + Else; + Call Subroutine(PlayerRespawn); + End; + "MUST BE AFTER ALL RESPAWN SUBROUTINES!" + Event Player.CurrentHero = Hero Of(Event Player); + } +} + +rule("SUBROUTINE: BOT - RESPAWN") +{ + event + { + Subroutine; + BotRespawn; + } + + actions + { + "RESET COMMON PROPERTIES" + Event Player.IsRespawning = True; + Enable Nameplates(Event Player, All Players(Team 1)); + Call Subroutine(BotResetPathFinding); + disabled If(Hero Of(Event Player) != Event Player.CurrentHero); + Call Subroutine(GameLogicSetBotProperties); + disabled End; + "INDIVIDUAL HERO'S RESPAWN SCRIPTS" + If(Hero Of(Event Player) == Hero(Bastion)); + Call Subroutine(BotBastionRespawn); + Else If(Hero Of(Event Player) == Hero(Zenyatta)); + Call Subroutine(BotZenyattaRespawn); + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + Call Subroutine(BotWidowRespawn); + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Call Subroutine(BotBallRespawn); + Else If(Hero Of(Event Player) == Hero(Orisa)); + Call Subroutine(BotOrisaRespawn); + Else If(Hero Of(Event Player) == Hero(Echo)); + Call Subroutine(BotEchoRespawn); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Call Subroutine(BotReinRespawn); + End; + Event Player.IsRespawning = False; + } +} + +rule("SUBROUTINE: PLAYER - RESPAWN") +{ + event + { + Subroutine; + PlayerRespawn; + } + + actions + { + "TEAM CHALLENGE - MAX AMMO" + If(Hero Of(Event Player) != Event Player.CurrentHero && Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]); + Set Max Ammo(Event Player, 0, Ammo(Event Player, 0) * 2); + Set Max Ammo(Event Player, 1, Ammo(Event Player, 1) * 2); + Set Ammo(Event Player, 0, Max Ammo(Event Player, 0)); + Set Ammo(Event Player, 1, Max Ammo(Event Player, 1)); + End; + "MUST BE AFTER TEAM CHALLENGE MAX AMMO!" + disabled Event Player.CurrentHero = Hero Of(Event Player); + "PLAYER RESPAWN" + Set Status(Event Player, Null, Phased Out, 3); + Set Facing(Event Player, Vector(-1, 0, 0), To World); + Teleport(Event Player, Global.PlayerSpawnPositions[Slot Of(Event Player) == Count Of(Global.PlayerSpawnPositions) ? Random Integer( + 0, Count Of(Global.PlayerSpawnPositions) - 1) : Slot Of(Event Player)]); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + } +} + +rule("PLAYER: DEATH") +{ + event + { + Player Died; + Team 1; + All; + } + + actions + { + If(Hero Of(Event Player) == Hero(Roadhog)); + Event Player.Abilities[8] -= 1; + Wait(Global.Perk[2] ? 5 : 10, Ignore Condition); + Event Player.Abilities[8] += 1; + End; + disabled If(Event Player.lastSecondWind > 0); + disabled Event Player.lastSecondWind = 0; + disabled End; + Event Player.IsDead = True; + } +} + +rule("BOT: DEATH") +{ + event + { + Player Died; + Team 2; + All; + } + + actions + { + If(Event Player.isBoss == 1); + If(Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]); + If(Global.UpgradeBossHealthValue < Global.UpgradeCriticalDamageMaxValue[2]); + Global.UpgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + End; + End; + Event Player.isBoss = 0; + Global.activeBoss = Null; + Big Message(All Players(Team 1), Custom String("BOSS DIED - {0}", Hero Of(Event Player))); + End; + Event Player.IsDead = True; + Event Player.HasBadStatus = False; + Event Player.BotDoesUniqueBehaviour = False; + Disable Nameplates(Event Player, All Players(Team 1)); + disabled Stop Holding Button(Event Player, Button(Ability 1)); + disabled Stop Holding Button(Event Player, Button(Primary Fire)); + disabled Stop Holding Button(Event Player, Button(Secondary Fire)); + "BOT HAS 1 EFFECT IN VAR (NOT ARRAY)" + Skip If(!Entity Exists(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects); + "BOT HAS MORE THEN 1 EFFECT IN VAR (ARRAY)" + Skip If(Count Of(Event Player.BotEffects) == 0, 3); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects[Event Player.BotLoopIterator1]); + End; + } +} + +disabled rule("=== BOT COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BAD STATUS") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + Event Player.HasBadStatus = True; + "PROCESS BAD STATUS" + If(Hero Of(Event Player) == Hero(Widowmaker)); + Start Rule(BotWidowBadStatus, Do Nothing); + End; + Wait Until(!Has Status(Event Player, Knocked Down) && !Has Status(Event Player, Asleep) && !Has Status(Event Player, Frozen) + && !Has Status(Event Player, Stunned), 15); + Event Player.HasBadStatus = False; + } +} + +rule("SUBROUTINE: BOT - LANDING FROM SKY") +{ + event + { + Subroutine; + BotLandingFromSky; + } + + actions + { + Stop Throttle In Direction(Event Player); + "SET RESPAWN POSITION" + Event Player.BotEventPosition = Random Value In Array(Global.BigBossSpawnPositions); + "CREATE EFFECTS" + disabled Create Effect(All Players(All Teams), Light Shaft, Color(Red), Event Player.BotEventPosition, 3, Visible To); + disabled Event Player.BotEffects = Last Created Entity; + "RESPAWN IN LIGHT SHAFT EFFECT" + Teleport(Event Player, Event Player.BotEventPosition + Vector(0, 25, 0)); + Wait(0.020, Ignore Condition); + "SLOW LANDING" + Set Gravity(Event Player, 50); + While(Is In Air(Event Player) == True); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Position Of(Event Player) + Vector(0, -2.700, 0), 2); + Wait(0.250, Ignore Condition); + End; + Set Gravity(Event Player, 100); + disabled Destroy Effect(Event Player.BotEffects); + "LANDING EFFECTS" + Play Effect(All Players(All Teams), Wrecking Ball Piledriver Impact Effect, Custom Color(105, 87, 46, 255), Position Of( + Event Player), 8); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Sound, Color(White), Position Of(Event Player), 150); + } +} + +rule("SUBROUTINE: BOT - APPEAR FROM UNDERGROUND") +{ + event + { + Subroutine; + BotApearFromUnderground; + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1); + Wait(0.200, Ignore Condition); + Set Gravity(Event Player, 20); + Disable Movement Collision With Environment(Event Player, True); + Teleport(Event Player, Global.ZenSpawnPositions[Random Integer(Min(Global.TimeMin, Count Of(Global.ZenSpawnPositions) - 10), Min( + Global.SpawnPositionMaxId, Count Of(Global.ZenSpawnPositions) - 4))] + Vector(0, -1.500, 0)); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Sigma Accretion Impact Effect, Custom Color(220, 175, 100, 255), Eye Position(Event Player), + 3); + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(Gray), Eye Position(Event Player), 50); + Apply Impulse(Event Player, Up, 3.500, To World, Cancel Contrary Motion); + Wait(0.400, Ignore Condition); + Clear Status(Event Player, Knocked Down); + Set Gravity(Event Player, 100); + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("=== PLAYER MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("PLAYER: DARKNESS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + !Entity Exists(Event Player.BotEffects) == True; + } + + actions + { + Disable Nameplates(Event Player, All Players(All Teams)); + Start Forcing Player Outlines(Event Player, All Players(All Teams), False, Color(White), Default); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 14), 25, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(-5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + } +} + +rule("PLAYER: HEALTH REGEN") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + actions + { + Stop Heal Over Time(Event Player.HealOverTimeId); + Event Player.EventHealth = Health(Event Player); + Wait(4, Ignore Condition); + "TOOK DAMAGE, RESET REGENERATION TIMER" + Loop If(Is Alive(Event Player) && Event Player.EventHealth > Health(Event Player)); + Start Heal Over Time(Event Player, Null, 3, Max Health(Event Player) / 3); + Event Player.HealOverTimeId = Last Heal Over Time ID; + } +} + +disabled rule("=== NERFS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("REINHARDT: ANTI-CHARGE FOR BASTION & ORISA") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Using Ability 1(Event Player) == True; + Hero Of(Ray Cast Hit Player(Eye Position(Event Player) + Vector(0, 2, 0), Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 2, All Living Players(Team 2), Event Player, True)) == (Hero(Bastion) == True || Hero( + Orisa) == True); + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1.500); + } +} + +rule("HOG: ANTI-HOOK FOR BASTION & ORISA") +{ + event + { + Player Dealt Damage; + Team 1; + Roadhog; + } + + conditions + { + Event Ability == Button(Ability 1); + (Hero Of(Victim) == Hero(Bastion) || Hero Of(Victim) == Hero(Orisa)) == True; + } + + actions + { + Set Status(Event Player, Null, Stunned, 0.005); + } +} + +disabled rule("=== ZENYATTA ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ZEN - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Zenyatta; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + } + + actions + { + Set Ammo(Event Player, 0, 0); + Communicate(Event Player, Hello); + disabled Call Subroutine(BotResetPathFinding); + Wait(1.500, Ignore Condition); + Abort If(Is Dead(Event Player) == True); + Kill(Event Player, Null); + } +} + +rule("BOT: ZEN - DEATH") +{ + event + { + Player Died; + Team 2; + Zenyatta; + } + + actions + { + "EFFECT" + Play Effect(All Players(All Teams), Junkrat Frag Launcher Explosion Effect, Color(Red), Eye Position(Event Player), 2.500); + Play Effect(All Players(All Teams), Ashe Dynamite Explosion Sound, Color(Red), Eye Position(Event Player), 70); + "DAMAGE AND APPLY IMPULSE TO PLAYERS" + Event Player.BotPlayersInRadius = Players Within Radius(Position Of(Event Player), 2.500, All Teams, Surfaces And Enemy Barriers); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotPlayersInRadius), 1); + Apply Impulse(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Direction Towards(Position Of(Event Player), + Eye Position(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1])), 5, To World, Incorporate Contrary Motion); + If(Team Of(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1]) == Team 1); + Damage(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Event Player, 50); + End; + End; + "DAMAGE GATE" + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 125; + Else; + Global.GateHealth -= 25; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Respawn(Event Player); + Abort; + End; + "KILLED BY PLAYER" + Teleport(Event Player, Vector(0, -999, 0)); + Wait(2, Ignore Condition); + Respawn(Event Player); + Wait(2, Ignore Condition); + } +} + +rule("SUBROUTINE: ZEN - RESPAWN") +{ + event + { + Subroutine; + BotZenyattaRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WRECKING BALL ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BALL - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + disabled Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Set Ammo(Event Player, 0, 0); + Wait(1, Ignore Condition); + Set Ultimate Charge(Event Player, 100); + Start Holding Button(Event Player, Button(Ultimate)); + Wait Until(Is Using Ultimate(Event Player), 0.600); + Abort If(Is Dead(Event Player)); + Kill(Event Player, Null); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Effect, Color(Orange), Eye Position(Event Player), 6); + Play Effect(All Players(All Teams), DVa Self Destruct Explosion Sound, Color(White), Eye Position(Event Player), 250); + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 300; + Else; + Global.GateHealth -= 150; + End; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Damage(Players Within Radius(Eye Position(Event Player), 7, Team 1, Surfaces And All Barriers), Event Player, 200); + } +} + +rule("BOT: BALL - ALTERNATIVE FORM") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is In Alternate Form(Event Player) == False; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is In Alternate Form(Event Player), 10); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: BALL - DEATH") +{ + event + { + Player Died; + Team 2; + Wrecking Ball; + } + + actions + { + Stop Holding Button(Event Player, Button(Ability 1)); + Stop Holding Button(Event Player, Button(Ultimate)); + } +} + +rule("SUBROUTINE: BALL - RESPAWN") +{ + event + { + Subroutine; + BotBallRespawn; + } + + actions + { + "RESPAWN IN AIR" + Teleport(Event Player, Random Value In Array(Global.BallSpawnPositions) + Vector(0, 20, 0)); + Stop Holding Button(Event Player, Button(Ultimate)); + Wait(0.250, Ignore Condition); + "LANDING" + Start Holding Button(Event Player, Button(Crouch)); + Wait Until(Is On Ground(Event Player), 9999); + Stop Holding Button(Event Player, Button(Crouch)); + "LANDING IMPACT EFFECT" + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(White), Event Player, 150); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Effect, Color(Gray), Position Of(Event Player), 10); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Eye Position(Event Player), 1.500, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + "PATH FINDING TO GATE" + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +disabled rule("=== ECHO ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ECHO - FLY ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is Using Ability 1(Event Player) == False; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), 0); + Press Button(Event Player, Button(Ability 1)); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - BEAM ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Using Ability 1(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == True; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - BAD STATUS - RESET BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.HasBadStatus == True; + disabled (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + Wait Until(Event Player.HasBadStatus, 7); + } +} + +rule("BOT: ECHO - CAN'T SEE PORTAL - APPLY IMPULSE") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == True; + Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Wait(0.300, Abort When False); + Apply Impulse(Event Player, Vector(Random Integer(-1, 1), 1, Random Integer(-1, 1)), 20, To World, Incorporate Contrary Motion); + Wait(1, Ignore Condition); + If(!Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + Event Player.BotTargetPosition = Global.BotEchoRespawnPosition; + Start Rule(BotStartPathFinding, Restart Rule); + Else; + Call Subroutine(BotResetPathFinding); + End; + Loop If Condition Is True; + } +} + +disabled rule("BOT: ECHO - MAIN LOGIC - BACKUP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(!Event Player.BotIsPathFinding); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Is In Line of Sight(Eye Position(Event Player), + Eye Position(Current Array Element), Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), + Position Of(Current Array Element)))[0]; + End; + "NO PLAYERS IN VIEW RANGE" + disabled If(Event Player.BotSeePlayer == Null); + disabled Stop Throttle In Direction(Event Player); + disabled End; + "FLY TO PLAYER" + If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + > 4 && Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + "ACTIVATE FOCUS BEAM" + Else If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + < 4 && Event Player.BotDoesUniqueBehaviour == False && Event Player.HasBadStatus == False); + Event Player.BotDoesUniqueBehaviour = True; + Set Status(Event Player.BotSeePlayer, Event Player, Stunned, 1); + Set Status(Event Player.BotSeePlayer, Event Player, Hacked, 99999); + Attach Players(Event Player.BotSeePlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + "TELEPORT PLAYER TO AWAY" + Else If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotSeePlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotSeePlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotSeePlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + "BEGIN TO FLY TO THE PORTAL" + Else If(Event Player.BotDoesUniqueBehaviour == True); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + End; + "TELEPORT PLAYER SO FAR" + If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotEchoCapturedPlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotEchoCapturedPlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + End; + "BEGIN TO FLY TO THE PORTAL WITH A PLAYER" + If(Event Player.BotDoesUniqueBehaviour); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotEchoCapturedPlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - DEFEND PORTAL") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + } + + actions + { + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPlayer); + } +} + +rule("BOT: ECHO - PATH FINDING TO PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Call Subroutine(BotStartPathFinding); + } +} + +rule("BOT: ECHO - ATTACH PLAYER BY BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotEchoCapturedPlayer == Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 3; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Event Player.BotEchoCapturedPlayer = Event Player.BotSeePlayer; + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Stunned, 0.700); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Hacked, 10); + Attach Players(Event Player.BotEchoCapturedPlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - PLAYER DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Dead(Event Player.BotEchoCapturedPlayer) != Null; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - DEATH") +{ + event + { + Player Died; + Team 2; + Echo; + } + + actions + { + Call Subroutine(BotEchoDetachPlayer); + Stop Holding Button(Event Player, Button(Jump)); + Wait(5, Ignore Condition); + Teleport(Event Player, Vector(0, 999, 0)); + Start Forcing Player To Be Hero(Event Player, Hero(Orisa)); + } +} + +rule("SUBROUTINE: ECHO - RESPAWN") +{ + event + { + Subroutine; + BotEchoRespawn; + } + + actions + { + Event Player.BotCounter = 0; + Event Player.BotEffects = Empty Array; + Create Effect(All Players(All Teams), Good Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Energy Sound, Color(White), Global.BotEchoRespawnPosition, 200, Visible To); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Chase Player Variable Over Time(Event Player, BotCounter, 3, 0.800, Destination and Duration); + Play Effect(All Players(All Teams), Sombra EMP Explosion Effect, Color(Sky Blue), Global.BotEchoRespawnPosition, 12); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Null, Global.BotEchoRespawnPosition, 100); + Wait(3, Ignore Condition); + Teleport(Event Player, Global.BotEchoRespawnPosition); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Global.BotEchoRespawnPosition, 2.500); + Play Effect(All Players(All Teams), Debuff Impact Sound, Null, Global.BotEchoRespawnPosition, 100); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PLAYER") +{ + event + { + Subroutine; + BotEchoFlyToPlayer; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Stop Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PORTAL") +{ + event + { + Subroutine; + BotEchoFlyToPortal; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - DETACH PLAYER") +{ + event + { + Subroutine; + BotEchoDetachPlayer; + } + + actions + { + Detach Players(Event Player.BotEchoCapturedPlayer); + Clear Status(Event Player.BotEchoCapturedPlayer, Hacked); + "IF PLAYER INSIDE THE WALL" + If(Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotEchoCapturedPlayer), Barriers Do Not Block LOS)); + Teleport(Event Player.BotEchoCapturedPlayer, Position Of(Event Player)); + End; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEchoCapturedPlayer = Null; + } +} + +disabled rule("=== REINHARDT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: REIN - SET PLAYER AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + disabled Event Player.BotIsPathFinding == False; + "BOT IS FAR FROM GATES" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Global.GatePosition), 0, Z Component Of(Global.GatePosition))) > 20; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET CLOSEST PLAYER TO BOT AS TARGET AND FOLLOW HIM" + Event Player.BotTargetPlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - SET GATE AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "BOT DOESN'T FOLLOW PLAYER" + Event Player.BotTargetPlayer == -1; + "CAN'T SEE ANY PLAYER" + disabled Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), !Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET GATE AS TARGET" + Event Player.BotTargetPosition = Global.GatePosition; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - TARGET DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer != -1; + Is Dead(Event Player.BotTargetPlayer) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + } +} + +rule("BOT: REIN - ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) < 4; + "CAN ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) < 4; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + "TARGET IS PLAYER" + Abort If(Event Player.BotTargetPlayer != -1); + If(Event Player.isBoss == 1); + "TARGET IS GATE" + Global.GateHealth -= 25; + Else; + Global.GateHealth -= 5; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: REIN - STOP ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) > 4; + "CAN'T ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) > 4; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + } +} + +rule("BOT: REIN - USE SHIELD") +{ + event + { + Player Took Damage; + Team 2; + Reinhardt; + } + + conditions + { + Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) > 3; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Attacker)), 200, To World, + Direction and Turn Rate); + Start Holding Button(Event Player, Button(Secondary Fire)); + Wait Until(Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) < 3, 3); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("BOT: REIN - CHARGE IN GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer == -1; + Is Using Ability 1(Event Player) == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == True; + Is In View Angle(Event Player, Global.GatePosition, 7.500) == True; + } + + actions + { + disabled Wait(0.800, Abort When False); + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is Using Ability 1(Event Player), 1); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: REIN - DEATH") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("SUBROUTINE: REIN - RESPAWN") +{ + event + { + Subroutine; + BotReinRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WIDOW ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: WIDOW - SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer == Null; + Event Player.HasBadStatus == False; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Event Player.BotWidowShotTime = Total Time Elapsed + (Global.TimeMin >= 9 ? Random Real(2, 5) : Random Real(5, 10)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 9999, To World, + Direction and Turn Rate); + } +} + +rule("BOT: WIDOW - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer != Null; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowShotTime; + } + + actions + { + Press Button(Event Player, Button(Primary Fire)); + Stop Facing(Event Player); + Event Player.BotSeePlayer = Null; + } +} + +rule("BOT: WIDOW - Aim Sound") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Alive(Event Player) == True; + Is In Line of Sight(Eye Position(Players On Hero(Hero(Widowmaker), Team 2)), Eye Position(Event Player), Barriers Do Not Block LOS) + == True; + Is Alive(Players On Hero(Hero(Widowmaker), Team 2)) == True; + Players On Hero(Hero(Widowmaker), Team 2).BotSeePlayer == True; + } + + actions + { + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 100); + Wait(1, Abort When False); + Loop If Condition Is True; + } +} + +rule("BOT: WIDOW - TELEPORT TO NEW POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowTeleportTime; + } + + actions + { + Event Player.BotWidowTeleportTime = Total Time Elapsed + 28; + Event Player.BotWidowShotTime = Total Time Elapsed + Random Real(1, 1.600); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Event Player, 1); + Wait(0.016, Ignore Condition); + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + } +} + +rule("BOT: WIDOW - DEATH") +{ + event + { + Player Died; + Team 2; + Widowmaker; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + Wait(0.250, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - RESPAWN") +{ + event + { + Subroutine; + BotWidowRespawn; + } + + actions + { + "RESPAWN ON RANDOM SNIPER POSITION" + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Wait(0.700, Ignore Condition); + Start Holding Button(Event Player, Button(Secondary Fire)); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait Until(Is Dead(Event Player), 99999); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - BAD STATUS") +{ + event + { + Subroutine; + BotWidowBadStatus; + } + + actions + { + Stop Facing(Event Player); + Destroy Effect(Event Player.BotEffects); + Wait Until(!Event Player.HasBadStatus, 15); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + } +} + +disabled rule("=== BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("BOT: BASTION - FLAME GUN") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 50) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 8; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Stop Holding Button(Event Player, Button(Primary Fire)); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Update Every Frame(Eye Position(Event Player) + World Vector Of( + Vector(-1, -1.200, 1.800), Event Player, Rotation)), 1, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Start Rule(BotBastionFlameGunDamage, Do Nothing); + Wait(1.100, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(4, Ignore Condition); + Loop If Condition Is True; + } +} + +disabled rule("BOT: BASTION - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + disabled Event Player.BotSeePlayer == Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - CAN'T SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == False; + } + + actions + { + Event Player.BotSeePlayer = Null; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - MOVE TO BASTION'S TARGET (POSITION)") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotTargetPosition = Random Value In Array(Filtered Array(Global.BastionTargetPositions, Distance Between(Position Of( + Event Player), Current Array Element) > 3.500)); + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("BOT: BASTION - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + "SEE THE PLAYER" + If(Event Player.BotSeePlayer != Null); + Stop Holding Button(Event Player, Button(Secondary Fire)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer) - Vector(0, 0.500, + 0)), 100, To World, Direction and Turn Rate); + "SELF REPAIRING" + Else If(!Is Firing Secondary(Event Player) && Health(Event Player) < Max Health(Event Player)); + Start Holding Button(Event Player, Button(Secondary Fire)); + End; + "START FOLLOW PATH" + disabled If(!Event Player.BotIsPathFinding && !Event Player.BotDoesUniqueBehaviour); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled Wait(0.050, Ignore Condition); + disabled Event Player.BotTargetPosition = Random Value In Array(Global.BastionTargetPositions); + disabled Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Event Player.BotTargetPosition + Vector(0, 2, 0)), 100, + To World, Direction and Turn Rate); + disabled Start Rule(BotStartPathFinding, Do Nothing); + "REACHED PATH TARGET" + disabled Else If(Distance Between(Position Of(Event Player), Event Player.BotTargetPosition) <= 3); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled End; + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - ARTILLERY") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 30) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) > 18; + Distance Between(Eye Position(Event Player), Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Up * 99, Null, Event Player, False)) >= 35; + } + + actions + { + "TRYING TO CAPTURE TARGET" + Wait(0.800, Abort When False); + "CAPTURE TARGET" + Event Player.BotDoesUniqueBehaviour = True; + Stop Throttle In Direction(Event Player); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Update Every Frame(Eye Position(Event Player)), + Update Every Frame(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 1000, All Living Players(Team 1), Event Player, True)), Color(Sky Blue), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait(1.400, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Event Player.BotEventPosition = Position Of(Event Player.BotSeePlayer); + "SHOOT FROM ARTILLERY" + Event Player.BotBastionArtilleryDidShotsCount = 0; + For Player Variable(Event Player, BotLoopIterator1, 0, 4, 1); + Event Player.BotBastionArtilleryDidShotsCount += 1; + Play Effect(All Players(All Teams), Wrecking Ball Minefield Explosion Sound, Color(White), Eye Position(Event Player), 250); + Play Effect(All Players(All Teams), Pharah Barrage Explosion Effect, Color(Orange), Eye Position(Event Player) + World Vector Of( + Vector(0, 1.400, -0.700), Event Player, Rotation), 2); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) + World Vector Of(Vector(0, 1.400, + -0.700), Event Player, Rotation), Eye Position(Event Player) + World Vector Of(Vector(Random Real(-1, 1), Random Integer(40, + 80), Random Real(0.500, 1.500)), Event Player, Rotation), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + If(Is Dead(Event Player)); + Break; + End; + End; + disabled Call Subroutine(BotResetPathFinding); + disabled Start Rule(BotStartPathFinding, Do Nothing); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Wait(1.500, Ignore Condition); + Start Rule(BotBastionArtilleryDamage, Do Nothing); + Wait(4, Ignore Condition); + } +} + +rule("BOT: BASTION - PRIMARY FIRE") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 40) == True; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Stop Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Bastion; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + For Player Variable(Event Player, BotLoopIterator1, 0, 3, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Effect, Color(White), Event Player, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player, 100); + Wait(0.250, Ignore Condition); + End; + } +} + +rule("SUBROUTINE: BASTION - RESPAWN") +{ + event + { + Subroutine; + BotBastionRespawn; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + Call Subroutine(BotLandingFromSky); + Set Ammo(Event Player, 0, 0); + Wait Until(!Is Reloading(Event Player), 99999); + Event Player.BotTargetPosition = Objective Position(2); + } +} + +rule("SUBROUTINE: BASTION - ARTILLERY DAMAGE") +{ + event + { + Subroutine; + BotBastionArtilleryDamage; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = False; + "EXPLOSIONS OF ARTILLERY" + For Player Variable(Event Player, BotLoopIterator2, 0, Event Player.BotBastionArtilleryDidShotsCount, 1); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotEventPosition + Vector(0, 50, 0), + Event Player.BotEventPosition + Vector(Random Integer(-4, 4), -15, Random Integer(-4, 4)), Null, Event Player, True); + Damage(Players Within Radius(Event Player.BotEventPosition, 8, Team 1, Surfaces And Enemy Barriers), Event Player, 50); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Pharah Rocket Launcher Explosion Effect, Color(Orange), Event Player.BotEventPosition, 5); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Event Player.BotEventPosition, + Event Player.BotEventPosition + Vector(0, 60, 0), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + End; + } +} + +disabled rule("SUBROUTINE: BASTION - FLAME GUN DAMAGE") +{ + event + { + Subroutine; + BotBastionFlameGunDamage; + } + + actions + { + Event Player.BotRayCastHitPosition = Eye Position(Event Player) + World Vector Of(Vector(-1, -1.200, 1.800), Event Player, + Rotation); + "FIRE PARTICLES OF FLAME GUN" + For Player Variable(Event Player, BotLoopIterator1, 1, 13, 3); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotRayCastHitPosition, + Event Player.BotRayCastHitPosition + Facing Direction Of(Event Player) * Event Player.BotLoopIterator1, Null, Event Player, + True); + Damage(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Surfaces And Enemy Barriers), Event Player, 20); + Set Status(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Off), Event Player, Burning, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.BotEventPosition, 2.500); + Wait(0.200, Ignore Condition); + End; + Event Player.BotDoesUniqueBehaviour = False; + } +} + +disabled rule("=== ORISA + BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ORISA-BASTION - REACHED TARGET POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotIsPathFinding == True; + Distance Between(Position Of(Event Player), Global.BotOrisaTargetPosition) < 1.500; + } + + actions + { + Call Subroutine(BotResetPathFinding); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Vector(X Component Of(Global.GatePosition), -999, + Z Component Of(Global.GatePosition))), 80, To World, Direction and Turn Rate); + Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + disabled Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element) && Is In Line of Sight(Eye Position(Event Player), Position Of(Current Array Element), + Barriers Do Not Block LOS)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + Press Button(Event Player, Button(Ability 1)); + Wait Until(Y Component Of(Facing Direction Of(Event Player)) < -0.300, 99999); + Press Button(Event Player, Button(Ability 2)); + Wait(0.800, Ignore Condition); + Global.BotOrisaChild.BotDoesUniqueBehaviour = False; + Disallow Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ORISA-BASTION - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + While(Is Alive(Event Player)); + disabled Create Effect(All Players(All Teams), Bad Aura, Color(Purple), Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3.200, 1, Visible To Position and Radius); + disabled Event Player.BotEffects = Last Created Entity; + Wait(1.500, Ignore Condition); + disabled Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Press Button(Event Player, Button(Primary Fire)); + Press Button(Event Player, Button(Reload)); + Event Player.BotRayCastHitPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Facing Direction Of(Event Player) * 999, All Players(Team 1), All Players(Team 2), True); + "ANTI-SHIELD BUG" + Event Player.BotRayCastHitPosition = Event Player.BotRayCastHitPosition + Direction Towards(Event Player.BotRayCastHitPosition, + Eye Position(Event Player)) * 0.200; + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3, Event Player.BotRayCastHitPosition, Color(Purple), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Damage(Players Within Radius(Event Player.BotRayCastHitPosition, 4, Team 1, Surfaces And All Barriers), Event Player, 0.040); + Play Effect(All Players(All Teams), Pharah Concussive Blast Effect, Color(Purple), Event Player.BotRayCastHitPosition, 4); + Play Effect(All Players(All Teams), Pharah Concussive Blast Sound, Color(Purple), Event Player.BotRayCastHitPosition, 250); + Play Effect(All Players(All Teams), Bad Explosion, Color(Purple), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 3.300, 2); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Color(Purple), Eye Position(Event Player), 170); + If(Distance Between(Event Player.BotRayCastHitPosition, Global.GatePosition) < 4 && Is In Line of Sight( + Event Player.BotRayCastHitPosition, Global.GatePosition, Enemy Barriers Block LOS)); + Global.GateHealth -= 80; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Wait(0.150, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.060, Ignore Condition); + Wait Until(!Is Reloading(Event Player), 2.500); + End; + } +} + +rule("BOT: ORISA-BASTION - CAN'T SEE THE TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: ORISA-BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Orisa; + } + + actions + { + Allow Button(Event Player, Button(Ability 2)); + Kill(Global.BotOrisaChild, Null); + Detach Players(Global.BotOrisaChild); + Clear Status(Global.BotOrisaChild, Phased Out); + Set Damage Dealt(Global.BotOrisaChild, 100); + Global.BotOrisaChild.BotIsOrisaChild = False; + Global.BotOrisaChild = Null; + Global.BotOrisaParent = Null; + Start Forcing Player To Be Hero(Event Player, Hero(Widowmaker)); + } +} + +rule("SUBROUTINE: ORISA - RESPAWN") +{ + event + { + Subroutine; + BotOrisaRespawn; + } + + actions + { + Global.BotOrisaParent = Event Player; + "WAITING FOR ANY BASTION TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero(Bastion)), + 99999); + "SETUP BASTION AS CHILD" + Global.BotOrisaChild = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Bastion))[0]; + Global.BotOrisaChild.BotIsOrisaChild = True; + Global.BotOrisaChild.BotDoesUniqueBehaviour = True; + Wait(2, Ignore Condition); + Respawn(Global.BotOrisaChild); + Start Scaling Player(Global.BotOrisaChild, 1.800, False); + Set Damage Dealt(Global.BotOrisaChild, 2000); + Set Status(Global.BotOrisaChild, Null, Phased Out, 9999); + Disable Nameplates(Global.BotOrisaChild, All Players(All Teams)); + Set Facing(Global.BotOrisaChild, Vector(X Component Of(Facing Direction Of(Event Player)), 9999, Z Component Of( + Facing Direction Of(Event Player))), To World); + Start Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Wait Until(Is In Alternate Form(Global.BotOrisaChild), 5); + Stop Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Teleport(Global.BotOrisaChild, Position Of(Event Player)); + Attach Players(Global.BotOrisaChild, Global.BotOrisaParent, Vector(0, 1.800, 0.230)); + disabled Wait(1, Ignore Condition); + disabled Stop Holding Button(Global.BotOrisaChild, Button(Primary Fire)); + disabled Wait(0.250, Ignore Condition); + Call Subroutine(BotLandingFromSky); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 0 - ZENS, REINS, BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 0; + } + + actions + { + "CREATE BOTS - ZEN" + While(Count Of(All Players(Team 2)) < 15); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "BALL" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "REPLACE DEAD ZEN TO REIN" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) != 3); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 1 - WIDOW") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 1; + } + + actions + { + Global.IsNewWaveGameLogicProcessing = True; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Global.IsNewWaveGameLogicProcessing = False; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 3 - BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 3; + } + + actions + { + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 5 - REINS WAVE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 5; + } + + actions + { + "PREPARE WAVE - DESTROY WIDOW AND BALLS" + Destroy Dummy Bot(Team 2, Slot Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))[0])); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))[0]; + Kill(Global.DefaultCurrentBot, Null); + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + "BOSS WAVE" + Big Message(All Players(All Teams), Custom String("BOSS WAVE - {1} {0}", Hero Icon String(Hero(Reinhardt)), Hero(Reinhardt))); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) < 6); + Wait Until(Is True For Any(All Players(Team 2), Distance Between(Position Of(Current Array Element), Global.GatePosition) + > 15 && Hero Of(Current Array Element) == Hero(Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + disabled Wait(0.200, Ignore Condition); + disabled Set Max Health(Global.DefaultCurrentBot, 50); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) > 3); + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Reinhardt)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Reinhardt))[0]; + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(All Players(Team 2)) < 15); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Big Message(All Players(All Teams), Custom String("BOSS WAVE FINISHED!")); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 7 - BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 7; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 9 - ECHO, +1 BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 9; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Echo))) == 0); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + "FILL EMPTY SLOTS BY ZENS" + While(Count Of(All Players(Team 2)) < 14); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("Ana Nano Variable") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + } + + actions + { + Player Closest To Reticle(Event Player, Team 1).IsNanoed = 1; + } +} + +rule("IsNanoed") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.IsNanoed == True; + } + + actions + { + If(Is Dead(Event Player)); + Event Player.IsNanoed = 0; + End; + Wait(8, Ignore Condition); + Event Player.IsNanoed = 0; + } +} + +rule("money on kill") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + actions + { + If(Hero Of(Victim) == Hero(Zenyatta)); + All Players(Team 1).Money[0] += 5 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 5 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Reinhardt)); + All Players(Team 1).Money[0] += 15 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 15 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Wrecking Ball)); + All Players(Team 1).Money[0] += 20 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 20 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Widowmaker)); + All Players(Team 1).Money[0] += 25 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 25 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Bastion)); + All Players(Team 1).Money[0] += 50 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 50 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Echo)); + All Players(Team 1).Money[0] += 75 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 75 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Orisa)); + All Players(Team 1).Money[0] += 100 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 100 * (Victim.isBoss ? 3 : 1); + End; + } +} + +rule("Abilities and Hero Talents by Shingen and LemonAid") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.DamageDealt = 100; + Event Player.PlayerHealth = 100; + Event Player.Money[0] = 2400 + Global.StartMoney; + If(Custom String("{0}", Event Player) == Custom String("ShuriZma")); + Create HUD Text(Event Player, Custom String("Serverload: {0}, AVG {1}, Peak {2}", Server Load, Server Load Average, + Server Load Peak), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create HUD Text(Event Player, Custom String("Last SW: {0}, SW Active {1}", Event Player.lastSecondWind, + Event Player.secondWindActive), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + End; + } +} + +rule("Team 1 (Ability): Headhunter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[1] == True; + Event Was Critical Hit == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[1] * 40 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Ambush") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[2] == True; + Event Ability != Null; + (Y Component Of(Position Of(Event Player)) - Y Component Of(Position Of(Victim)) >= 3 || Absolute Value(Horizontal Angle Towards( + Victim, Event Player)) >= 90) == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[2] * 30 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Quick Fix") +{ + event + { + Player Earned Elimination; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[3] == True; + } + + actions + { + Heal(Event Player, Null, Event Player.Abilities[3] * 50); + Set Move Speed(Event Player, 100 + Event Player.Abilities[3] * 20); + Wait(5, Restart When True); + Set Move Speed(Event Player, 100); + } +} + +rule("Team 1 (Ability): Heavyweight") +{ + event + { + Player Dealt Knockback; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[4] == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[4] * 25 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Charged") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[5] == True; + Ultimate Charge Percent(Event Player) < Event Player.Abilities[5] * 20; + } + + actions + { + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + If(Is Duplicating(Event Player)); + Wait(0.016, Ignore Condition); + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + End; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Team 1 (Ability): Haste Primary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Primary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Primary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Primary Fire))); + } +} + +rule("Team 1 (Ability): Haste Secondary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Secondary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Secondary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Secondary Fire))); + } +} + +rule("Team 1 (Ability): Haste Ability 1") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 1)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 1))); + } +} + +rule("Team 1 (Ability): Haste Ability 2") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 2)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 2))); + } +} + +rule("Team 1 (Ability): Haste Jump") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Jump)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Jump), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Jump))); + } +} + +rule("Team 1 (Ability): Haste Crouch") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Crouch)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Crouch), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Crouch))); + } +} + +rule("Team 2 (Ability): Heavy Impact") +{ + event + { + Player Took Damage; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[7] == True; + } + + actions + { + Abort If(Random Real(-0.020, 1) > Event Damage / Max Health(Event Player)); + Set Status(Event Player, Attacker, Stunned, 1 * Attacker.Abilities[7]); + Wait(5, Ignore Condition); + } +} + +rule("Team 1 (Ability): Binding Heal") +{ + event + { + Player Dealt Healing; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[10] == True; + Healee != Event Player; + } + + actions + { + Set Player Health(Event Player, Health(Event Player) + Event Player.Abilities[10] * 0.250 * Event Healing); + } +} + +rule("Team 1 (Ability): Resilience") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[11] == True; + Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300; + } + + actions + { + Set Damage Received(Event Player, 70); + Wait Until(!(Event Player.Abilities[11] && Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Auto Repair") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.AutoRepair == True; + Global.GateHealth < Global.GateMaxHealth; + } + + actions + { + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2]); + Global.GateHealth += 10 * Global.AutoRepair; + Global.UpgradeGateMaxHealthValue += 10 * Global.AutoRepair; + Else; + Global.GateHealth += 5 * Global.AutoRepair; + Global.UpgradeGateMaxHealthValue += 5 * Global.AutoRepair; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(5, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ana Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ana), Button(Ability 1)), Custom String( + "Sleep Paralysis: Slept enemies cannot be woken up by damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Ana), Button(Ability 2)), Custom String( + "Multinade: Ana throws multiple Biotic Grenades")); + } +} + +rule("Brigitte Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Brigitte), Button(Ability 1)), Custom String( + "Heavy Iron: Hitting enemies with Whip Flail will root them in pace")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Brigitte), Button(Ultimate)), Custom String( + "Endeavor: Gain a health, damage and speed boost when your barrier breaks")); + } +} + +rule("Mercy Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mercy), Button(Ability 2)), Custom String( + "Angelic blessing: Healing an ally slowly charges their ultimate")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mercy), Button(Ultimate)), Custom String( + "Holy light missiles: Unleash blasts of holy light missiles during valkyrie")); + } +} + +rule("Lúcio Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Lúcio), Button(Secondary Fire)), Custom String( + "Healing Wave: Soundwave heals allies for 30% of their max HP")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Lúcio), Button(Ability 1)), Custom String( + "Reverse Amp: Amp It Up inflicts the opposite effect of the currently played song to enemies")); + } +} + +rule("Moira Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Moira), Button(Secondary Fire)), Custom String( + "Hose: Biotic Grasp primary will damage and push enemies back")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Moira), Button(Ability 2)), Custom String( + "Flourish: Biotic Orbs are 3x more effective")); + } +} + +rule("Baptiste Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String( + "Corrode: Regenerative Burst will damage and poison enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Breakthrough: Immortality Field HP threshold increased to 100%; allies inside gain ultimate")); + } +} + +rule("Ashe Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ashe), Button(Ability 2)), Custom String( + "Wildfire: Shooting a burning enemy ignites other nearby enemies")); + Event Player.HeroTalentText[2] = Array(Icon String(Fire), Custom String( + "Flare trigger: Coach gun instantly damages all burning enemies")); + } +} + +rule("D.Va Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(D.Va), Button(Secondary Fire)), Custom String( + "Voltage Grid: Defense Matrix will damage and root enemies it's casted over")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(D.Va), Button(Ability 1)), Custom String( + "Shooting Star: Boosters set enemies on fire")); + } +} + +rule("Genji Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Genji), Button(Ability 1)), Custom String( + "Venomous Strike: Swift Strike poisons enemies; heal for poison damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Genji), Button(Ultimate)), Custom String( + "Dragon's Breath: Dragonblade fires large explosive energy charges")); + } +} + +rule("Hanzo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Hanzo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "Stormbreak: Enemies eliminated by hanzo unleash a thundercloud")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Hanzo), Button(Ability 2)), Custom String( + "Punch II: Storm Arrows deal more damage and stun and knockback enemies")); + } +} + +rule("Widowmaker Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Widowmaker; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Widowmaker), Button(Ultimate)), Custom String( + "Kiss Of Death: Scoped critical hits against enemies below 30% health explode and instantly die")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Widowmaker), Button(Ability 2)), Custom String( + "Epidemic: Enemies hurt by Venom Mine unleash toxic pulses; heal for dealt damage")); + } +} + +rule("McCree Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Cassidy), Button(Ability 2)), Custom String( + "Panic: Flashbang puts enemies in fear; deal +120% more damage to enemies in fear")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Cassidy), Button(Ultimate)), Custom String( + "Clocked: Deadeye deals more damage and knocks enemies down")); + } +} + +rule("Reinhardt Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reinhardt), Button(Ability 2)), Custom String( + "Fire Blast: Fire Strike explodes as it deals damage, setting enemies on fire")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reinhardt), Button(Ultimate)), Custom String( + "Epicenter: Earthshatter travels in all directions")); + } +} + +rule("Soldier: 76 Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ultimate)), Custom String( + "Triple Threat: 2 more rockets are fired alongside Helix Rockets")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Soldier: 76), Button(Ability 1)), Custom String( + "Shoulder Check: Sprinting into enemies will damage and tackle them to the ground")); + } +} + +rule("Torbjörn Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Torbjörn), Button(Ability 2)), Custom String( + "Melting point: Unleash heatwaves during overload and molten core")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Torbjörn), Button(Ultimate)), Custom String( + "Roots Of Magma: Enemies trapped in Molten Core blots cannot move")); + } +} + +rule("Tracer Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Tracer), Button(Ability 2)), Custom String( + "Vortex: Recall pulls and roots enemies towards the activation point")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Tracer), Button(Ultimate)), Custom String( + "Chain Reaction: Pulse Bomb creates chain explosions on enemies damaged by it")); + } +} + +rule("Winston Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Winston), Button(Ability 2)), Custom String( + "Blast Barrier: Barrier Projector damages enemies inside the area")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Winston), Button(Ultimate)), Custom String( + "Next Generation: Eliminations during Primal Rage add +15% ultimate charge towards the next")); + } +} + +rule("Pharah Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Pharah; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ability 2)), Custom String( + "Head Trauma: Concussive Blast stuns and damages enemies for 25% of their max health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Pharah), Button(Ability 1)), Custom String( + "Thunderbird: Gain 150 shields and deal 4x the damage to barriers and objects")); + } +} + +rule("Bastion Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Bomblets: Bullets shot during sentry configuration are explosive")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ability 1)), Custom String( + "Tesla: A powerful mounted laser will autmotically attack one enemy at a time")); + } +} + +rule("Doomfist Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Jump)), Custom String( + "Phase Shifter: Immune to damage while any ability is active")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Doomfist), Button(Ultimate)), Custom String( + "Fissure: Meteor Strike leaves a large fissure behind that burns enemies over it")); + } +} + +rule("Echo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Focusing Optics: Focusing Beam damage ramp starts at 90% health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Streamline: Fire many more sticky bombs per burst")); + } +} + +rule("Junkrat Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Junkrat; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Fire), Custom String("Pyromania: All explosive attacks inflict fire damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Junkrat), Button(Ability 2)), Custom String( + "Short Fused: Steel Trap sets off violent explosions once triggered")); + } +} + +rule("Mei Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mei), Button(Ultimate)), Custom String( + "Cold Snap: Instantly freeze neaerby enemies once Cryo-Freeze expires")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mei), Button(Ability 2)), Custom String( + "Icebound: While Ice Wall is up, Icicles freeze and deal much more damage")); + } +} + +rule("Orisa Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Orisa), Button(Ability 1)), Custom String( + "Immovable Object: During Fortify, become immune and convert 50% of taken damage to healing")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Orisa), Button(Secondary Fire)), Custom String( + "Unstoppable Force: Halt! is much larger and pushes enemies. When triggered, it explodes violently")); + } +} + +rule("Reaper Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reaper), Button(Ability 1)), Custom String( + "shadow streak: shadow step creates a beam that damages enemies who cross")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reaper), Button(Ultimate)), Custom String( + "Loom: Traumatize enemies in front of you when using Wraith Form")); + } +} + +rule("Roadhog Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String("Stench: Roadhog constantly damages enemies nearby")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Roadhog), Button(Ability 1)), Custom String( + "Rusted Anchor: Hook deals more damage; Eliminations will reset hook cooldown")); + } +} + +rule("Sigma Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sigma), Button(Ability 1)), Custom String( + "Gravity Well: Kinetic Grasp gives invincibility")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sigma), Button(Ultimate)), Custom String( + "Gravity Channels: Gravitic Flux damages enemies for 75% of max hp instead of 50%")); + } +} + +rule("Sombra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sombra), Button(Secondary Fire)), Custom String( + "Malware: Enemies hacked or in fear take +100% more damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sombra), Button(Ultimate)), Custom String( + "Glitch: EMP leaves behind a large hack zone ")); + } +} + +rule("Symmetra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Symmetra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "High Voltage: Enemies eliminated by Symmetra explode and damage other enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ultimate)), Custom String( + "Energy Source: While Photon Barrier is active, all players regenerate health and gain ultimate")); + } +} + +rule("Wrecking Ball Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ultimate)), Custom String( + "Mirror Ball: Reflect 100% of taken damage to nearby enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ability 2)), Custom String( + "Distort: Adaptive Shields damages and hacks nearby enemies")); + } +} + +rule("Zarya Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zarya; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Zarya), Button(Ability 1)), Custom String( + "Augment: Health and barrier hp increased by 50%; barrier sized doubled")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Perpetual Energy: secondary inflicts burn damage that continues to last until the enemy dies")); + } +} + +rule("Zenyatta Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Vigor: The ally under the effect of Harmony Orb is immune to damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Zenyatta), Button(Ultimate)), Custom String( + "Perfect Balance: Transcendence damages enemies in a large proximity")); + } +} + +rule("Ana: Sleep Paralysis") +{ + event + { + Player Dealt Damage; + Team 1; + Ana; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Black), Victim, 1); + Wait(0.250, Ignore Condition); + Set Status(Victim, Null, Knocked Down, 5); + } +} + +rule("Ana: Multinade") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.AbilityCountdown = 4; + While(Event Player.AbilityCountdown > 0); + Wait(0.030, Ignore Condition); + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Cancel Primary Action(Event Player); + Wait(0.050, Ignore Condition); + Press Button(Event Player, Button(Ability 2)); + Event Player.AbilityCountdown -= 1; + End; + Wait(2, Ignore Condition); + } +} + +rule("Brigitte: Heavy Iron") +{ + event + { + Player Dealt Damage; + Team 1; + Brigitte; + } + + conditions + { + (Event Ability == Button(Primary Fire) || Event Ability == Button(Ability 1)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Victim, 1.500); + Set Status(Victim, Null, Rooted, 0.500); + Set Environment Credit Player(Victim, Event Player); + } +} + +rule("Brigitte: Endeavor") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Ability Cooldown(Event Player, Button(Secondary Fire)) >= 0.100; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Eye Position(Event Player), 15); + Heal(Players Within Radius(Event Player, 15, Team Of(Event Player), Off), Event Player, 200); + Event Player.DamageDealt *= 2.500; + Set Move Speed(Event Player, 100 * 1.750); + Add Health Pool To Player(Event Player, Armor, Max Health(Event Player) / 2, False, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(Is Dead(Event Player), 6); + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Move Speed(Event Player, 100); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Mercy: Angelic Blessing") +{ + event + { + Player Dealt Healing; + All; + Mercy; + } + + conditions + { + Event Player.Abilities[8] == True; + Healee != Event Player; + Normalized Health(Healee) < True; + } + + actions + { + Set Ultimate Charge(Healee, Ultimate Charge Percent(Healee) + 1); + Wait(0.400, Ignore Condition); + } +} + +rule("Mercy: Aurora") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ultimate(Event Player) == True; + } + + actions + { + Wait(1.500, Ignore Condition); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(All Teams), Event Player, True); + Create Beam Effect(All Players(All Teams), Mercy Heal Beam, Event Player, Event Player.Ability_Projectile1, Color(White), + Visible To Position and Radius); + Event Player.Effects_[3] = Last Created Entity; + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 70, Destination and Rate); + While(Event Player.Ability_End != Event Player.Ability_Projectile1); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Event Player.Ability_Projectile1, 1); + Wait(0.032, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[3]); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 120); + Loop If Condition Is True; + } +} + +rule("Lucio: Healing Wave") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4); + Heal(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 4, 4, Team Of(Event Player), Surfaces), + Event Player, Max Health(Filtered Array(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4, Team Of(Event Player), Surfaces), Is Alive(Current Array Element))) * 0.300); + } +} + +rule("Lucio: Reverse Amp") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + If(Is Using Ability 1(Event Player)); + Set Status(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Rooted, 4); + Else; + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 16.250); + End; + Play Effect(All Players(All Teams), Ring Explosion, Is Using Ability 1(Event Player) ? Color(Green) : Color(Yellow), Event Player, + 1); + Wait(0.400, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Hose") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Event Player.Abilities[8] == True; + Ability Resource(Event Player, Button(Primary Fire)) > False; + } + + actions + { + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Facing Direction Of(Event Player), 15, To World, + Cancel Contrary Motion); + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && !Is In Line of Sight(Current Array Element, Event Player, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Up, 8, To World, Cancel Contrary Motion); + Start Damage Over Time(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), + Distance Between(Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS)), Event Player, 1, 15); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Flourish - Damage") +{ + event + { + Player Dealt Damage; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("[Moira] Flourish - Healing") +{ + event + { + Player Dealt Healing; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Heal(Healee, Event Player, Event Healing * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Healee, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("Baptiste: Corrode") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 20); + Wait(0.200, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 12); + } +} + +rule("Baptiste: Breakthrough") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Status(Event Player, Unkillable) == True; + (Event Player.Abilities[12] ? Players On Hero(Hero(Baptiste), Team Of(Event Player)) : Empty Array).Abilities[12] == True; + } + + actions + { + Heal(Event Player, Event Player, 10000); + Set Status(Event Player, Null, Invincible, 0.800); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ashe: Firebourne") +{ + event + { + Player Dealt Damage; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability == Button(Primary Fire); + Has Status(Victim, Burning) == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Null, Burning, 10); + Start Damage Over Time(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Event Player, 10, 15); + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 5); + Wait(0.250, Ignore Condition); + } +} + +rule("Ashe: Taunt") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Damage(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, Burning)), + Event Player, 125); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Frozen, + 0.016); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Stunned, + 2); + } +} + +rule("D.Va: Voltage Grid") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 2, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 5, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 8, 0.500); + Wait(0.300, Ignore Condition); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Wait(0.016, Ignore Condition); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Loop If Condition Is True; + } +} + +rule("D.Va: Shooting Star") +{ + event + { + Player Dealt Knockback; + Team 1; + D.Va; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, 40); + Set Status(Victim, Null, Burning, 3); + Start Damage Over Time(Victim, Event Player, 3, 35); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 1); + } +} + +rule("Genji: Venomous Strike") +{ + event + { + Player Dealt Damage; + Team 1; + Genji; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 3, 25); + Start Damage Over Time(Victim, Event Player, 3, 25); + Damage(Victim, Event Player, 25); + Heal(Event Player, Event Player, 25); + } +} + +rule("Genji: Dragon's Breath") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is Firing Primary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Good Aura, Color(Lime Green), Event Player.Ability_Projectile1, 1, + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 80, Destination and Rate); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True); + Wait Until(Event Player.Ability_End == Event Player.Ability_Projectile1, 1); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Green), Event Player.Ability_Projectile1, 100); + Play Effect(All Players(All Teams), Bad Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Green), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 100); + } +} + +rule("[Hanzo] Stormbreak (Storm_Effects6)") +{ + event + { + Player Died; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[8] == True; + Hero Of(Attacker) == Hero(Hanzo); + } + + actions + { + Event Player.Storm_Projectile = Eye Position(Event Player); + Event Player.Storm_EndPoint = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Up * 12, Null, + All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Storm_Projectile, Event Player.Storm_EndPoint, 4, Destination and Rate); + Create Effect(All Players(All Teams), Cloud, Color(White), Vector(False, -0.500, False) + Event Player.Storm_Projectile, 4, + Visible To Position and Radius); + Event Player.Storm_Effects[3] = Last Created Entity; + Create Effect(All Players(All Teams), Bad Aura, Color(White), Event Player.Storm_Projectile, 3, Visible To Position and Radius); + Event Player.Storm_Effects[4] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(White), Event Player.Storm_Projectile, 3.500, Visible To Position and Radius); + Event Player.Storm_Effects[5] = Last Created Entity; + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Storm_Projectile, Ray Cast Hit Position( + Event Player.Storm_Projectile, Vector(0.100, 0, 0) + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), + False), Color(Aqua), Visible To Position and Radius); + Event Player.Storm_Effects[6] = Last Created Entity; + While(Distance Between(Event Player.Storm_Projectile, Event Player.Storm_EndPoint) > 1); + Wait(0.600, Ignore Condition); + Damage(Players Within Radius(Ray Cast Hit Position(Event Player.Storm_Projectile, Event Player.Storm_Projectile + Down * 1000, + Null, All Players(All Teams), False), 3, Team Of(Event Player), Surfaces), Attacker, 50); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + End; + Destroy Effect(Event Player.Storm_Effects[3]); + Destroy Effect(Event Player.Storm_Effects[4]); + Destroy Effect(Event Player.Storm_Effects[5]); + Destroy Effect(Event Player.Storm_Effects[6]); + } +} + +rule("Hanzo: Punch II") +{ + event + { + Player Dealt Damage; + Team 1; + Hanzo; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + Hero Of(Victim) != Hero(Torbjörn); + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.800); + Apply Impulse(Victim, Facing Direction Of(Event Player), 12, To World, Cancel Contrary Motion); + Apply Impulse(Victim, Up, 5, To World, Cancel Contrary Motion); + Set Environment Credit Player(Victim, Event Player); + Set Status(Victim, Null, Stunned, 1); + } +} + +rule("Widowmaker: Kiss Of Death") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + (Normalized Health(Victim) <= 0.300 || Event Damage >= Normalized Health(Victim) + Event Damage) == True; + Is Firing Secondary(Event Player) == True; + Event Ability == Button(Primary Fire); + Event Player.Abilities[8] == True; + Event Damage >= 40; + Event Was Critical Hit == True; + } + + actions + { + Kill(Victim, Event Player); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 2), Victim, 3); + Damage(Players Within Radius(Victim, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage * 1.500); + } +} + +rule("Widowmaker: Epidemic") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 8); + Play Effect(All Players(All Teams), Good Explosion, Color(Purple), Victim, 4); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Victim, 16); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Victim, 3); + Start Damage Over Time(Players Within Radius(Victim, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, 50); + Start Heal Over Time(Event Player, Event Player, 3, 50); + Wait(0.500, Ignore Condition); + } +} + +rule("McCree: Panic") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Victim.Feared_until = Total Time Elapsed + 3.500; + } +} + +rule("McCree: Panic - Damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), + Event Player.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 220, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("McCree: Clocked") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Damage(Victim, Event Player, Event Damage * 1.500); + Set Status(Victim, Null, Knocked Down, 3); + } +} + +rule("Reinhardt: Fire Blast") +{ + event + { + Player Dealt Damage; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Start Damage Over Time(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, 20); + Set Status(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Burning, 5); + } +} + +rule("Reinhardt: Epicenter") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is On Ground(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, Knocked Down, 2.500); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 10); + Damage(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, 50); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 20); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 30); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 40); + Wait(5, Ignore Condition); + } +} + +rule("[Soldier: 76] Rocket Assault Rifle") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile2 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(-2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Projectile1 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Position = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, + 0), Event Player, Rotation); + Event Player.Ability_End = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, 0), + Event Player, Rotation); + Chase Player Variable At Rate(Event Player, Ability_Position, Event Player.Ability_Projectile1, 60, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_End, Event Player.Ability_Projectile2, 60, Destination and Rate); + Wait Until(Event Player.Ability_Position == 0 && Event Player.Ability_End == 0, 2.500); + } +} + +rule("[Soldier: 76] First Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile1 != Event Player.Ability_Position; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_Position, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_Position, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_Position, 2.500); + Stop Chasing Player Variable(Event Player, Ability_Position); + Wait(0.016, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 80); + Stop Chasing Player Variable(Event Player, Ability_Position); + Event Player.Ability_Position = 0; + Event Player.Ability_Projectile1 = 0; + Wait(0.016, Ignore Condition); + } +} + +rule("[Soldier: 76] Second Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile2 != Event Player.Ability_End; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_End, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_End, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_End, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_End, 2.500); + Stop Chasing Player Variable(Event Player, Ability_End); + Damage(Players Within Radius(Event Player.Ability_End, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Event Player.Ability_End = 0; + Event Player.Ability_Projectile2 = 0; + } +} + +rule("Soldier: 76 - Init rockets") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile1 = Event Player.Ability_Position; + Event Player.Ability_Projectile2 = Event Player.Ability_End; + } +} + +rule("[Soldier: 76] Shoulder Check") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 3; + Is Alive(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) == True; + } + + actions + { + Damage(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Event Player, 55); + Set Status(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Null, Knocked Down, 1.500); + Apply Impulse(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Facing Direction Of(Event Player), 15, + To World, Cancel Contrary Motion); + Apply Impulse(Event Player, Vector(0, 8, 15), 15, To Player, Cancel Contrary Motion); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Closest Player To(Event Player, Opposite Team Of(Team Of( + Event Player))), 1); + Set Ability Cooldown(Event Player, Button(Melee), 0); + Press Button(Event Player, Button(Melee)); + Wait(1, Ignore Condition); + } +} + +rule("Torbjorn: Melting Point") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Event Player.Abilities[8] == True; + (Is Using Ability 2(Event Player) || Is Using Ultimate(Event Player)) == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Event Player, 8); + Play Effect(All Players(All Teams), Bad Explosion, Color(Yellow), Event Player, 8); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 16); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, + 25); + Set Status(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Off), Null, Burning, 3); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player, 100); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Torbjorn: Roots of Magma") +{ + event + { + Player Dealt Damage; + Team 1; + Torbjörn; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Set Status(Victim, Null, Rooted, 1); + Wait(1, Ignore Condition); + } +} + +rule("Tracer: Vortex") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, 0); + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 10); + Play Effect(All Players(All Teams), Ring Explosion, Color(Red), Position Of(Event Player), 24); + Play Effect(All Players(All Teams), Ring Explosion, Color(Yellow), Position Of(Event Player), 18); + Play Effect(All Players(All Teams), Ring Explosion, Color(Green), Position Of(Event Player), 12); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player), 6); + Set Environment Credit Player(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player); + } +} + +rule("Tracer: Vortex 2") +{ + event + { + Player Received Healing; + Team 2; + All; + } + + conditions + { + Healer.Abilities[8] == True; + Hero Of(Healer) == Hero(Tracer); + Is Using Ability 2(Healer) == True; + Event Ability == Null; + Event Damage <= 20; + } + + actions + { + Apply Impulse(Event Player, Up, 5, To World, Cancel Contrary Motion); + Wait(0.100, Ignore Condition); + Apply Impulse(Event Player, Direction Towards(Event Player, Healer), Distance Between(Event Player, Healer) * 3.500, To World, + Cancel Contrary Motion); + Set Status(Event Player, Null, Rooted, 1.300); + } +} + +rule("Tracer: Chain Reaction") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is True For Any(Filtered Array(All Players(Team Of(Event Player)), Current Array Element.Chain_Reaction_On), Distance Between( + Event Player, Current Array Element) <= 8 && True) == True; + Event Player.Chain_Reaction_Immune == False; + Event Player.Chain_Reaction_On == False; + Is Alive(Event Player) == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Event Player.Chain_Reaction_On = True; + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player, 3); + } +} + +rule("Tracer: Chain Reaction 2") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Event Player.Chain_Reaction_On == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Aqua), Event Player, 3); + Damage(Event Player, Players On Hero(Hero(Tracer), Opposite Team Of(Team Of(Event Player))), 200); + Wait(0.500, Ignore Condition); + Event Player.Chain_Reaction_Immune = True; + Event Player.Chain_Reaction_On = False; + Wait(2, Ignore Condition); + Event Player.Chain_Reaction_Immune = False; + } +} + +rule("Tracer: Chain Reaction 3") +{ + event + { + Player Dealt Damage; + Team 1; + Tracer; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Damage > 20; + Event Player.Abilities[12] == True; + } + + actions + { + Victim.Chain_Reaction_On = True; + } +} + +rule("[Winston] Electric Field") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 65); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Orb, Color(White), Event Player.Ability_Projectile1, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Stop Chasing Player Variable(Event Player, Ability_Resource); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Down * 1000, Null, + All Players(All Teams), False); + Wait(0.100, Ignore Condition); + Event Player.Ability_Resource = 5; + Wait(0.250, Ignore Condition); + Chase Player Variable At Rate(Event Player, Ability_Resource, 20, 7, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, Event Player.Ability_Resource, + Destination and Rate); + Wait(8.650, Restart When True); + Event Player.Ability_Active = False; + } +} + +rule("[Winston] Electric Field 2") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 33); + Play Effect(All Players(All Teams), Ring Explosion, Color(Blue), Event Player.Ability_Projectile1, 10); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 80); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Event Player.Ability_Projectile1, 12); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player.Ability_Projectile1, 125); + } +} + +rule("Winston: Next Generation") +{ + event + { + Player Earned Elimination; + Team 1; + Winston; + } + + conditions + { + Ultimate Charge Percent(Event Player) <= 80; + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 15); + } +} + +rule("Pharah: Head Trauma") +{ + event + { + Player Dealt Knockback; + Team 1; + Pharah; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Victim != Event Player; + } + + actions + { + Damage(Victim, Event Player, Max Health(Victim) * 0.300); + Set Status(Victim, Event Player, Knocked Down, 1); + Play Effect(All Players(All Teams), Good Explosion, Color(Team 1), Victim, 1); + } +} + +rule("Pharah: Thunderbird") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[12] == True; + Hero Of(Event Player) == Hero(Pharah); + } + + actions + { + Event Player.DamageDealt *= 4; + Start Damage Modification(All Players(All Teams), Event Player, 25, Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Add Health Pool To Player(Event Player, Shields, 150, True, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(!Event Player.Abilities[12] || Hero Of(Event Player) != Hero(Pharah), 99999); + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Stop Damage Modification(Event Player.Modification_Damage[1]); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + } +} + +rule("Orisa: Unstoppable Force") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Direction = Facing Direction Of(Event Player); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Sphere, Color(Green), Event Player.Ability_Projectile1, 4, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player) + Facing Direction Of(Event Player) * 0.500; + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 100, Null, All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 25, Destination and Rate); + Wait(0.250, Ignore Condition); + Wait Until((!Event Player.Gen_Available && Is Button Held(Event Player, Button(Secondary Fire))) || ( + Event Player.Ability_Projectile1 == Event Player.Ability_End), 99999); + Stop Chasing Player Variable(Event Player, Ability_Projectile1); + Wait(0.500, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, + 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Orisa: Availability for Halt!") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Available = True; + Wait Until(!Is Button Held(Event Player, Button(Secondary Fire)), 99999); + Event Player.Gen_Available = False; + } +} + +rule("Orisa: Drag effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Player.Ability_Active == True; + } + + actions + { + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Is Alive(Event Player) ? Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of( + Event Player)), Surfaces) : Empty Array, Event Player.Ability_Projectile1), 8, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Event Player.Ability_Projectile1, Event Player.Ability_End), 20, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Up, 5, + To Player, Cancel Contrary Motion); + Wait(0.200, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Orisa: Immoveable Object - Reduce dmg") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Damage Received(Event Player, 100 * 0.003); + Wait Until(!Is Using Ability 1(Event Player), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Orisa: Immovable Object - Healing") +{ + event + { + Player Took Damage; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Event Player, Null, Event Damage * 3); + } +} + +rule("[Reaper] Shadow Streak (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Event Player.Ability_Position = Position Of(Event Player) + Vector(0, 1, 0); + Wait(2, Abort When False); + Event Player.Ability_End = Position Of(Event Player) + Vector(0, 1, 0); + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Ability_End, Event Player.Ability_Position, Color(Black), + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player) || Is Using Ability 2(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage start to end (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players(Opposite Team Of(Team Of( + Event Player))), Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_Position, + Event Player.Ability_End, All Living Players(All Teams), Event Player, True), 1); + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage end to start (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Players(Opposite Team Of(Team Of(Event Player))), + Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_End, + Event Player.Ability_Position, All Living Players(All Teams), Event Player, True), 1); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Reaper: Loom") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Hacked, 1.500); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Rooted, 1.500); + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Event Player, 45); + } +} + +rule("Sigma: Gravity Well") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, 25); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Null, Rooted, 2); + Set Status(Event Player, Null, Invincible, 1); + Play Effect(Event Player, Ring Explosion, Color(Blue), Eye Position(Event Player), 50); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Sigma: Gravity Channels") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ultimate(Event Player)), Event Player, 150, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[12], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Echo: Focusing Optics") +{ + event + { + Player Dealt Damage; + Team 1; + Echo; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Normalized Health(Victim) > 0.500; + Normalized Health(Victim) <= 0.900; + Is Duplicating(Event Player) == False; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 3); + Play Effect(All Players(All Teams), Bad Explosion, Color(Violet), Victim, 0.500); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Wait(0.700, Abort When False); + Cancel Primary Action(Event Player); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Set Projectile Speed(Event Player, 100); + Wait(0.150, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Bomblets") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Is In Alternate Form(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Orange), Null + Ray Cast Hit Position(Eye Position(Event Player), + Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, All Living Players(Opposite Team Of(Team Of( + Event Player))), All Players(Team Of(Event Player)), True), 2); + Damage(Players Within Radius(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 2, + Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 12); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Taser - Loop damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is True For Any(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive(Current Array Element) + && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status(Current Array Element, + Phased Out) && Distance Between(Event Player, Current Array Element) <= 25) == True; + Is Alive(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Explosion Sound, Color(White), Event Player.Ability_Player, 80); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Event Player.Ability_Player, 1); + Event Player.Ability_Player = Filtered Array(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive( + Current Array Element) && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status( + Current Array Element, Phased Out) && Distance Between(Event Player, Current Array Element) <= 25); + Damage(Players Within Radius(Event Player.Ability_Player, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 30); + Wait(0.450, Ignore Condition); + Loop If Condition Is True; + Event Player.Ability_Player = Null; + } +} + +rule("Bastion: Taser - Visual beam") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player + Vector(False, 1, False), + Event Player.Ability_Player != Null ? Event Player.Ability_Player : Event Player, Color(Aqua), + Visible To Position Radius and Color); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[12], 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Sombra: Malware") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, + Hacked) || Current Array Element.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 200, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Sombra: Glitch") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Ability_Active = True; + Event Player.Ability_Position = Position Of(Event Player); + Create Effect(All Players(All Teams), Sphere, Color(Purple), Event Player.Ability_Position, 15, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait(8, Ignore Condition); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Sombra: Glitch - Loop") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Ability_Active == True; + } + + actions + { + Set Status(Players Within Radius(Event Player.Ability_Position, 15, Opposite Team Of(Team Of(Event Player)), Off), Null, Hacked, + 0.750); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Mei: Cold Snap") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Event Player, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Is Using Ability 1(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Damage(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Frozen, 2); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Rooted, 2); + Play Effect(All Players(All Teams), Ring Explosion, Color(White), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Sky Blue), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player) + Vector(0, 1, 0), 20); + } +} + +rule("Mei: Icebound") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Aqua), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Set Projectile Speed(Event Player, 200); + Wait Until(!Is Firing Secondary(Event Player), 99999); + Destroy Effect(Event Player.Effects_[2]); + Set Projectile Speed(Event Player, 100); + } +} + +rule("Mei: Icebound - Icicles hit") +{ + event + { + Player Dealt Damage; + Team 1; + Mei; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 1.250); + Set Status(Victim, Null, Frozen, 1); + Set Status(Victim, Null, Rooted, 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Victim, 1); + } +} + +rule("Wrecking Ball: Mirror Ball") +{ + event + { + Player Took Damage; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 4.500, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage); + Wait(0.100, Ignore Condition); + } +} + +rule("Wrecking Ball: Distort") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Set Status(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Hacked, Count Of( + Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces)) * 1.500); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Violet), Position Of(Event Player), 125); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Sound, Color(Purple), Position Of(Event Player), 16); + Play Effect(All Players(All Teams), Explosion Sound, Color(Violet), Position Of(Event Player), 80); + } +} + +rule("Symmetra: High voltage") +{ + event + { + Player Dealt Final Blow; + Team 1; + Symmetra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Victim, 10); + Play Effect(All Players(All Teams), Bad Explosion, Color(Aqua), Victim, 8); + Damage(Players Within Radius(Victim, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 150); + } +} + +rule("Symmetra: Energy Source") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is True For Any(Players On Hero(Hero(Symmetra), Team Of(Event Player)), Is Using Ultimate(Current Array Element) + && Current Array Element.Abilities[12]) == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 1, 40); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Event Player, 0.100); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Junkrat: Pyromania") +{ + event + { + Player Dealt Knockback; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability != Button(Melee); + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 2, 30); + Set Status(Victim, Null, Burning, 2); + } +} + +rule("Junkrat: Short Fused") +{ + event + { + Player Dealt Damage; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + } + + actions + { + Event Player.Ability_Countdown = 4; + While(Event Player.Ability_Countdown > 0); + Event Player.Ability_Countdown -= 1; + Event Player.Ability_Position = Position Of(Victim) + Vector(Random Real(-2, 2), Random Real(-2, 2), Random Real(-2, 2)); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 4); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Position, 4); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 35); + Set Status(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player, Stunned, 0.800); + Wait(0.200, Ignore Condition); + End; + } +} + +rule("Zenyatta: Vigor") +{ + event + { + Player Dealt Healing; + Team 1; + Zenyatta; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Healee, Null, Invincible, 1); + Wait(0.800, Ignore Condition); + } +} + +rule("Zenyatta: Perfect Balance") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Over Time(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 0.750, 200); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player, 24); + Wait(0.600, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Stench") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Violet), Event Player, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Roadhog: Stench effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 8; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 9); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Rusted Anchor") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ability 1(Event Player)), Event Player, 400, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Roadhog: Rusted Anchor - Reset cooldown") +{ + event + { + Player Earned Elimination; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ability 1(Event Player), 3); + Set Ability Cooldown(Event Player, Button(Ability 1), False); + } +} + +rule("Zarya: Augment") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Scaling Barriers(Event Player, 2, True); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5 + 50; + Set Max Health(Event Player, Event Player.PlayerHealth); + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Zarya), 99999); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Stop Scaling Barriers(Event Player); + } +} + +rule("Zarya: Perpetual Energy") +{ + event + { + Player Dealt Knockback; + Team 1; + Zarya; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Event Player.Abilities[12] == True; + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 9999, 15); + Set Status(Victim, Null, Burning, 9999); + } +} + +rule("Doomfist: Phase Shifter") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + (Is Firing Secondary(Event Player) || Is Using Ability 1(Event Player) || Is Using Ability 2(Event Player)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Event Player, Null, Phased Out, 1); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ultimate(Event Player), 99999); + Event Player.Ability_Position = Position Of(Event Player); + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player), 8); + Event Player.Ability_Active = False; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player.Ability_Position, 16); + While(Event Player.Ability_Active == True); + Damage(Players Within Radius(Event Player.Ability_Position, 8, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 34); + Wait(0.235, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[1]); + Destroy Effect(Event Player.Effects_[2]); + } +} + +rule("Team 1 (Perk): Sharpshooter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Global.Perk[0] == True; + Event Ability != Null; + Distance Between(Event Player, Victim) >= 10; + } + + actions + { + Damage(Victim, Event Player, 50 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Perk): Bulletstorm") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.Perk[1] == True; + (Ammo(Event Player, 0) < Max Ammo(Event Player, 0) || Ammo(Event Player, 1) < Max Ammo(Event Player, 1)) == True; + } + + actions + { + Set Ammo(Event Player, 0, 1000); + Set Ammo(Event Player, 1, 1000); + } +} + +rule("Team 1 Challenges") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + If(Global.Perk[2] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[17] = Last Text ID; + End; + If(Global.Perk[0] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[18] = Last Text ID; + End; + If(Global.Perk[1] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[19] = Last Text ID; + End; + If(Global.MaxHealthDone == 50); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + End; + } +} + +rule("Remove Auto Repair when Player leaves") +{ + event + { + Player Left Match; + Team 1; + All; + } + + actions + { + Global.AutoRepair -= Event Player.Abilities[16]; + } +} + +rule("Refund") +{ + event + { + Subroutine; + Refund; + } + + actions + { + "Refund Money" + Event Player.Money[0] += Event Player.Money[1]; + Event Player.Money[1] = 0; + "Reset Headhunter" + Event Player.Abilities[1] = 0; + "Reset Ambush" + Event Player.Abilities[2] = 0; + "Reset QuickFix" + Event Player.Abilities[3] = 0; + "Reset HeavyWeight" + Event Player.Abilities[4] = 0; + "Reset Charged" + Event Player.Abilities[5] = 0; + "Reset Haste" + Event Player.Abilities[6] = 0; + "Reset HeavyImpact" + Event Player.Abilities[7] = 0; + "Reset HeroTalent1" + Event Player.Abilities[8] = 0; + "Reset SecondWind" + Event Player.Abilities[9] = 0; + "Reset BindingHeal" + Event Player.Abilities[10] = 0; + "Reset Resilience" + Event Player.Abilities[11] = 0; + "Reset HeroTalent2" + Event Player.Abilities[12] = 0; + "Reset Damage" + Event Player.Abilities[13] = 0; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + "Reset Health" + Event Player.Abilities[14] = 0; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + If(Global.MaxHealthDone == 0); + End; + "Reset Healing" + Event Player.Abilities[15] = 0; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + "Reset AutoRepair" + Global.AutoRepair -= Event Player.Abilities[16]; + Event Player.Abilities[16] = 0; + } +} + +rule("Lucio Dash HUD Creation") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + } + + actions + { + If(Event Player.Lucio_Dash_Active == False); + Event Player.Lucio_Dash_Active = True; + Create HUD Text(Event Player, Null, Null, Custom String("{0} Slam on ground - Press: {1}", Ability Icon String(Hero(Wrecking Ball), + Button(Crouch)), Input Binding String(Button(Crouch))), Left, 1000, Color(White), Color(White), Color(White), + Visible To and String, Default Visibility); + Event Player.Lucio_Dash_Icon = Last Text ID; + End; + } +} + +rule("Lucio Dash Remove HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) != Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + } + + actions + { + Destroy HUD Text(Event Player.Lucio_Dash_Icon); + Event Player.Lucio_Dash_Active = False; + } +} + +rule("Lucio Dash") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + Is On Ground(Event Player) == False; + Is Button Held(Event Player, Button(Crouch)) == True; + } + + actions + { + Apply Impulse(Event Player, Down, 20, To World, Cancel Contrary Motion); + } +} + +rule("Ana Self-Nano") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + Ultimate Charge Percent(Event Player) == 100; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Abort If(Global.SelfNanoWorkshopSetting == False && Number Of Players(Team 1) > 1); + Wait(0.100, Ignore Condition); + If(Is Using Ultimate(Event Player) == False); + Create Dummy Bot(Hero(Ana), Team Of(Event Player), -1, Position Of(Event Player) + Backward, Eye Position(Event Player)); + Event Player.AnaEntityID = Last Created Entity; + Wait(0.100, Ignore Condition); + Set Ultimate Charge(Event Player.AnaEntityID, 100); + Start Facing(Event Player.AnaEntityID, Direction Towards(Eye Position(Event Player.AnaEntityID), Position Of(Event Player) + Up), + 1000, To World, Direction and Turn Rate); + Set Invisible(Event Player.AnaEntityID, All); + Set Status(Event Player.AnaEntityID, Null, Phased Out, 9999); + Wait(0.150, Ignore Condition); + Press Button(Event Player.AnaEntityID, Button(Ultimate)); + Set Ultimate Charge(Event Player, 0); + Wait(0.150, Ignore Condition); + Teleport(Event Player.AnaEntityID, Position Of(First Of(Spawn Points(Team Of(Event Player))))); + Wait(10, Ignore Condition); + Destroy Dummy Bot(Team Of(Event Player), Slot Of(Event Player.AnaEntityID)); + End; + } +} + +rule("Reinhard Charge Cancel") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + } + + actions + { + Wait(0.600, Ignore Condition); + Wait Until(Is Button Held(Event Player, Button(Ability 1)), 5); + Set Status(Event Player, Null, Rooted, 0.001); + Wait Until(Event Player.ReinPin, 1); + If(Event Player.ReinPin != 0); + Apply Impulse(Event Player.ReinPin, Facing Direction Of(Event Player), 15, To World, Cancel Contrary Motion); + End; + } +} + +disabled rule("Map Editor Walls") +{ + event + { + Ongoing - Global; + } +} + +rule("Initial Global") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Empty Array; + Global.AllDir = Empty Array; + Global.firstpos = Empty Array; + Global.secondpos = Empty Array; + Global.firstpoint2 = Empty Array; + Global.secondpoint2 = Empty Array; + Global.second = Empty Array; + Global.z = Empty Array; + Global.Wall_ID = Empty Array; + Global.g_beamType = Empty Array; + } +} + +rule("Initial Player") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.filterpos = 0; + Event Player.lastsavedpos = 0; + Event Player.closestbodypos = 0; + Event Player.fullbodypos = 0; + Event Player.prevpos_intersection = 0; + Event Player.active_wall = Empty Array; + Event Player.closestwall = Empty Array; + } +} + +rule("Collision Logic") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Event Player.lastsavedpos = (Eye Position(Event Player) + Position Of(Event Player)) / 2; + Wait(0.016, Ignore Condition); + Event Player.closestwall = Filtered Array(Global.AllPos, Distance Between(Global.AllPos[Current Array Index], Event Player) + <= Distance Between(Global.AllPos[Current Array Index], Global.firstpos[Current Array Index]) + || Event Player.active_wall[Current Array Index] == 1 || (Dot Product(Direction Towards(Current Array Element, + Event Player.lastsavedpos), Global.AllDir[Current Array Index]) > 0) != (Dot Product(Direction Towards(Current Array Element, + Event Player), Global.AllDir[Current Array Index]) > 0)); + For Player Variable(Event Player, x, 0, Count Of(Event Player.closestwall), 1); + Global.z = Index Of Array Value(Global.AllPos, Event Player.closestwall[Event Player.x]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3 || Global.Wall_ID[Global.z] == 5); + If(Y Component Of(Global.firstpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.firstpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.firstpos[Global.z]; + Else If(Y Component Of(Global.secondpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.secondpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.secondpos[Global.z]; + Else; + Event Player.closestbodypos = Position Of(Event Player); + End; + Event Player.fullbodypos = Vector(X Component Of(Eye Position(Event Player)), Y Component Of(Event Player.closestbodypos), + Z Component Of(Eye Position(Event Player))); + Event Player.filterpos = Event Player.fullbodypos + Global.AllDir[Global.z] * Dot Product( + Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) / Dot Product(Global.AllDir[Global.z], + Global.AllDir[Global.z]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3); + If((Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.lastsavedpos), Global.AllDir[Global.z]) > 0) != ( + Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.fullbodypos), Global.AllDir[Global.z]) > 0)); + Event Player.intersection_length = Dot Product(Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) + / Dot Product(Direction Towards(Event Player.lastsavedpos, Event Player.fullbodypos), Global.AllDir[Global.z]); + Event Player.prevpos_intersection = Event Player.fullbodypos + Direction Towards(Event Player.lastsavedpos, + Event Player.fullbodypos) * Vector(1, Empty Array, 1) * Event Player.intersection_length; + If(Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of( + Global.firstpos[Global.z]), Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], + Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of( + Global.firstpos[Global.z]), Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), + Direction Towards(Global.firstpos[Global.z], Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards( + Global.secondpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.prevpos_intersection)) + >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.secondpos[Global.z], Event Player.prevpos_intersection)) >= 0); + Cancel Primary Action(Event Player); + Teleport(Event Player, Event Player.prevpos_intersection + Direction Towards(Event Player.prevpos_intersection, + Event Player.lastsavedpos) * Vector(1, Empty Array, 1) * 2); + End; + End; + End; + Event Player.thickness = 0; + If(Global.Wall_ID[Global.z] == 5); + Event Player.thickness = 4; + Else; + Event Player.thickness = 1; + End; + If(Distance Between(Event Player.fullbodypos, Event Player.filterpos) <= Event Player.thickness && Dot Product(Direction Towards( + Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], Event Player.filterpos)) + >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.firstpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector( + X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), Z Component Of( + Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product( + Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), Y Component Of( + Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], + Event Player.filterpos)) >= 0); + If(!Global.is_Grounded); + Set Gravity(Event Player, 100); + End; + If(Event Player.active_wall[Global.z] == False); + Event Player.active_wall[Global.z] = 1; + If((Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3) && Global.is_Grounded == False); + Set Gravity(Event Player, 100); + Else If(Global.Wall_ID[Global.z] == 5); + Disable Movement Collision With Environment(Event Player, False); + End; + End; + If(Global.Wall_ID[Global.z] == 1); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos) * Vector(1, Empty Array, 1), 0.001, + To World, Cancel Contrary Motion); + Set Move Speed(Event Player, 100 - Dot Product(Direction Towards(Eye Position(Event Player), Eye Position(Event Player) + + World Vector Of(Throttle Of(Event Player), Event Player, Rotation)), Direction Towards(Event Player.filterpos, + Event Player.fullbodypos) * -1) * 100); + Else If(Global.Wall_ID[Global.z] == 3); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos), Speed Of(Event Player), To World, + Cancel Contrary Motion); + End; + Else; + Event Player.active_wall[Global.z] = 0; + Set Move Speed(Event Player, 100); + End; + End; + End; + Loop; + } +} + +rule("Reset") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Count Of(Filtered Array(Event Player.active_wall, Current Array Element != 0)) == 0; + } + + actions + { + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("Effect Creation") +{ + event + { + Ongoing - Global; + } + + actions + { + Wait(5, Ignore Condition); + If(Global.showwalls); + For Global Variable(x, 0, Count Of(Global.AllPos), 1); + If(Global.Wall_ID[Global.x] == 5); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Else; + Skip(Array(14, 0, 5, 10)[Index Of Array Value(Array(1, 2, 3), Global.g_beamType[Global.x]) + 1]); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(9); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(4); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + End; + Wait(0.016, Ignore Condition); + End; + End; + } +} + +rule("Wall Data") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Array(Vector(155.968, 12.470, -30.507), Vector(155.962, 12.472, -62.500), Vector(81.153, 6.453, -103.851), Vector( + 69.148, 6.474, -104.548)); + Global.AllDir = Array(Vector(-1, 0, -0.002), Vector(1, 0, -0.001), Vector(0, 0, 1), Vector(0.001, 0, 1)); + Global.firstpos = Array(Vector(155.971, 11.047, -31.771), Vector(155.964, 11.050, -61.229), Vector(79.761, 5.030, -103.852), + Vector(67.738, 5.022, -104.547)); + Global.secondpos = Array(Vector(155.965, 13.894, -29.242), Vector(155.960, 13.894, -63.771), Vector(82.544, 7.876, -103.851), + Vector(70.558, 7.925, -104.550)); + Global.firstpoint2 = Array(Vector(155.971, 13.894, -31.771), Vector(155.964, 13.894, -61.229), Vector(79.761, 7.876, -103.852), + Vector(67.738, 7.925, -104.547)); + Global.secondpoint2 = Array(Vector(155.965, 11.047, -29.242), Vector(155.960, 11.050, -63.771), Vector(82.544, 5.030, -103.851), + Vector(70.558, 5.022, -104.550)); + Global.z = 3; + Global.g_beamType = Array(1, 1, 1, 1); + Global.showwalls = True; + Global.Wall_ID = Array(5, 5, 5, 5); + } +} + +disabled rule("NEW SHOP") +{ + event + { + Ongoing - Global; + } +} + +rule("Setting Shop Position") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.ShopCamPos = 900 * Up; + Global.ShopPosAngle[1] = Direction From Angles(Horizontal Angle From Direction(Forward), Vertical Angle From Direction(Forward) + - 90); + Global.ShopPosAngle[0] = Cross Product(Global.ShopPosAngle[1], Forward); + Global.ShopBasePos = Global.ShopCamPos - 9 * Global.ShopPosAngle[1] + 142 * Forward; + } +} + +rule("Create Shop Buttons") +{ + event + { + Ongoing - Global; + } + + actions + { + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] + 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] - 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Refund"), + Global.ShopBasePos + 45 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 3, Do Not Clip, Visible To, Color(Green), + Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("[{0}] Leave", + Input Binding String(Button(Reload))), Global.ShopBasePos + 45 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 3, + Do Not Clip, Visible To and String, Color(Green), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("{0}$\n", Local Player.Money[0]), + Global.ShopBasePos + 36.500 * Global.ShopPosAngle[1], 3, Do Not Clip, Visible To and String, Color(White), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("▲"), Update Every Frame( + Global.ShopBasePos - (4 + Vertical Facing Angle Of(Local Player)) * Global.ShopPosAngle[1] + Horizontal Facing Angle Of( + Local Player) * Global.ShopPosAngle[0]), 4, Do Not Clip, Visible To Position and Color, Custom Color( + 245 + 10 * Sine From Radians(4 * Total Time Elapsed), 205 + 50 * Sine From Radians(4 * Total Time Elapsed), + 200 * Sine From Radians(4 * Total Time Elapsed), 255), Default Visibility); + "Headhunter" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[1] ? Custom String("Headhunter II\n  800$") : Custom String("Headhunter I\n  800$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[1] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Ambush" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[2] ? Custom String("Ambush II\n 800$") : Custom String("Ambush I\n 800$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[2] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Quick Fix" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[3] ? Custom String("Quick Fix II\n  700$") : Custom String("Quick Fix I\n  700$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[3] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavyweight" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[4] ? Custom String("Heavyweight II\n  1000$") : Custom String("Heavyweight I\n  1000$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[4] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Charged" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[5] ? Custom String("Charged II\n  700$") : Custom String("Charged I\n  700$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[5] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Haste" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[6] ? Custom String("Haste II\n 700$") : Custom String("Haste I\n 700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[6] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavy Impact" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[7] ? Custom String("Heavy Impact II\n  1000$") : Custom String("Heavy Impact I\n  1000$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[7] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 1" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 1\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[8] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "Second Wind" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[9] ? Custom String("Second Wind II\n   900$") : Custom String("Second Wind I\n   900$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[9] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Binding Heal" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[10] ? Custom String("Binding Heal II\n   700$") : Custom String("Binding Heal I\n   700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[10] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Resilience" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[11] ? Custom String("Resilience II\n  800$") : Custom String("Resilience I\n  800$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[11] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 2" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 2\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[12] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "PlusDamage" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Damage\n  400$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealth" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Health\n 400$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Healing\n  400$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, Visible To and String, + Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "+{0} Auto-Repair\n    400$", Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Global.AutoRepair < 5 ? Color(Green) : Color(Gray), Default Visibility); + "Use Update Every Frame to avoid showing the String when the cursor is out of bounds, resulting in 0\r\n ROW 0" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -33.750 ? Array(Custom String("Leave Buy Menu\n"), Custom String( + ""), Custom String(""), Custom String("Refund your money\n"))[Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) + / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, + Color(White), Default Visibility); + "ROW 1" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 22.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -11.250 ? Array(Custom String("Increase your damage by 5%\n"), + Local Player.Abilities[9] ? Custom String( + "Second Wind II: 60% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds") + : Custom String( + "Second Wind I: 30% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds"), + Local Player.Abilities[5] ? Custom String("Charged II: Ultimates cost 40% less\n") : Custom String( + "Charged I: Ultimates cost 20% less\n"), Local Player.Abilities[1] ? Custom String( + "Headhunter II: Critical hits deal 80% more damage\n") : Custom String("Headhunter I: Critical hits deal 40% more damage\n")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 2" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 36.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 11.250 ? Array(Custom String("Increase your health by 5%\n"), + Local Player.Abilities[10] ? Custom String("Binding Heal II: Heal yourself for 50% the amount when healing allies\n") + : Custom String("Binding Heal I: Heal yourself for 25% the amount when healing allies\n"), + Local Player.Abilities[6] ? Custom String( + " Haste II: Ability cooldown is reduced by 50%\nDoes not affect abilities with multiple charges") : Custom String( + " Haste I: Ability cooldown is reduced by 25%\nDoes not affect abilities with multiple charges"), + Local Player.Abilities[2] ? Custom String("Ambush II: Deal 60% more damage when attacking enemies from behind or above\n") + : Custom String("Ambush I: Deal 30% more damage when attacking enemies from behind or above\n"))[Round To Integer(( + Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 3" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 83.750) < 72.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 33.750 ? Array(Custom String("Increase your healing by 5%\n"), + Local Player.Abilities[11] ? Custom String("Resilience II: Take 30% less damage while below 60% health\n") : Custom String( + "Resilience I: Take 30% less damage while below 30% health\n"), Local Player.Abilities[7] ? Custom String( + "Heavy Impact II: Every hit has a chance to stun the enemy for 2 seconds\n") : Custom String( + "Heavy Impact I: Every hit has a chance to stun the enemy for 1 second\n"), Local Player.Abilities[3] ? Custom String( + "Quick Fix II: Eliminations restore 100 HP and shortly increase speed by 40%\n") : Custom String( + "Quick Fix I: Eliminations restore 50 HP and shortly increase speed by 20%\n"))[Round To Integer((Horizontal Facing Angle Of( + Local Player) + 90) / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, + Visible To and String, Color(White), Default Visibility); + "ROW 4" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 133) < 99.250 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 56.250 ? Array(Custom String( + "Increase your auto-repair by {0}/5s\n", Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Custom String("{0}", Local Player.HeroTalentText[2][1]), Custom String("{0}", Local Player.HeroTalentText[1][1]), + Local Player.Abilities[4] ? Custom String( + "Heavyweight II: Your knock back attacks deal 50% more damage and knock back\n            You receive 33% less knock back") + : Custom String( + "Heavyweight I: Your knock back attacks deal 25% more damage and knock back\n            You receive 20% less knock back")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + } +} + +rule("Toggle Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + !Is Dummy Bot(Event Player) == True; + Is Button Held(Event Player, Button(Reload)) == True; + !Is Communicating Any Emote(Event Player) == True; + } + + actions + { + If(Event Player.isInMenu == False); + Wait Until(!Is Button Held(Event Player, Button(Reload)), 0.500); + If(!Is Button Held(Event Player, Button(Reload))); + Abort; + End; + End; + Event Player.isInMenu = !Event Player.isInMenu; + } +} + +rule("Open Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == True; + } + + actions + { + Event Player.PlayerFacing = Facing Direction Of(Event Player); + Start Camera(Event Player, Global.ShopCamPos, Global.ShopCamPos + Forward, 0); + Disable Hero HUD(Event Player); + Call Subroutine(DisablePlayer); + Set Aim Speed(Event Player, 200); + } +} + +rule("Close Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == False; + } + + actions + { + Stop Camera(Event Player); + Enable Hero HUD(Event Player); + Call Subroutine(EnablePlayer); + Set Aim Speed(Event Player, 100); + Set Facing(Event Player, Event Player.PlayerFacing, To World); + } +} + +rule("Subroutine: Disable Player") +{ + event + { + Subroutine; + DisablePlayer; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + Set Primary Fire Enabled(Event Player, False); + Set Secondary Fire Enabled(Event Player, False); + Set Ability 1 Enabled(Event Player, False); + Set Ability 2 Enabled(Event Player, False); + Set Melee Enabled(Event Player, False); + Set Jump Enabled(Event Player, False); + Set Crouch Enabled(Event Player, False); + Disallow Button(Event Player, Button(Ultimate)); + } +} + +rule("Subroutine: Enable Player") +{ + event + { + Subroutine; + EnablePlayer; + } + + actions + { + Stop Forcing Throttle(Event Player); + Set Primary Fire Enabled(Event Player, True); + Set Secondary Fire Enabled(Event Player, True); + Set Ability 1 Enabled(Event Player, True); + Set Ability 2 Enabled(Event Player, True); + Set Melee Enabled(Event Player, True); + Set Jump Enabled(Event Player, True); + Set Crouch Enabled(Event Player, True); + Allow Button(Event Player, Button(Ultimate)); + } +} + +rule("Buy Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Primary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + Event Player.isInMenu = !Event Player.isInMenu; + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Money[1] != 0); + Call Subroutine(Refund); + Else; + Small Message(Local Player, Custom String("You don't have anything to refund!")); + End; + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[13] += 1; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 2); + If(Event Player.Money[0] >= 900); + Event Player.Money[0] -= 900; + Event Player.Money[1] += 900; + Event Player.Abilities[9] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[5] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[1] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[14] += 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[10] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[6] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[2] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[15] += 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[11] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[7] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[3] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Global.AutoRepair != 5); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Global.AutoRepair += 1; + Event Player.Abilities[16] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[12] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[8] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[4] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + End; + } +} + +rule("Refund Single Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Secondary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[13] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[13] -= 1; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 0); + Event Player.Money[0] += 900; + Event Player.Money[1] -= 900; + Event Player.Abilities[9] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[5] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[1] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[14] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[14] -= 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[10] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[6] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[2] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[15] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[15] -= 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[11] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[7] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[3] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[16] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Global.AutoRepair -= 1; + Event Player.Abilities[16] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[12] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[8] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[4] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + End; + } +} + +rule("Create Player HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Custom String("{0}{1}", + Event Player, Event Player.isInMenu ? Custom String("(In Shop)") : Custom String("")), Custom String("{0}{1}", Is Alive( + Event Player) ? Custom String("{0} HP", Round To Integer(Health(Event Player), Up)) : Custom String("Dead"), Custom String( + ", {0}$", Event Player.Money)), Left, Local Player == Event Player ? -1 : Slot Of(Event Player), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), + Visible To Sort Order String and Color, Default Visibility); + Create HUD Text(Event Player.Abilities[13] || Global.DamageDone ? Event Player : Null, Null, Null, Custom String("+{0}% Damage", + Global.DamageDone + Event Player.Abilities[13] * 5), Left, 913, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[9] ? Event Player : Null, Null, Null, Custom String("Second Wind {0}", + Event Player.Abilities[9] == 1 ? Custom String("I") : Custom String("II")), Left, 908, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[5] ? Event Player : Null, Null, Null, Custom String("Charged {0}", + Event Player.Abilities[5] == 1 ? Custom String("I") : Custom String("II")), Left, 905, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[1] ? Event Player : Null, Null, Null, Custom String("Headhunter {0}", + Event Player.Abilities[1] == 1 ? Custom String("I") : Custom String("II")), Left, 901, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[14] || Global.MaxHealthDone ? Event Player : Null, Null, Null, Custom String("+{0}% Health", + Global.MaxHealthDone + Event Player.Abilities[14] * 5), Left, 914, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[10] ? Event Player : Null, Null, Null, Custom String("Binding Heal {0}", + Event Player.Abilities[10] == 1 ? Custom String("I") : Custom String("II")), Left, 909, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[6] ? Event Player : Null, Null, Null, Custom String("Haste {0}", + Event Player.Abilities[6] == 1 ? Custom String("I") : Custom String("II")), Left, 906, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[2] ? Event Player : Null, Null, Null, Custom String("Ambush {0}", + Event Player.Abilities[2] == 1 ? Custom String("I") : Custom String("II")), Left, 902, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[15] ? Event Player : Null, Null, Null, Custom String("+{0}% Healing", + Event Player.Abilities[15] * 5), Left, 915, Color(White), Color(White), Color(Turquoise), Visible To and String, + Default Visibility); + Create HUD Text(Event Player.Abilities[11] ? Event Player : Null, Null, Null, Custom String("Resilience {0}", + Event Player.Abilities[11] == 1 ? Custom String("I") : Custom String("II")), Left, 910, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[7] ? Event Player : Null, Null, Null, Custom String("Heavy Impact {0}", + Event Player.Abilities[7] == 1 ? Custom String("I") : Custom String("II")), Left, 907, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[3] ? Event Player : Null, Null, Null, Custom String("Quick Fix {0}", + Event Player.Abilities[3] == 1 ? Custom String("I") : Custom String("II")), Left, 903, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Global.AutoRepair ? Event Player : Null, Null, Null, Custom String("{0} total Auto-Repair/5s", + Global.AutoRepair * (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5)), Left, 916, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[2][0], Event Player.HeroTalentText[2][1]), Top, 902, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("Hero Talent 2"), Left, 912, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[1][0], Event Player.HeroTalentText[1][1]), Top, 901, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("Hero Talent 1"), Left, 911, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[4] ? Event Player : Null, Null, Null, Custom String("Heavyweight {0}", + Event Player.Abilities[4] == 1 ? Custom String("I") : Custom String("II")), Left, 904, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + } +} + +rule("Rein Pin detect") +{ + event + { + Player Dealt Knockback; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 1); + Has Status(Victim, Stunned) == True; + } + + actions + { + Event Player.ReinPin = Victim; + Wait(1, Ignore Condition); + Event Player.ReinPin = Null; + } +} + +rule("Boss Rotation") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.activeBoss == True; + } + + actions + { + If(Global.bossRotation == 0 || Global.bossRotation == 3); + Global.bossRotation = 1; + Global.lastBoss[1] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 1); + Global.bossRotation = 2; + Global.lastBoss[2] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 2); + Global.bossRotation = 3; + Global.lastBoss[3] = Hero Of(Global.activeBoss); + End; + } +} + +rule("15 minutes hud") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 10; + } + + actions + { + Create HUD Text(All Players(Team 1), Global.activeBoss ? Custom String("Boss: {0}, HP: {1}/{2}", Hero Of(Global.activeBoss), + Health(Global.activeBoss), Max Health(Global.activeBoss)) : Custom String(""), Null, Null, Top, 900, Color(Red), Color(White), + Color(White), Visible To and String, Default Visibility); + } +} + +rule("debug") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + (Is Button Held(Event Player, Button(Primary Fire)) && Is Button Held(Event Player, Button(Crouch))) == True; + } + + actions + { + Global.TimeSec = 59; + } +} + +disabled rule("debug") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + } + + actions + { + Create HUD Text(Local Player, Custom String("{0}", Position Of(Local Player)), Null, Null, Left, 0, Color(Yellow), Color(White), + Color(White), Visible To and String, Default Visibility); + Set Status(Event Player, Null, Invincible, 9999); + Set Status(Event Player, Null, Phased Out, 9999); + } +} + +rule("ending 1 part 1") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + } + + actions + { + Big Message(All Players(Team 1), Custom String("Exfiltration available! (optional - ends the mode)")); + Create In-World Text(All Players(Team 1), Custom String( + "Exfiltration available! Gather here!\n{0}/{1} Players ready to exfiltrate!", Count Of(Filtered Array(All Players(Team 1), + Distance Between(Vector(186, 11, -46.500), Current Array Element) <= 9)), Count Of(All Players(Team 1))), Vector(186, 15, + -46.500), 1.200, Do Not Clip, Visible To and String, Color(Green), Default Visibility); + } +} + +rule("ending 1 part 2") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + Distance Between(Vector(186, 11, -46.500), All Players(Team 1)) <= 9; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GG! YOU DID IT!")); + Destroy All Dummy Bots; + Disable Movement Collision With Environment(All Players(Team 1), True); + Start Accelerating(All Players(Team 1), Up, 100, 5, To World, Direction Rate and Max Speed); + Wait(5, Ignore Condition); + Declare Team Victory(Team 1); + } +} + +rule("Team 1 (Ability): Second Wind save life") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[9] == True; + Event Player.secondWindActive == True; + Health(Event Player) == 1; + } + + actions + { + Small Message(All Players(All Teams), Custom String("{0} received a second wind!", Event Player)); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Green), Event Player, 1); + Clear Status(Event Player, Unkillable); + Set Player Health(Event Player, Max Health(Event Player)); + Event Player.lastSecondWind = 30; + Event Player.secondWindActive = 0; + } +} + +rule("Team 1 (Ability): Second Wind after buying") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[9] == True; + Event Player.secondWindActive == False; + Event Player.lastSecondWind == 0; + } + + actions + { + If(Random Integer(1, 100) > Event Player.Abilities[9] * 30); + Wait(30, Ignore Condition); + Loop; + End; + Set Status(Event Player, Null, Unkillable, 9999); + Event Player.secondWindActive = 1; + } +} + +rule("Team 1 (Ability): Second Wind counter") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Player.lastSecondWind > 0; + } + + actions + { + Wait(1, Ignore Condition); + Event Player.lastSecondWind -= 1; + Loop If Condition Is True; + } +} \ No newline at end of file diff --git a/defendTheCastleExtended/old_versions/c121.ow b/defendTheCastleExtended/old_versions/c121.ow new file mode 100644 index 0000000..f5803b4 --- /dev/null +++ b/defendTheCastleExtended/old_versions/c121.ow @@ -0,0 +1,9310 @@ +settings +{ + main + { + Description: "Defend Castle v0.6.c121 by HuKuTa94#2589 modified by ShuriZma#2349 - J1K6F (Code Version: v090) - Defend the gate, kill enemies and don't allow them to damage the gate! Torb, Brig and Rein can repair the gate but beware! You never know what the enemy might be hiding until now! Special Thanks to: Shingen#21859 for the Abilities, LemonAid#11644 for the Hero Talents & Josbird for teaching me about Menus! Find the Original Mode on: workshop.codes/BQEGS" + Mode Name: "Defend Castle v0.6.c121" + } + + lobby + { + Max Spectators: 0 + Max Team 1 Players: 4 + Max Team 2 Players: 0 + Return To Lobby: Never + Swap Teams After Match: No + } + + modes + { + Escort + { + enabled maps + { + Havana + } + } + + Team Deathmatch + { + enabled maps + { + } + } + + General + { + Game Mode Start: Immediately + Spawn Health Packs: Disabled + } + } + + workshop + { + Ana can nano herself even if there are other players only if no player targeted: On + Story Heroes: Off + } + + extensions + { + Beam Effects + Kinetic Explosion Effects + Explosion Sounds + Play More Effects + Spawn More Dummy Bots + } +} + +variables +{ + global: + 0: GatePosition + 1: ZenSpawnPositions + 2: SpawnPositionMaxId + 3: LoopIterator1 + 4: BigBossSpawnPositions + 5: PlayerSpawnPositions + 6: GateHealthChase + 7: GateHealth + 8: GateMaxHealth + 9: GateProgressBarColorCurrent + 10: GateProgressBarColorComponent + 11: GateHealthEvent + 12: BastionTargetPositions + 13: SniperPositions + 14: BallSpawnPositions + 15: ZenRespawnTime + 16: TimeMin + 17: TimeSec + 18: DefaultCurrentBot + 19: DefaultHeroBotsPool + 20: DefaultHeroBotsPoolCurrentId + 21: IsDebug + 22: BotOrisaParent + 23: IsStoryHeroes + 24: BotOrisaChild + 25: GateRepairPosition + 26: BotOrisaTargetPosition + 27: BotEchoRespawnPosition + 28: BotEchoTeleportPositions + 29: UpgradeGateMaxHealthValue + 30: UpgradeGateMaxHealthHudId + 31: UpgradePlayerMaxHealthValue + 32: UpgradePlayerMaxHealthHudId + 33: UpgradeCriticalDamageValue + 34: UpgradeCriticalDamageHudId + 35: UpgradeMaxAmmoValue + 36: UpgradeMaxAmmoHudId + 37: UpgradeMaxAmmoMaxValue + 38: UpgradePlayerMaxHealthMaxValue + 39: UpgradeCriticalDamageMaxValue + 40: UpgradeGateMaxHealthMaxValue + 41: DamageDone + 42: IsDebugAINavigation + 43: GameLogicCountOfUniqueHeroes + 44: IsNewWaveGameLogicProcessing + 45: AutoRepair + 46: UpgradePerkSharpshooterValue + 47: Perk + 48: MaxHealthDone + 49: StartMoney + 50: Time5Min + 51: SelfNanoWorkshopSetting + 52: ShopCamPos + 53: ShopBasePos + 54: ShopPosAngle + 55: activeBoss + 56: bossTrigger + 57: bossRotation + 58: lastBoss + 59: Time10Min + 60: MoneyMult + 61: challengeCount + 62: UpgradeBossHealthValue + 112: AllPos + 113: AllDir + 114: firstpos + 115: secondpos + 116: firstpoint2 + 117: secondpoint2 + 118: second + 119: z + 120: Wall_ID + 121: showwalls + 122: is_Grounded + 123: g_beamType + 124: x + 125: NodePositions + 126: NodeConnections + 127: DistanceMatrix + + player: + 0: BotSeePlayer + 1: BotDoesUniqueBehaviour + 2: BotEffects + 3: BotRayCastHitPosition + 4: BotEventPosition + 5: CurrentHero + 6: IsDead + 7: IsRespawning + 8: BotBastionArtilleryDidShotsCount + 9: BotCounter + 10: HasBadStatus + 11: EventHealth + 12: HealOverTimeId + 13: BotIsOrisaChild + 14: BotEchoCapturedPlayer + 15: BotPlayersInRadius + 16: BotLoopIterator2 + 17: BotWidowShotTime + 18: BotWidowTeleportTime + 19: IsNanoed + 20: AbilityHUD + 21: Lucio_Dash_Active + 22: Lucio_Dash_Icon + 23: AnaEntityID + 24: Abilities + 25: Money + 26: HeroTalentText + 27: DamageDealt + 28: PlayerHealth + 29: AbilityCountdown + 30: HP_Pool + 31: Effects_ + 32: Ability_Projectile1 + 33: Ability_End + 34: Storm_Projectile + 35: Storm_EndPoint + 36: Storm_Effects + 37: Feared_until + 38: Modification_Damage + 39: Ability_Projectile2 + 40: Ability_Position + 41: Chain_Reaction_On + 42: Chain_Reaction_Immune + 43: Ability_Active + 44: Ability_Resource + 45: secondWindActive + 46: isInMenu + 47: ReinPin + 48: PlayerFacing + 49: isBoss + 50: Gen_Direction + 51: Gen_Available + 52: Ability_Player + 53: Ability_Countdown + 54: lastSecondWind + 105: filterpos + 106: lastsavedpos + 107: closestbodypos + 108: fullbodypos + 109: prevpos_intersection + 110: active_wall + 111: closestwall + 112: x + 113: intersection_length + 114: thickness + 115: BotCancelPathFinding + 116: BotLoopIterator1 + 117: BotTempArray + 118: BotTargetPlayer + 119: BotTargetPosition + 120: BotClosestNodeIdToTarget + 121: BotClosestNodeIdToBot + 122: BotPrevNodeId + 123: BotNextNodeId + 124: BotNextNodePosition + 125: BotCurrentDistanceToTarget + 126: BotShortestDistanceToTarget + 127: BotIsPathFinding +} + +subroutines +{ + 0: BotBastionArtilleryDamage + 1: BotBastionFlameGunDamage + 2: BotBastionRespawn + 3: GateProgressBarColor + 4: BotZenyattaRespawn + 5: BotWidowRespawn + 6: BotBallRespawn + 7: GameLogicAddNextHeroInGame + 8: BotOrisaRespawn + 9: BotLandingFromSky + 10: BotEchoRespawn + 11: BotEchoDetachPlayer + 12: BotEchoFlyToPlayer + 13: BotEchoFlyToPortal + 14: GameLogicSetBotProperties + 15: DisablePlayer + 16: BotApearFromUnderground + 17: BotReinRespawn + 18: PlayerInit + 19: BotInit + 20: PlayerRespawn + 21: BotRespawn + 22: BotWidowBadStatus + 23: GameLogicWave0 + 24: Refund + 25: EnablePlayer + 26: GateRepair + 124: BotStartPathFinding + 125: BotGetClosestNodeIdToTarget + 126: BotGetNextNodeIdAndPosition + 127: BotResetPathFinding +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("MAP: HAVANA") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Havana); + } + + actions + { + Global.NodePositions = Array(Vector(147.588, 6.425, -46.749), Vector(136.181, 6.425, -57.159), Vector(130.189, 6.425, -63.781), + Vector(123.305, 6.425, -57.983), Vector(125.678, 6.504, -46.633), Vector(114.485, 7.471, -46.699), Vector(138.743, 6.425, + -32.974), Vector(126.498, 6.425, -39.920), Vector(124.572, 10.434, -34.300), Vector(138.605, 5.359, -18.647), Vector(119.009, + 2.331, -31.024), Vector(121.138, 5.228, -19.933), Vector(126.722, 6.425, -29.505), Vector(102.762, 3.157, -33.609), Vector( + 76.030, 7.418, -74.087), Vector(83.720, 9.425, -33.744), Vector(97.439, 7.238, -42.379), Vector(86.252, 12.416, -47.261), + Vector(65.178, 11.425, -73.187), Vector(97.466, 7.269, -50.596), Vector(113.039, 7.424, -37.337), Vector(106.179, 7.450, + -46.143), Vector(90.086, 7.411, -44.653), Vector(78.752, 7.418, -62.140), Vector(82.124, 7.428, -44.229), Vector(90.675, 7.231, + -51.234), Vector(85.717, 4.692, -63.446), Vector(90.830, 4.330, -70.697), Vector(102.425, 2.387, -72.817), Vector(81.443, + 4.425, -81.648), Vector(70.743, 6.418, -81.495), Vector(69.738, 6.419, -96.344), Vector(127.586, 12.643, -63.344), Vector( + 118.911, 13.468, -58.008), Vector(102.885, 1.092, -56.579), Vector(100.009, 2.967, -67.139), Vector(106.703, 0.465, -44.628), + Vector(81.695, 7.418, -52.140), Vector(126.979, 12.393, -55.079), Vector(153.720, 18.578, -21.745), Vector(155.301, 18.619, + -17.595), Vector(133.043, 10.425, -26.625), Vector(114.646, 7.278, -57.336), Vector(95.160, 3.688, -81.194), Vector(78.456, + 5.418, -93.581), Vector(75.455, 5.418, -101.492), Vector(148.071, 9.432, -32.123), Vector(146.706, 9.425, -27.858), Vector( + 144.273, 9.445, -63.119), Vector(144.278, 9.454, -58.447)); + Global.NodeConnections = Array(Array(1, 6, 4, 7), Array(2, 1, 4, 6, 7, 0, 49), Array(1, 3), Array(2, 4, 42), Array(3, 1, 5, 7, 6, + 1, 0), Array(4, 7, 20, 21, 19, 16, 42), Array(7, 1, 4, 1, 9, 12, 0, 46), Array(4, 5, 6, 1, 1, 12, 0), Array(7, 41), Array(6, + 11), Array(11, 13), Array(9, 10, 13), Array(6, 7, 10), Array(10, 16, 36), Array(18, 23, 30), Array(17, 24), Array(13, 19, 22, + 21, 25, 5), Array(15, 22, 25, 23), Array(14), Array(16, 21, 22, 26, 27, 35, 25, 5), Array(5, 13, 10), Array(19, 16, 5, 13, 22, + 34), Array(16, 19, 21, 24, 25), Array(14, 25, 26, 37), Array(22, 15, 37), Array(23, 22, 19, 16, 26, 27, 35, 37), Array(25, 19, + 27, 35, 29), Array(19, 26, 25, 29, 35, 43), Array(35, 34, 43), Array(27, 26, 30, 43, 44), Array(29, 14, 31), Array(30, 29, 45), + Array(33, 38, 1, 48), Array(32, 38, 42), Array(35, 36, 28), Array(28, 19, 25, 27, 26, 34), Array(13, 34), Array(25, 23, 24), + Array(5, 4, 1, 6, 1, 32, 33, 0), Array(40), Array(39), Array(6, 8, 47, 46), Array(3, 5, 34), Array(28, 27, 29, 44), Array(29, + 43, 45), Array(44, 31), Array(6, 47), Array(46, 41), Array(49, 32), Array(1, 0, 6, 48)); + Global.DistanceMatrix = Array(Array(0, 1, 2, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, + 4, 5, 4, 4, 5, 5, 5, 0, 0, 4, 3, 5, 6, 7, 2, 3, 3, 2), Array(1, 0, 1, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, + 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 3, 4, 4, 4, 5, 5, 4, 0, 0, 4, 3, 5, 6, 7, 2, 3, 2, 1), Array(2, 1, 0, 1, 2, 3, 2, 2, 6, 3, 4, 4, + 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 4, 6, 7, 8, 4, 5, 3, 4, 4, 6, 5, 0, 0, 5, 2, 5, 6, 7, 3, 4, 3, 2), Array(2, 2, + 1, 0, 1, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, 5, 6, 2, 3, 3, 5, 6, 0, 0, 5, 1, 4, + 5, 6, 3, 4, 4, 3), Array(1, 1, 2, 1, 0, 1, 1, 1, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, + 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, 2, 3, 3, 2), Array(2, 2, 3, 2, 1, 0, 2, 1, 6, 3, 2, 3, 2, 2, 4, 4, 1, 5, 5, 1, 1, 1, 2, 3, + 3, 2, 2, 2, 3, 3, 4, 5, 5, 6, 2, 2, 3, 3, 6, 0, 0, 5, 1, 3, 4, 5, 3, 4, 4, 3), Array(1, 1, 2, 2, 1, 2, 0, 1, 4, 1, 2, 2, 1, 3, + 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 4, 5, 4, 4, 4, 5, 5, 0, 0, 3, 3, 5, 6, 7, 1, 2, 3, 2), Array(1, 1, 2, 2, + 1, 1, 1, 0, 5, 2, 2, 3, 1, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, + 2, 3, 3, 2), Array(2, 2, 3, 3, 2, 2, 2, 1, 0, 3, 3, 4, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, + 5, 5, 6, 0, 0, 1, 3, 5, 6, 7, 2, 2, 4, 3), Array(2, 2, 3, 3, 2, 3, 1, 2, 5, 0, 2, 1, 2, 2, 6, 6, 3, 7, 7, 4, 4, 4, 4, 5, 5, 4, + 5, 5, 5, 6, 7, 8, 5, 6, 4, 5, 3, 5, 6, 0, 0, 4, 4, 6, 7, 8, 2, 3, 4, 3), Array(4, 4, 5, 5, 4, 3, 3, 4, 7, 2, 0, 1, 4, 1, 5, 5, + 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 7, 8, 3, 4, 2, 4, 8, 0, 0, 6, 4, 5, 6, 7, 4, 5, 6, 5), Array(3, 3, 4, 4, 3, 3, + 2, 3, 6, 1, 1, 0, 3, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 6, 7, 3, 4, 2, 4, 7, 0, 0, 5, 4, 5, 6, 7, 3, 4, + 5, 4), Array(2, 2, 3, 3, 2, 2, 1, 1, 5, 2, 1, 2, 0, 2, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, 3, 5, + 6, 0, 0, 4, 3, 5, 6, 7, 2, 3, 4, 3), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 3, 1, 2, 4, 0, 4, 4, 1, 5, 5, 2, 3, 2, 2, 3, 3, 2, 3, 3, + 3, 4, 5, 6, 7, 8, 2, 3, 1, 3, 8, 0, 0, 7, 3, 4, 5, 6, 5, 6, 6, 5), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 5, 6, 6, 4, 0, 4, 3, 5, + 1, 3, 5, 4, 3, 1, 3, 2, 2, 3, 4, 2, 1, 2, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 3, 3, 3, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, + 5, 10, 7, 5, 6, 6, 4, 3, 0, 3, 1, 4, 3, 5, 3, 2, 2, 1, 2, 3, 3, 4, 4, 4, 5, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 4, 5, 6, 7, 8, + 8, 7), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 3, 3, 0, 4, 4, 1, 2, 1, 1, 2, 2, 1, 2, 2, 3, 3, 4, 5, 6, 7, 2, 2, 2, 2, + 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 1, 2, 0, 3, 2, 4, 2, 1, 1, 2, 1, 2, 2, + 3, 3, 3, 4, 8, 9, 3, 2, 4, 2, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 6, 7, 7, 5, 1, 5, 4, 6, + 0, 4, 6, 5, 4, 2, 4, 3, 3, 4, 5, 3, 2, 3, 10, 11, 5, 4, 6, 3, 11, 0, 0, 10, 6, 4, 4, 4, 8, 9, 9, 8), Array(3, 3, 4, 3, 2, 1, 3, + 2, 7, 4, 3, 4, 3, 2, 3, 3, 1, 4, 4, 0, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 3, 4, 6, 7, 2, 1, 3, 2, 7, 0, 0, 6, 2, 2, 3, 4, 4, 5, 5, + 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 3, 1, 2, 3, 1, 5, 5, 2, 6, 6, 2, 0, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 6, 7, 3, 3, 2, 4, 7, + 0, 0, 6, 2, 4, 5, 6, 4, 5, 5, 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 4, 3, 1, 4, 5, 1, 2, 0, 1, 3, 2, 2, 2, 2, 2, + 3, 4, 5, 6, 7, 1, 2, 2, 3, 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 3, 2, 1, 3, 4, + 1, 3, 1, 0, 2, 1, 1, 2, 2, 3, 3, 4, 5, 7, 8, 2, 2, 3, 2, 8, 0, 0, 7, 3, 3, 4, 5, 5, 6, 6, 5), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, + 6, 4, 5, 5, 3, 1, 3, 2, 4, 2, 2, 4, 3, 2, 0, 2, 1, 1, 2, 3, 2, 2, 3, 8, 9, 3, 2, 4, 1, 9, 0, 0, 8, 4, 3, 3, 4, 6, 7, 7, 6), + Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 3, 1, 2, 2, 4, 2, 4, 2, 1, 2, 0, 2, 3, 3, 4, 4, 4, 5, 8, 9, 3, 3, 4, 1, 9, 0, + 0, 8, 4, 4, 5, 6, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 2, 3, 1, 4, 3, 1, 3, 2, 1, 1, 2, 0, 1, 1, 2, 2, + 3, 4, 7, 8, 2, 1, 3, 1, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, + 3, 2, 2, 2, 3, 1, 0, 1, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 2, 2, 3, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, + 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 0, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 1, 2, 3, 5, 6, 6, 5), Array( + 5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 4, 5, 3, 6, 5, 2, 4, 3, 3, 3, 4, 2, 2, 2, 0, 2, 3, 4, 8, 9, 1, 1, 2, 3, 9, 0, 0, 8, + 4, 1, 2, 3, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 2, 5, 3, 6, 3, 2, 4, 3, 3, 3, 4, 2, 1, 1, 2, 0, 1, 2, + 8, 9, 3, 2, 4, 3, 9, 0, 0, 8, 4, 1, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 1, 5, 4, 6, 2, 3, 5, 4, + 4, 2, 4, 3, 2, 2, 3, 1, 0, 1, 9, 10, 4, 3, 5, 3, 10, 0, 0, 9, 5, 2, 2, 2, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, + 7, 6, 5, 2, 6, 4, 7, 3, 3, 5, 4, 4, 3, 5, 3, 2, 2, 3, 1, 1, 0, 9, 10, 4, 3, 5, 4, 10, 0, 0, 9, 5, 2, 2, 1, 7, 8, 8, 7), Array( + 2, 1, 2, 3, 2, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 4, 5, 6, 7, 0, 1, 3, 4, 4, 5, 1, 0, 0, 5, + 2, 5, 6, 7, 3, 4, 1, 2), Array(2, 2, 3, 2, 2, 2, 2, 3, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, + 1, 0, 2, 3, 3, 5, 1, 0, 0, 5, 1, 4, 5, 6, 3, 4, 2, 3), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 5, 3, 4, 5, 2, 4, 5, 3, 6, 5, 2, 4, 3, + 3, 3, 4, 2, 2, 2, 1, 3, 4, 5, 8, 9, 0, 1, 1, 3, 9, 0, 0, 8, 4, 2, 3, 4, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, + 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 1, 1, 2, 3, 4, 7, 8, 1, 0, 2, 2, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(5, 5, + 6, 5, 4, 3, 5, 4, 9, 4, 2, 3, 5, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 8, 9, 1, 2, 0, 4, 9, 0, 0, 8, 4, 3, + 4, 5, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 2, 2, 3, 3, 2, 4, 3, 2, 1, 1, 1, 2, 2, 3, 3, 3, 4, 8, 9, + 3, 2, 4, 0, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(1, 1, 2, 2, 1, 1, 1, 2, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, + 4, 3, 3, 3, 4, 4, 5, 6, 1, 1, 3, 3, 4, 4, 0, 0, 0, 4, 2, 4, 5, 6, 2, 3, 2, 2), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(2, 2, 3, 3, 2, 3, 1, 2, 1, 2, 3, 3, 2, + 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 0, 4, 6, 7, 8, 1, 1, 4, 3), Array(3, 3, 2, + 1, 2, 1, 3, 2, 7, 4, 3, 4, 3, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 6, 7, 1, 2, 2, 4, 7, 0, 0, 6, 0, 3, 4, + 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 3, 5, 3, 6, 4, 2, 4, 3, 3, 3, 4, 2, 2, 1, 1, 1, 2, 3, 8, 9, 2, + 2, 3, 3, 9, 0, 0, 8, 4, 0, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 3, 6, 4, 7, 4, 3, 5, 4, 4, 4, 5, + 3, 2, 2, 2, 1, 2, 2, 9, 10, 3, 3, 4, 4, 10, 0, 0, 9, 5, 1, 0, 1, 7, 8, 8, 7), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 7, 8, 7, 6, + 3, 7, 5, 8, 4, 4, 6, 5, 5, 4, 6, 4, 3, 3, 3, 2, 2, 1, 10, 11, 4, 4, 5, 5, 11, 0, 0, 10, 6, 2, 1, 0, 8, 9, 9, 8), Array(2, 2, 3, + 3, 2, 3, 1, 2, 3, 2, 3, 3, 2, 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 2, 4, 6, 7, + 8, 0, 1, 4, 3), Array(3, 3, 4, 4, 3, 4, 2, 3, 2, 3, 4, 4, 3, 5, 8, 8, 5, 9, 9, 5, 5, 5, 6, 7, 7, 6, 6, 6, 7, 7, 8, 9, 6, 7, 6, + 6, 6, 7, 7, 0, 0, 1, 5, 7, 8, 9, 1, 0, 5, 4), Array(2, 2, 3, 4, 3, 3, 2, 3, 6, 3, 4, 4, 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, + 5, 5, 5, 5, 6, 7, 8, 1, 2, 4, 5, 5, 6, 2, 0, 0, 5, 3, 6, 7, 8, 3, 4, 0, 1), Array(1, 1, 2, 3, 2, 3, 1, 2, 5, 2, 3, 3, 2, 4, 7, + 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 2, 3, 5, 5, 5, 6, 3, 0, 0, 4, 4, 6, 7, 8, 2, 3, 1)); + } +} + +rule("SUBROUTINE: BOT - RESET PATH FINDING") +{ + event + { + Subroutine; + BotResetPathFinding; + } + + actions + { + Event Player.BotTargetPlayer = -1; + Event Player.BotTargetPosition = -1; + Event Player.BotPrevNodeId = -1; + Event Player.BotClosestNodeIdToTarget = -1; + Event Player.BotNextNodeId = -1; + Event Player.BotNextNodePosition = -1; + Event Player.BotIsPathFinding = False; + Event Player.BotCancelPathFinding = False; + Stop Throttle In Direction(Event Player); + disabled Stop Facing(Event Player); + } +} + +rule("SUBROUTINE: BOT - START PATH FINDING") +{ + event + { + Subroutine; + BotStartPathFinding; + } + + actions + { + disabled Abort If(Event Player.BotIsPathFinding == True); + Call Subroutine(BotGetNextNodeIdAndPosition); + disabled Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Event Player.BotIsPathFinding = True; + } +} + +rule("SUBROUTINE: BOT - GET NEXT NODE ID AND POSITION") +{ + event + { + Subroutine; + BotGetNextNodeIdAndPosition; + } + + actions + { + "BOT JUST START FOLLOW PATH OR LOST NEXT NODE" + If(Event Player.BotPrevNodeId == -1); + Event Player.BotClosestNodeIdToBot = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array(Global.NodePositions, + Is In Line of Sight(Position Of(Event Player) + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS) == True), + Distance Between(Position Of(Event Player), Current Array Element))[0]); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + "NEXT NODE IS TARGET (DISTANCE TO TARGET NODE = 1)" + If(Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1); + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToTarget; + "CHECK CONNECTIONS OF REACHED NODE" + Else; + Event Player.BotShortestDistanceToTarget = 999; + Event Player.BotCurrentDistanceToTarget = Event Player.BotShortestDistanceToTarget; + Event Player.BotTempArray = Global.NodeConnections[Event Player.BotClosestNodeIdToBot]; + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotTempArray), 1); + Event Player.BotCurrentDistanceToTarget = Global.DistanceMatrix[Event Player.BotTempArray[Event Player.BotLoopIterator1]][Event Player.BotClosestNodeIdToTarget]; + If(Event Player.BotCurrentDistanceToTarget < Event Player.BotShortestDistanceToTarget); + Event Player.BotShortestDistanceToTarget = Event Player.BotCurrentDistanceToTarget; + Event Player.BotNextNodeId = Event Player.BotTempArray[Event Player.BotLoopIterator1]; + End; + End; + End; + "NEXT NODE IS HIGHER THAN BOT AND BOT DIDN'T REACH CLOSEST NODE" + If(Y Component Of(Position Of(Event Player)) - Y Component Of(Global.NodePositions[Event Player.BotNextNodeId]) + < -3 && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + "BOT CAN SEE TARGET POSITION AND NEXT NODE IS TARGET" + Else If( + Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1 && Is In Line of Sight( + Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotTargetPosition + Vector(0, 2, 0), Barriers Do Not Block LOS)); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Abort; + "BOT CAN'T SEE NEXT NODE AND PREV NODE != REACHED NODE" + Else If(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), + Global.NodePositions[Event Player.BotNextNodeId] + Vector(0, 2, 0), Barriers Do Not Block LOS) + == False && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + End; + Event Player.BotNextNodePosition = Global.NodePositions[Event Player.BotNextNodeId]; + } +} + +rule("SUBROUTINE: BOT - GET CLOSEST NODE ID AND POSITION TO TARGET") +{ + event + { + Subroutine; + BotGetClosestNodeIdToTarget; + } + + actions + { + Event Player.BotTargetPosition = Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Event Player.BotTargetPosition; + Event Player.BotClosestNodeIdToTarget = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array( + Global.NodePositions, Is In Line of Sight(Event Player.BotTargetPosition + Vector(0, 2, 0), Current Array Element, + Barriers Do Not Block LOS) == True), Distance Between(Event Player.BotTargetPosition, Current Array Element))[0]); + } +} + +rule("BOT: PATH FINDING - START") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + (Event Player.BotTargetPosition != -1 || Event Player.BotTargetPlayer != -1) == True; + } + + actions + { + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - CANCEL") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotCancelPathFinding == True; + } + + actions + { + Start Rule(BotResetPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - LOST THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + (Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotNextNodePosition + Vector(0, 2.500, 0), + Barriers Do Not Block LOS) == False && Speed Of In Direction(Event Player, Throttle Of(Event Player)) < 2) == True; + } + + actions + { + Wait(0.500, Abort When False); + "RESET PREV NODE ID TO INFORM BOT THAT IT LOST NEXT NODE" + Event Player.BotPrevNodeId = -1; + "TRY FIND NEW NEXT NODE" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodeId), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +rule("BOT: PATH FINDING - REACHED THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotClosestNodeIdToTarget >= 0; + (Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotNextNodePosition), 0, Z Component Of(Event Player.BotNextNodePosition))) < 0.850) == True; + } + + actions + { + Event Player.BotPrevNodeId = Event Player.BotNextNodeId; + Event Player.BotClosestNodeIdToBot = Event Player.BotNextNodeId; + "BOT'S TARGET IS PLAYER" + If(Event Player.BotTargetPlayer != -1); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + Event Player.BotCurrentDistanceToTarget = Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of( + Position Of(Event Player))), Vector(X Component Of(Event Player.BotTargetPosition), 0, Z Component Of( + Event Player.BotTargetPosition))); + "BOT REACHED THE TARGET NODE OR TARGET POSITION" + If(Event Player.BotNextNodeId == Event Player.BotClosestNodeIdToTarget || Event Player.BotCurrentDistanceToTarget <= 0.850); + "BOT DIDN'T REACH TARGET POSITION" + If(Event Player.BotCurrentDistanceToTarget > 0.850); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Skip(6); + "BOT REACHED TARGET" + Else; + Call Subroutine(BotResetPathFinding); + Abort; + End; + End; + "CONTINUE FOLLOW PATH" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: GAME MODE INIT - WORKSHOP SETTINGS") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.IsDebug = False; + Global.IsDebugAINavigation = False; + Global.GateMaxHealth = Workshop Setting Integer(Custom String("DEFEND CASTLE"), Custom String("GATE MAX HEALTH"), 500, 100, 1000, + 0); + Global.IsStoryHeroes = Workshop Setting Toggle(Custom String("DEFEND CASTLE"), Custom String("Story Heroes"), True, 0); + Global.SelfNanoWorkshopSetting = Workshop Setting Toggle(Custom String("Ana Self Nano"), Custom String( + "Ana can nano herself even if there are other players (only if no player targeted)"), False, 0); + } +} + +rule("GLOBAL: GAME MODE INIT - COMMON PROPERTIES") +{ + event + { + Ongoing - Global; + } + + actions + { + Create HUD Text(All Players(All Teams), Null, Null, Custom String( + "DEFEND CASTLE v0.6.c121 BY HUKUTA94#2589\r\nmodified by ShuriZma#2349\r\nDiscord: discord.shurizma.de\r\n{0}", Custom String( + "Special Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents &\nJosbird for teaching me about Menus{0}", + Custom String("{0}", Custom String(" \nPS: SHINGEN PLS COME BACK")))), Right, -1000, Null, Null, Color(White), Visible To, + Default Visibility); + Global.GateRepairPosition = Vector(153, 8, -46.500); + Global.GatePosition = Vector(148.800, 6, -46.400); + Global.BallSpawnPositions = Array(Vector(104, 7, -46), Vector(106, 2, -31)); + Global.SniperPositions = Array(Vector(154, 18, -22.600), Vector(86, 12, -46.600), Vector(80.880, 11.300, -71.600), Vector(98, 9, + -19)); + Global.ZenSpawnPositions = Array(Vector(79.500, 5, -100), Vector(90, 4, -88), Vector(65, 11, -70), Vector(85, 4, -68), Vector(96, + 2, -73), Vector(84, 7, -47), Vector(95, 9, -34), Vector(108, 1.700, -28), Vector(113, 7, -37), Vector(123, 5, -19), Vector(144, + 5, -19), Vector(123, 6, -39), Vector(123, 6, -61), Vector(129, 6, -30.500), Vector(135, 6, -63)); + Global.PlayerSpawnPositions = Array(Vector(153.300, 10, -63.800), Vector(153.300, 10, -61.700), Vector(153.300, 10, -31.700), + Vector(153.300, 10, -29.600)); + Global.BigBossSpawnPositions = Array(Vector(78, 4, -84), Vector(95, 4, -82)); + Global.BastionTargetPositions = Array(Vector(131, 12, -62), Vector(115, 7, -46), Objective Position(2), Vector(136, 10, -27)); + Global.SpawnPositionMaxId = 2; + Global.BotOrisaTargetPosition = Vector(104, 7, -46); + Global.BotEchoRespawnPosition = Vector(130, 23, -44); + Global.BotEchoTeleportPositions = Array(Vector(88, 23, -79), Vector(108, 18, -27)); + Global.DefaultHeroBotsPool = Array(Hero(Zenyatta), Hero(Widowmaker), Null, Hero(Bastion), Hero(Echo), Hero(Bastion)); + Global.ZenRespawnTime = 10; + Global.GameLogicCountOfUniqueHeroes = 5; + Global.lastBoss = Array(Null, Null, Null, Null); + Create Effect(All Players(Team 1), Ring, Color(Sky Blue), Vector(186, 11, -46.500), 9, Visible To Position and Radius); + } +} + +disabled rule("PLAYER: DEBUG - PRESS INTERACT") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Host Player == True; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + disabled Modify Player Score(Event Player, 10); + disabled Global.GateHealth -= 5; + disabled Start Rule(GateProgressBarColor, Restart Rule); + Global.TimeSec = 59; + Set Status(Event Player, Null, Phased Out, 9999); + disabled Set Ultimate Charge(Event Player, 100); + disabled Kill(Event Player, Null); + disabled Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: DEBUG - AI NAVIGATION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.IsDebugAINavigation == True; + } + + actions + { + For Global Variable(LoopIterator1, 0, Count Of(Global.NodePositions), 1); + Create Effect(All Players(All Teams), Sphere, Color(Red), Global.NodePositions[Global.LoopIterator1], 0.850, Visible To); + Create In-World Text(All Players(All Teams), Custom String("NODE {0}", Global.LoopIterator1), + Global.NodePositions[Global.LoopIterator1], 1.200, Clip Against Surfaces, Visible To, Color(White), Default Visibility); + End; + } +} + +disabled rule("GLOBAL: DEBUG - CREATE BOTS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + Create Dummy Bot(Hero(Bastion), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + Create Dummy Bot(Hero(Orisa), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +disabled rule("PLAYER: DEBUG - INFOS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + Host Player == Event Player; + Has Spawned(Event Player) == True; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Create HUD Text(Event Player, Custom String("POS {0}\r\nFACING {1}", Position Of(Event Player), Facing Direction Of(Event Player)), + Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + Create HUD Text(Event Player, Custom String("SERVER PERFORMANCE\r\nLOAD {0}%\r\nPEAK {1}%\r\nAVG {2}%", Server Load, + Server Load Peak, Server Load Average), Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create Progress Bar HUD Text(Event Player, 45, Custom String("45 / 100 KILLS"), Left, -99, Color(Blue), Color(White), + Visible To Values and Color, Default Visibility); + disabled Create HUD Text(Event Player, Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Null, Custom String( + "LEVEL 1 - 50 AMMO CLIP"), Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + "ЭФФЕКТ С ОФФСЕТОМ ОТ ПОЗИЦИИ ГЛАЗ" + disabled Create Beam Effect(All Players(All Teams), Bad Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + Facing Direction Of( + Event Player) * 3, Eye Position(Event Player) + Facing Direction Of(Event Player) * 50, Color(Purple), + Visible To Position and Radius); + } +} + +disabled rule("=== TEAM UPGRADES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: TEAM UPGRADES - INIT") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.UpgradeMaxAmmoMaxValue[0] = 250; + Global.UpgradeMaxAmmoMaxValue[1] = 500; + Global.UpgradeMaxAmmoMaxValue[2] = 1000; + Global.UpgradeCriticalDamageMaxValue[0] = 10; + Global.UpgradeCriticalDamageMaxValue[1] = 10; + Global.UpgradeCriticalDamageMaxValue[2] = 10; + Global.UpgradePlayerMaxHealthMaxValue[0] = 2500; + Global.UpgradePlayerMaxHealthMaxValue[1] = 5000; + Global.UpgradePlayerMaxHealthMaxValue[2] = 10000; + Global.UpgradeGateMaxHealthMaxValue[0] = Round To Integer(Global.GateMaxHealth + Global.GateMaxHealth * 0.500, Up); + Global.UpgradeGateMaxHealthMaxValue[1] = Global.UpgradeGateMaxHealthMaxValue[0] + Global.UpgradeGateMaxHealthMaxValue[0]; + Global.UpgradeGateMaxHealthMaxValue[2] = Global.UpgradeGateMaxHealthMaxValue[1] + Global.UpgradeGateMaxHealthMaxValue[1]; + Abort If(Global.IsDebug == False); + Global.UpgradeMaxAmmoMaxValue[0] = 1; + Global.UpgradeCriticalDamageMaxValue[0] = 1; + Global.UpgradePlayerMaxHealthMaxValue[0] = 1; + Global.UpgradeGateMaxHealthMaxValue[0] = 1; + Global.UpgradeMaxAmmoMaxValue[1] = 1; + Global.UpgradeCriticalDamageMaxValue[1] = 1; + Global.UpgradePlayerMaxHealthMaxValue[1] = 1; + Global.UpgradeGateMaxHealthMaxValue[1] = 1; + Global.UpgradeMaxAmmoMaxValue[2] = 1; + Global.UpgradeCriticalDamageMaxValue[2] = 1; + Global.UpgradePlayerMaxHealthMaxValue[2] = 1; + Global.UpgradeGateMaxHealthMaxValue[2] = 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GATE'S MAX HEALTH UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Global.GateMaxHealth = Global.UpgradeGateMaxHealthMaxValue[0]; + Global.GateHealth = Global.GateMaxHealth; + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Right, 1, Color( + Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X GATE REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[1]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X GATE REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X GATE REPAIR"), Right, 2, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X AUTO-REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[2]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[2] = Last Text ID; + Global.GateHealth = Global.GateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 3 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X AUTO-REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X AUTO-REPAIR"), Right, 3, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.UpgradeGateMaxHealthHudId[2] = Last Text ID; + Global.GateHealth = Global.GateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - PLAYER'S MAX HEALTH - DEALT HEALING") +{ + event + { + Player Received Healing; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + disabled Healer != Event Player; + Global.UpgradePlayerMaxHealthValue < Global.UpgradePlayerMaxHealthMaxValue[2]; + } + + actions + { + Global.UpgradePlayerMaxHealthValue += Event Healing; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +50%"), Right, 4, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("Up You Go: You respawn twice as fast"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[1]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.MaxHealthDone = 50; + All Players(Team 1).PlayerHealth = 100 + Global.MaxHealthDone + All Players(Team 1).Abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).PlayerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK UP YOU GO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("UP YOU GO UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String("Up You Go"), + Right, 5, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +100%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[2]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[2] = Last Text ID; + Set Respawn Max Time(All Players(Team 1), 5); + Heal(All Players(Team 1), Null, 9999); + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.Perk[2] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[17] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH 2 UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +100%"), Right, 6, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[2] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.MaxHealthDone = 150; + All Players(Team 1).PlayerHealth = 100 + Global.MaxHealthDone + All Players(Team 1).Abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).PlayerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Hero Of(Victim) == Hero(Widowmaker); + Global.UpgradeCriticalDamageValue < Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradeCriticalDamageValue += 1; + Small Message(All Players(Team 1), Custom String("CRITICAL DAMAGE CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - CRITICAL DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("CRITICAL DAMAGE 150% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "CRITICAL DAMAGE 150%"), Right, 7, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String( + "Sharpshooter: Deal 40% more damage to enemies that are further than 15 meters away"), Custom String("KILL ECHO {0}/{1}", + Global.UpgradePerkSharpshooterValue, Global.UpgradeCriticalDamageMaxValue[1]), Left, 14, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - UNLOCKED") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.500); + } +} + +rule("PLAYER: UPGRADE - PERK SHARPSHOOTER - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Echo); + Global.UpgradePerkSharpshooterValue < Global.UpgradeCriticalDamageMaxValue[1]; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradePerkSharpshooterValue += 1; + Small Message(All Players(Team 1), Custom String("SHARPSHOOTER CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - PERK SHARPSHOOTER - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("SHARPSHOOTER UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Sharpshooter"), Right, 8, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("-10% BOSS HEALTH"), Custom String("KILL Bosses {0}/{1}", + Global.UpgradeBossHealthValue, Global.UpgradeCriticalDamageMaxValue[2]), Left, 14, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[2] = Last Text ID; + Global.Perk[0] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[18] = Last Text ID; + Global.challengeCount += 1; + } +} + +disabled rule("PLAYER: UPGRADE - -10% BOSS HEALTH - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]; + Global.UpgradeBossHealthValue < Global.UpgradeCriticalDamageMaxValue[2]; + Victim.isBoss == 1; + } + + actions + { + Global.UpgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - -10% BOSS HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("-10% BOSS HEALTH UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "-10% BOSS HEALTH"), Right, 9, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[2] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - MAX AMMO - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Zenyatta); + Global.UpgradeMaxAmmoValue < Global.UpgradeMaxAmmoMaxValue[2]; + } + + actions + { + If(Event Player.isBoss == 1); + Global.UpgradeMaxAmmoValue += 10; + Else; + Global.UpgradeMaxAmmoValue += 1; + End; + } +} + +rule("GLOBAL: UPGRADE - MAX AMMO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("MAX AMMO 200% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "MAX AMMO 200%"), Right, 10, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("Bulletstorm: Your weapon can hold unlimited ammo"), + Custom String("KILL {2}: {0}/{1}", Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[1], Hero(Zenyatta)), Left, 15, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0) * 2); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1) * 2); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0)); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1)); + End; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK BULLETSTORM - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("BULLETSTORM UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Bulletstorm"), Right, 11, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("+50% DAMAGE"), Custom String("KILL {2}: {0}/{1}", + Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[2], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[2] = Last Text ID; + Global.Perk[1] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[19] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - +50% DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("+50% DAMAGE UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "+50% DAMAGE"), Right, 12, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[2] = Last Text ID; + Global.DamageDone = 50; + All Players(Team 1).DamageDealt = 100 + Global.DamageDone + All Players(Team 1).Abilities[13] * 5; + Set Damage Dealt(All Players(Team 1), All Players(Team 1).DamageDealt); + Global.challengeCount += 1; + } +} + +disabled rule("=== GAME PHASES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: ASEMBLING PHASE - MAKE CHALLENGES HUDS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Assembling Heroes == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Disable Inspector Recording; + Set Match Time(20); + End; + Create In-World Text(All Players(Team 1), Custom String(" {0}\r\nREPAIR\r\n {1}", Hero Icon String(Hero(Torbjörn)), + Ability Icon String(Hero(Bastion), Button(Secondary Fire))), Global.GatePosition + Vector(0, 1.400, 0), 1.200, Do Not Clip, + Visible To, Color(White), Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("TEAM CHALLENGES"), Left, 11, Color(White), Color(Blue), Color( + White), Visible To, Default Visibility); + "UPGRADE - GATE'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String( + "GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Custom String("REPAIR GATE {0}/{1} HP", + Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[0]), Left, 12, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 2, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - PLAYER'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +50%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[0]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 4, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - CRITICAL DAMAGE" + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("CRITICAL DAMAGE 150%"), Custom String( + "KILL WIDOW WITH HEADSHOT: {0}/{1}", Global.UpgradeCriticalDamageValue, Global.UpgradeCriticalDamageMaxValue[0]), Left, 14, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 6, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - MAX AMMO" + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("MAX AMMO 200%"), Custom String("KILL {2}: {0}/{1}", + Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[0], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Custom String("HOLD {0} - Reload to open the shop", Input Binding String(Button(Reload))), + Null, Null, Top, 1000, Color(Yellow), Color(White), Color(White), Visible To and String, Default Visibility); + } +} + +rule("GLOBAL: SETUP PHASE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Set Match Time(20); + End; + Set Objective Description(All Players(All Teams), Custom String("DEFEND GATE"), Visible To and String); + } +} + +rule("GLOBAL: GAME IN PROGRESS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + } + + actions + { + Set Match Time(3599); + Pause Match Time; + Disable Built-In Game Mode Scoring; + Disable Built-In Game Mode Announcer; + Disable Built-In Game Mode Completion; + Disable Game Mode HUD(All Players(All Teams)); + Disable Game Mode In-World UI(All Players(All Teams)); + Global.GateHealth = Global.GateMaxHealth; + Global.GateHealthChase = Global.GateHealth; + Global.GateProgressBarColorComponent = 255; + Global.GateProgressBarColorCurrent = Color(White); + Create Progress Bar HUD Text(All Players(Team 1), Global.GateHealthChase * 100 / Global.GateMaxHealth, Custom String( + "GATE {0}/{1}", Global.GateHealth, Global.GateMaxHealth), Top, 1, Global.GateProgressBarColorCurrent, Color(White), + Visible To Values and Color, Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("SURVIVED TIME: {0}:{1}", Global.TimeMin, + Global.TimeSec < 10 ? Custom String("0{0}", Global.TimeSec) : Global.TimeSec), Top, 2, Color(White), Color(White), Color( + White), Visible To and String, Default Visibility); + Start Rule(GameLogicWave0, Do Nothing); + } +} + +disabled rule("=== GAME - MAIN LOGIC ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: DEFEAT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.IsDebug == False; + Global.GateHealth <= 0; + } + + actions + { + Declare Team Victory(Team 2); + } +} + +rule("GLOBAL: TIMER - MAIN GAME LOOP") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + disabled Global.GateHealth > 0; + } + + actions + { + Wait(1, Ignore Condition); + Global.TimeSec += 1; + If(Global.TimeSec == 60); + Global.TimeSec = 0; + Global.TimeMin += 1; + Global.Time5Min = Round To Integer(Global.TimeMin / 5, Down); + Global.Time10Min = Round To Integer(Global.TimeMin / 10, Down); + Global.SpawnPositionMaxId += 1; + disabled Start Rule(GameLogicAddNextHeroInGame, Restart Rule); + Else If(Global.TimeSec == 30); + Global.SpawnPositionMaxId += 1; + End; + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GAME LOGIC - ADD NEXT HERO IN GAME") +{ + event + { + Subroutine; + GameLogicAddNextHeroInGame; + } + + actions + { + "REDUCE RESPAWN TIME FOR ZENS" + disabled Global.ZenRespawnTime -= 1.500; + disabled Global.ZenRespawnTime = Max(1, Global.ZenRespawnTime); + disabled Set Respawn Max Time(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Global.DefaultHeroBotsPool[0]), + Global.ZenRespawnTime); + "ALL HEROES WAS ADDED IN GAME" + Abort If(Global.DefaultHeroBotsPoolCurrentId == Count Of(Global.DefaultHeroBotsPool) - 1); + Global.DefaultHeroBotsPoolCurrentId += 1; + "ВРЕМЕННЫЙ КОСТЫЛЬ ЧТОБЫ ЭХО ЗАМЕНИЛА ХАМСТЕРА" + If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Hero(Echo)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Abort; + End; + "ABORT IF NEXT HERO IN ARRAY ORDER IS NULL" + Abort If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Null); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId], Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("SUBROUTINE: GAME LOGIC - SET BOT PROPERTIES") +{ + event + { + Subroutine; + GameLogicSetBotProperties; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + If(Global.TimeMin >= 10); + If(Filtered Array(Global.lastBoss, Current Array Element == Hero Of(Event Player)) == False); + If(Global.activeBoss == False); + If(Global.bossTrigger < Global.TimeMin); + Global.bossTrigger = Global.TimeMin; + Global.activeBoss = Event Player; + Event Player.isBoss = 1; + Big Message(All Players(Team 1), Custom String("BOSS SPAWNED - {0}", Hero Of(Event Player))); + End; + End; + End; + End; + "PROPERTIES BY DEFAULT" + Set Gravity(Event Player, 100); + Set Damage Dealt(Event Player, 100); + Set Respawn Max Time(Event Player, 10); + Start Scaling Player(Event Player, 1, False); + "INDIVIDUAL HERO'S PROPERTIES" + If(Hero Of(Event Player) == Hero(Zenyatta)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 30); + Set Max Health(Event Player, 5 * (100 + Global.TimeMin * 10) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 1.500, False); + Else; + If(20 + 3 * Number Of Players(Team 1) + 3 * Global.TimeMin > 75); + Set Move Speed(Event Player, 75); + Else; + Set Move Speed(Event Player, 20 + 3 * Count Of(All Players(Team 1)) + 3 * Global.TimeMin); + End; + Set Max Health(Event Player, 100 + Global.TimeMin * 10); + End; + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 20); + Set Max Health(Event Player, 5 * (70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + If(30 + Global.TimeMin + 2.500 * Global.Time5Min > 40); + Set Move Speed(Event Player, 40); + Else; + Set Move Speed(Event Player, 30 + Global.TimeMin + 2.500 * Global.Time5Min); + End; + Set Ultimate Charge(Event Player, 0); + Set Max Health(Event Player, 70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + If(Event Player.isBoss == 1); + Set Damage Dealt(Event Player, 2 * (85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min)); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 5 * (100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Event Player.BotCounter = 0; + Set Damage Dealt(Event Player, 85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Bastion)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 50); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Start Scaling Player(Event Player, 3, False); + Set Max Health(Event Player, 5 * (155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Else; + Set Move Speed(Event Player, 80); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Start Scaling Player(Event Player, 2, False); + Set Max Health(Event Player, 155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Orisa)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 5 * (220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Set Move Speed(Event Player, 30 + 5 * Global.Time5Min); + Else; + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min); + Set Move Speed(Event Player, 90 + 5 * Global.Time5Min); + End; + Else If(Hero Of(Event Player) == Hero(Echo)); + If(Event Player.isBoss == 1); + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 70 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 5 * (90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 130 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.500, False); + Set Move Speed(Event Player, 70); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 5 * (55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Else; + disabled Start Scaling Player(Event Player, 0.850, False); + Set Move Speed(Event Player, 110); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin); + End; + End; + Wait(0.250, Ignore Condition); + "FILL HEALTH" + Heal(Event Player, Null, 100000); + } +} + +disabled rule("=== GATE ===") +{ + event + { + Ongoing - Global; + } +} + +rule("Subroutine: GATE REPAIR") +{ + event + { + Subroutine; + GateRepair; + } + + actions + { + Small Message(Event Player, Custom String("REPAIR +2% ULTIMATE")); + "UPGRADE - GATE'S MAX HEALTH" + If(Global.UpgradeGateMaxHealthValue < Global.UpgradeGateMaxHealthMaxValue[2]); + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.UpgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.UpgradeGateMaxHealthValue += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + End; + End; + "HEAL GATE" + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.GateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.GateHealth += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + "CHARGE ULTIMATE" + Else; + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + End; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + } +} + +rule("TORB: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Has Spawned(Event Player) == True; + Weapon(Event Player) == 2; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(Is Using Ability 2(Event Player) == True ? 0.350 : 0.700, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Brig: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 5; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Rein: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + Is Game In Progress == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Call Subroutine(GateRepair); + Wait(0.850, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GATE PROGRESS BAR COLOR") +{ + event + { + Subroutine; + GateProgressBarColor; + } + + actions + { + Stop Chasing Global Variable(GateHealthChase); + Chase Global Variable Over Time(GateHealthChase, Global.GateHealth, 0.100, Destination and Duration); + "GATE WAS DAMAGED" + If(Global.GateHealth < Global.GateHealthEvent); + For Global Variable(LoopIterator1, 0, 3, 1); + Global.GateProgressBarColorCurrent = Color(Red); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(White); + Wait(0.030, Ignore Condition); + End; + "GATE WAS REPAIRED" + Else; + Global.GateProgressBarColorCurrent = Color(Green); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(Yellow); + Wait(0.030, Ignore Condition); + End; + Global.GateHealthEvent = Global.GateHealth; + Global.GateProgressBarColorComponent = Global.GateHealth * 255 / Global.GateMaxHealth; + Global.GateProgressBarColorCurrent = Custom Color(255, Global.GateProgressBarColorComponent, Global.GateProgressBarColorComponent, + 255); + } +} + +disabled rule("=== COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("ALL: INIT") +{ + event + { + Player Joined Match; + All; + All; + } + + actions + { + "ALL (COMMON) INIT" + Event Player.IsDead = True; + Disable Kill Feed(Event Player); + Disable Game Mode In-World UI(Event Player); + Disable Death Spectate Target HUD(Event Player); + "BOT INIT" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotInit); + "PLAYER INIT" + Else; + Call Subroutine(PlayerInit); + End; + } +} + +rule("SUBROUTINE: BOT - INIT") +{ + event + { + Subroutine; + BotInit; + } + + actions + { + "INIT VARS" + Event Player.HasBadStatus = False; + Event Player.IsRespawning = False; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEventPosition = Vector(9999, 999, 9999); + "DISABLE ALL FOR BOT" + Disable Hero HUD(Event Player); + Disable Messages(Event Player); + Disable Text Chat(Event Player); + Disable Scoreboard(Event Player); + Disable Game Mode HUD(Event Player); + Disable Death Spectate All Players(Event Player); + Disable Voice Chat(Event Player, True, True, True); + "INIT AI NAVIGATION VARS" + Call Subroutine(BotResetPathFinding); + } +} + +rule("SUBROUTINE: PLAYER - INIT") +{ + event + { + Subroutine; + PlayerInit; + } + + actions + { + "STORY HEROES" + If(Global.IsStoryHeroes); + Reset Player Hero Availability(Event Player); + Set Player Allowed Heroes(Event Player, Array(Hero(Ana), Hero(Brigitte), Hero(Mercy), Hero(Lúcio), Hero(Moira), Hero(Baptiste), + Hero(Ashe), Hero(D.Va), Hero(Genji), Hero(Hanzo), Hero(Widowmaker), Hero(Cassidy), Hero(Reinhardt), Hero(Soldier: 76), Hero( + Torbjörn), Hero(Tracer), Hero(Winston), Hero(Pharah))); + End; + "TEAM CHALLENGE - PLAYER'S MAX HEALTH" + If(Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0]); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + End; + If(Is Game In Progress); + Disable Game Mode HUD(Event Player); + End; + } +} + +rule("ALL: RESPAWN") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + (Hero Of(Event Player) != Event Player.CurrentHero || Event Player.IsDead == True) == True; + } + + actions + { + Event Player.IsDead = False; + "BOT RESPAWN" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotRespawn); + If(Global.IsDebugAINavigation); + Create Beam Effect(All Players(All Teams), Good Beam, Eye Position(Event Player), Event Player.BotNextNodePosition, Color(Green), + Visible To Position and Radius); + End; + "PLAYER RESPAWN" + Else; + Call Subroutine(PlayerRespawn); + End; + "MUST BE AFTER ALL RESPAWN SUBROUTINES!" + Event Player.CurrentHero = Hero Of(Event Player); + } +} + +rule("SUBROUTINE: BOT - RESPAWN") +{ + event + { + Subroutine; + BotRespawn; + } + + actions + { + "RESET COMMON PROPERTIES" + Event Player.IsRespawning = True; + Enable Nameplates(Event Player, All Players(Team 1)); + Call Subroutine(BotResetPathFinding); + disabled If(Hero Of(Event Player) != Event Player.CurrentHero); + Call Subroutine(GameLogicSetBotProperties); + disabled End; + "INDIVIDUAL HERO'S RESPAWN SCRIPTS" + If(Hero Of(Event Player) == Hero(Bastion)); + Call Subroutine(BotBastionRespawn); + Else If(Hero Of(Event Player) == Hero(Zenyatta)); + Call Subroutine(BotZenyattaRespawn); + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + Call Subroutine(BotWidowRespawn); + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Call Subroutine(BotBallRespawn); + Else If(Hero Of(Event Player) == Hero(Orisa)); + Call Subroutine(BotOrisaRespawn); + Else If(Hero Of(Event Player) == Hero(Echo)); + Call Subroutine(BotEchoRespawn); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Call Subroutine(BotReinRespawn); + End; + Event Player.IsRespawning = False; + } +} + +rule("SUBROUTINE: PLAYER - RESPAWN") +{ + event + { + Subroutine; + PlayerRespawn; + } + + actions + { + "TEAM CHALLENGE - MAX AMMO" + If(Hero Of(Event Player) != Event Player.CurrentHero && Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]); + Set Max Ammo(Event Player, 0, Ammo(Event Player, 0) * 2); + Set Max Ammo(Event Player, 1, Ammo(Event Player, 1) * 2); + Set Ammo(Event Player, 0, Max Ammo(Event Player, 0)); + Set Ammo(Event Player, 1, Max Ammo(Event Player, 1)); + End; + "MUST BE AFTER TEAM CHALLENGE MAX AMMO!" + disabled Event Player.CurrentHero = Hero Of(Event Player); + "PLAYER RESPAWN" + Set Status(Event Player, Null, Phased Out, 3); + Set Facing(Event Player, Vector(-1, 0, 0), To World); + Teleport(Event Player, Global.PlayerSpawnPositions[Slot Of(Event Player) == Count Of(Global.PlayerSpawnPositions) ? Random Integer( + 0, Count Of(Global.PlayerSpawnPositions) - 1) : Slot Of(Event Player)]); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + } +} + +rule("PLAYER: DEATH") +{ + event + { + Player Died; + Team 1; + All; + } + + actions + { + If(Hero Of(Event Player) == Hero(Roadhog)); + Event Player.Abilities[8] -= 1; + Wait(Global.Perk[2] ? 5 : 10, Ignore Condition); + Event Player.Abilities[8] += 1; + End; + disabled If(Event Player.lastSecondWind > 0); + disabled Event Player.lastSecondWind = 0; + disabled End; + Event Player.IsDead = True; + } +} + +rule("BOT: DEATH") +{ + event + { + Player Died; + Team 2; + All; + } + + actions + { + If(Event Player.isBoss == 1); + If(Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]); + If(Global.UpgradeBossHealthValue < Global.UpgradeCriticalDamageMaxValue[2]); + Global.UpgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + End; + End; + Event Player.isBoss = 0; + Global.activeBoss = Null; + Big Message(All Players(Team 1), Custom String("BOSS DIED - {0}", Hero Of(Event Player))); + End; + Event Player.IsDead = True; + Event Player.HasBadStatus = False; + Event Player.BotDoesUniqueBehaviour = False; + Disable Nameplates(Event Player, All Players(Team 1)); + disabled Stop Holding Button(Event Player, Button(Ability 1)); + disabled Stop Holding Button(Event Player, Button(Primary Fire)); + disabled Stop Holding Button(Event Player, Button(Secondary Fire)); + "BOT HAS 1 EFFECT IN VAR (NOT ARRAY)" + Skip If(!Entity Exists(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects); + "BOT HAS MORE THEN 1 EFFECT IN VAR (ARRAY)" + Skip If(Count Of(Event Player.BotEffects) == 0, 3); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects[Event Player.BotLoopIterator1]); + End; + } +} + +disabled rule("=== BOT COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BAD STATUS") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + Event Player.HasBadStatus = True; + "PROCESS BAD STATUS" + If(Hero Of(Event Player) == Hero(Widowmaker)); + Start Rule(BotWidowBadStatus, Do Nothing); + End; + Wait Until(!Has Status(Event Player, Knocked Down) && !Has Status(Event Player, Asleep) && !Has Status(Event Player, Frozen) + && !Has Status(Event Player, Stunned), 15); + Event Player.HasBadStatus = False; + } +} + +rule("SUBROUTINE: BOT - LANDING FROM SKY") +{ + event + { + Subroutine; + BotLandingFromSky; + } + + actions + { + Stop Throttle In Direction(Event Player); + "SET RESPAWN POSITION" + Event Player.BotEventPosition = Random Value In Array(Global.BigBossSpawnPositions); + "CREATE EFFECTS" + disabled Create Effect(All Players(All Teams), Light Shaft, Color(Red), Event Player.BotEventPosition, 3, Visible To); + disabled Event Player.BotEffects = Last Created Entity; + "RESPAWN IN LIGHT SHAFT EFFECT" + Teleport(Event Player, Event Player.BotEventPosition + Vector(0, 25, 0)); + Wait(0.020, Ignore Condition); + "SLOW LANDING" + Set Gravity(Event Player, 50); + While(Is In Air(Event Player) == True); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Position Of(Event Player) + Vector(0, -2.700, 0), 2); + Wait(0.250, Ignore Condition); + End; + Set Gravity(Event Player, 100); + disabled Destroy Effect(Event Player.BotEffects); + "LANDING EFFECTS" + Play Effect(All Players(All Teams), Wrecking Ball Piledriver Impact Effect, Custom Color(105, 87, 46, 255), Position Of( + Event Player), 8); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Sound, Color(White), Position Of(Event Player), 150); + } +} + +rule("SUBROUTINE: BOT - APPEAR FROM UNDERGROUND") +{ + event + { + Subroutine; + BotApearFromUnderground; + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1); + Wait(0.200, Ignore Condition); + Set Gravity(Event Player, 20); + Disable Movement Collision With Environment(Event Player, True); + Teleport(Event Player, Global.ZenSpawnPositions[Random Integer(Min(Global.TimeMin, Count Of(Global.ZenSpawnPositions) - 10), Min( + Global.SpawnPositionMaxId, Count Of(Global.ZenSpawnPositions) - 4))] + Vector(0, -1.500, 0)); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Sigma Accretion Impact Effect, Custom Color(220, 175, 100, 255), Eye Position(Event Player), + 3); + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(Gray), Eye Position(Event Player), 50); + Apply Impulse(Event Player, Up, 3.500, To World, Cancel Contrary Motion); + Wait(0.400, Ignore Condition); + Clear Status(Event Player, Knocked Down); + Set Gravity(Event Player, 100); + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("=== PLAYER MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("PLAYER: DARKNESS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + !Entity Exists(Event Player.BotEffects) == True; + } + + actions + { + Disable Nameplates(Event Player, All Players(All Teams)); + Start Forcing Player Outlines(Event Player, All Players(All Teams), False, Color(White), Default); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 14), 25, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(-5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + } +} + +rule("PLAYER: HEALTH REGEN") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + actions + { + Stop Heal Over Time(Event Player.HealOverTimeId); + Event Player.EventHealth = Health(Event Player); + Wait(4, Ignore Condition); + "TOOK DAMAGE, RESET REGENERATION TIMER" + Loop If(Is Alive(Event Player) && Event Player.EventHealth > Health(Event Player)); + Start Heal Over Time(Event Player, Null, 3, Max Health(Event Player) / 3); + Event Player.HealOverTimeId = Last Heal Over Time ID; + } +} + +disabled rule("=== NERFS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("REINHARDT: ANTI-CHARGE FOR BASTION & ORISA") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Using Ability 1(Event Player) == True; + Hero Of(Ray Cast Hit Player(Eye Position(Event Player) + Vector(0, 2, 0), Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 2, All Living Players(Team 2), Event Player, True)) == (Hero(Bastion) == True || Hero( + Orisa) == True); + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1.500); + } +} + +rule("HOG: ANTI-HOOK FOR BASTION & ORISA") +{ + event + { + Player Dealt Damage; + Team 1; + Roadhog; + } + + conditions + { + Event Ability == Button(Ability 1); + (Hero Of(Victim) == Hero(Bastion) || Hero Of(Victim) == Hero(Orisa)) == True; + } + + actions + { + Set Status(Event Player, Null, Stunned, 0.005); + } +} + +disabled rule("=== ZENYATTA ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ZEN - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Zenyatta; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + } + + actions + { + Set Ammo(Event Player, 0, 0); + Communicate(Event Player, Hello); + disabled Call Subroutine(BotResetPathFinding); + Wait(1.500, Ignore Condition); + Abort If(Is Dead(Event Player) == True); + Kill(Event Player, Null); + } +} + +rule("BOT: ZEN - DEATH") +{ + event + { + Player Died; + Team 2; + Zenyatta; + } + + actions + { + "EFFECT" + Play Effect(All Players(All Teams), Junkrat Frag Launcher Explosion Effect, Color(Red), Eye Position(Event Player), 2.500); + Play Effect(All Players(All Teams), Ashe Dynamite Explosion Sound, Color(Red), Eye Position(Event Player), 70); + "DAMAGE AND APPLY IMPULSE TO PLAYERS" + Event Player.BotPlayersInRadius = Players Within Radius(Position Of(Event Player), 2.500, All Teams, Surfaces And Enemy Barriers); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotPlayersInRadius), 1); + Apply Impulse(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Direction Towards(Position Of(Event Player), + Eye Position(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1])), 5, To World, Incorporate Contrary Motion); + If(Team Of(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1]) == Team 1); + Damage(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Event Player, 50); + End; + End; + "DAMAGE GATE" + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 125; + Else; + Global.GateHealth -= 25; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Respawn(Event Player); + Abort; + End; + "KILLED BY PLAYER" + Teleport(Event Player, Vector(0, -999, 0)); + Wait(2, Ignore Condition); + Respawn(Event Player); + Wait(2, Ignore Condition); + } +} + +rule("SUBROUTINE: ZEN - RESPAWN") +{ + event + { + Subroutine; + BotZenyattaRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WRECKING BALL ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BALL - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + disabled Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Set Ammo(Event Player, 0, 0); + Wait(1, Ignore Condition); + Set Ultimate Charge(Event Player, 100); + Start Holding Button(Event Player, Button(Ultimate)); + Wait Until(Is Using Ultimate(Event Player), 0.600); + Abort If(Is Dead(Event Player)); + Kill(Event Player, Null); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Effect, Color(Orange), Eye Position(Event Player), 6); + Play Effect(All Players(All Teams), DVa Self Destruct Explosion Sound, Color(White), Eye Position(Event Player), 250); + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 300; + Else; + Global.GateHealth -= 150; + End; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Damage(Players Within Radius(Eye Position(Event Player), 7, Team 1, Surfaces And All Barriers), Event Player, 200); + } +} + +rule("BOT: BALL - ALTERNATIVE FORM") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is In Alternate Form(Event Player) == False; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is In Alternate Form(Event Player), 10); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: BALL - DEATH") +{ + event + { + Player Died; + Team 2; + Wrecking Ball; + } + + actions + { + Stop Holding Button(Event Player, Button(Ability 1)); + Stop Holding Button(Event Player, Button(Ultimate)); + } +} + +rule("SUBROUTINE: BALL - RESPAWN") +{ + event + { + Subroutine; + BotBallRespawn; + } + + actions + { + "RESPAWN IN AIR" + Teleport(Event Player, Random Value In Array(Global.BallSpawnPositions) + Vector(0, 20, 0)); + Stop Holding Button(Event Player, Button(Ultimate)); + Wait(0.250, Ignore Condition); + "LANDING" + Start Holding Button(Event Player, Button(Crouch)); + Wait Until(Is On Ground(Event Player), 9999); + Stop Holding Button(Event Player, Button(Crouch)); + "LANDING IMPACT EFFECT" + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(White), Event Player, 150); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Effect, Color(Gray), Position Of(Event Player), 10); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Eye Position(Event Player), 1.500, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + "PATH FINDING TO GATE" + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +disabled rule("=== ECHO ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ECHO - FLY ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is Using Ability 1(Event Player) == False; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), 0); + Press Button(Event Player, Button(Ability 1)); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - BEAM ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Using Ability 1(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == True; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - BAD STATUS - RESET BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.HasBadStatus == True; + disabled (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + Wait Until(Event Player.HasBadStatus, 7); + } +} + +rule("BOT: ECHO - CAN'T SEE PORTAL - APPLY IMPULSE") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == True; + Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Wait(0.300, Abort When False); + Apply Impulse(Event Player, Vector(Random Integer(-1, 1), 1, Random Integer(-1, 1)), 20, To World, Incorporate Contrary Motion); + Wait(1, Ignore Condition); + If(!Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + Event Player.BotTargetPosition = Global.BotEchoRespawnPosition; + Start Rule(BotStartPathFinding, Restart Rule); + Else; + Call Subroutine(BotResetPathFinding); + End; + Loop If Condition Is True; + } +} + +disabled rule("BOT: ECHO - MAIN LOGIC - BACKUP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(!Event Player.BotIsPathFinding); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Is In Line of Sight(Eye Position(Event Player), + Eye Position(Current Array Element), Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), + Position Of(Current Array Element)))[0]; + End; + "NO PLAYERS IN VIEW RANGE" + disabled If(Event Player.BotSeePlayer == Null); + disabled Stop Throttle In Direction(Event Player); + disabled End; + "FLY TO PLAYER" + If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + > 4 && Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + "ACTIVATE FOCUS BEAM" + Else If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + < 4 && Event Player.BotDoesUniqueBehaviour == False && Event Player.HasBadStatus == False); + Event Player.BotDoesUniqueBehaviour = True; + Set Status(Event Player.BotSeePlayer, Event Player, Stunned, 1); + Set Status(Event Player.BotSeePlayer, Event Player, Hacked, 99999); + Attach Players(Event Player.BotSeePlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + "TELEPORT PLAYER TO AWAY" + Else If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotSeePlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotSeePlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotSeePlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + "BEGIN TO FLY TO THE PORTAL" + Else If(Event Player.BotDoesUniqueBehaviour == True); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + End; + "TELEPORT PLAYER SO FAR" + If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotEchoCapturedPlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotEchoCapturedPlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + End; + "BEGIN TO FLY TO THE PORTAL WITH A PLAYER" + If(Event Player.BotDoesUniqueBehaviour); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotEchoCapturedPlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - DEFEND PORTAL") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + } + + actions + { + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPlayer); + } +} + +rule("BOT: ECHO - PATH FINDING TO PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Call Subroutine(BotStartPathFinding); + } +} + +rule("BOT: ECHO - ATTACH PLAYER BY BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotEchoCapturedPlayer == Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 3; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Event Player.BotEchoCapturedPlayer = Event Player.BotSeePlayer; + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Stunned, 0.700); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Hacked, 10); + Attach Players(Event Player.BotEchoCapturedPlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - PLAYER DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Dead(Event Player.BotEchoCapturedPlayer) != Null; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - DEATH") +{ + event + { + Player Died; + Team 2; + Echo; + } + + actions + { + Call Subroutine(BotEchoDetachPlayer); + Stop Holding Button(Event Player, Button(Jump)); + Wait(5, Ignore Condition); + Teleport(Event Player, Vector(0, 999, 0)); + Start Forcing Player To Be Hero(Event Player, Hero(Orisa)); + } +} + +rule("SUBROUTINE: ECHO - RESPAWN") +{ + event + { + Subroutine; + BotEchoRespawn; + } + + actions + { + Event Player.BotCounter = 0; + Event Player.BotEffects = Empty Array; + Create Effect(All Players(All Teams), Good Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Energy Sound, Color(White), Global.BotEchoRespawnPosition, 200, Visible To); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Chase Player Variable Over Time(Event Player, BotCounter, 3, 0.800, Destination and Duration); + Play Effect(All Players(All Teams), Sombra EMP Explosion Effect, Color(Sky Blue), Global.BotEchoRespawnPosition, 12); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Null, Global.BotEchoRespawnPosition, 100); + Wait(3, Ignore Condition); + Teleport(Event Player, Global.BotEchoRespawnPosition); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Global.BotEchoRespawnPosition, 2.500); + Play Effect(All Players(All Teams), Debuff Impact Sound, Null, Global.BotEchoRespawnPosition, 100); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PLAYER") +{ + event + { + Subroutine; + BotEchoFlyToPlayer; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Stop Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PORTAL") +{ + event + { + Subroutine; + BotEchoFlyToPortal; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - DETACH PLAYER") +{ + event + { + Subroutine; + BotEchoDetachPlayer; + } + + actions + { + Detach Players(Event Player.BotEchoCapturedPlayer); + Clear Status(Event Player.BotEchoCapturedPlayer, Hacked); + "IF PLAYER INSIDE THE WALL" + If(Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotEchoCapturedPlayer), Barriers Do Not Block LOS)); + Teleport(Event Player.BotEchoCapturedPlayer, Position Of(Event Player)); + End; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEchoCapturedPlayer = Null; + } +} + +disabled rule("=== REINHARDT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: REIN - SET PLAYER AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + disabled Event Player.BotIsPathFinding == False; + "BOT IS FAR FROM GATES" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Global.GatePosition), 0, Z Component Of(Global.GatePosition))) > 20; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET CLOSEST PLAYER TO BOT AS TARGET AND FOLLOW HIM" + Event Player.BotTargetPlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - SET GATE AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "BOT DOESN'T FOLLOW PLAYER" + Event Player.BotTargetPlayer == -1; + "CAN'T SEE ANY PLAYER" + disabled Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), !Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET GATE AS TARGET" + Event Player.BotTargetPosition = Global.GatePosition; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - TARGET DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer != -1; + Is Dead(Event Player.BotTargetPlayer) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + } +} + +rule("BOT: REIN - ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) < 4; + "CAN ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) < 4; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + "TARGET IS PLAYER" + Abort If(Event Player.BotTargetPlayer != -1); + If(Event Player.isBoss == 1); + "TARGET IS GATE" + Global.GateHealth -= 25; + Else; + Global.GateHealth -= 5; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: REIN - STOP ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) > 4; + "CAN'T ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) > 4; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + } +} + +rule("BOT: REIN - USE SHIELD") +{ + event + { + Player Took Damage; + Team 2; + Reinhardt; + } + + conditions + { + Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) > 3; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Attacker)), 200, To World, + Direction and Turn Rate); + Start Holding Button(Event Player, Button(Secondary Fire)); + Wait Until(Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) < 3, 3); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("BOT: REIN - CHARGE IN GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer == -1; + Is Using Ability 1(Event Player) == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == True; + Is In View Angle(Event Player, Global.GatePosition, 7.500) == True; + } + + actions + { + disabled Wait(0.800, Abort When False); + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is Using Ability 1(Event Player), 1); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: REIN - DEATH") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("SUBROUTINE: REIN - RESPAWN") +{ + event + { + Subroutine; + BotReinRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WIDOW ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: WIDOW - SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer == Null; + Event Player.HasBadStatus == False; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Event Player.BotWidowShotTime = Total Time Elapsed + (Global.TimeMin >= 9 ? Random Real(2, 5) : Random Real(5, 10)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 9999, To World, + Direction and Turn Rate); + } +} + +rule("BOT: WIDOW - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer != Null; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowShotTime; + } + + actions + { + Press Button(Event Player, Button(Primary Fire)); + Stop Facing(Event Player); + Event Player.BotSeePlayer = Null; + } +} + +rule("BOT: WIDOW - Aim Sound") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Alive(Event Player) == True; + Is In Line of Sight(Eye Position(Players On Hero(Hero(Widowmaker), Team 2)), Eye Position(Event Player), Barriers Do Not Block LOS) + == True; + Is Alive(Players On Hero(Hero(Widowmaker), Team 2)) == True; + Players On Hero(Hero(Widowmaker), Team 2).BotSeePlayer == True; + } + + actions + { + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 100); + Wait(1, Abort When False); + Loop If Condition Is True; + } +} + +rule("BOT: WIDOW - TELEPORT TO NEW POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowTeleportTime; + } + + actions + { + Event Player.BotWidowTeleportTime = Total Time Elapsed + 28; + Event Player.BotWidowShotTime = Total Time Elapsed + Random Real(1, 1.600); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Event Player, 1); + Wait(0.016, Ignore Condition); + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + } +} + +rule("BOT: WIDOW - DEATH") +{ + event + { + Player Died; + Team 2; + Widowmaker; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + Wait(0.250, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - RESPAWN") +{ + event + { + Subroutine; + BotWidowRespawn; + } + + actions + { + "RESPAWN ON RANDOM SNIPER POSITION" + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Wait(0.700, Ignore Condition); + Start Holding Button(Event Player, Button(Secondary Fire)); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait Until(Is Dead(Event Player), 99999); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - BAD STATUS") +{ + event + { + Subroutine; + BotWidowBadStatus; + } + + actions + { + Stop Facing(Event Player); + Destroy Effect(Event Player.BotEffects); + Wait Until(!Event Player.HasBadStatus, 15); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + } +} + +disabled rule("=== BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("BOT: BASTION - FLAME GUN") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 50) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 8; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Stop Holding Button(Event Player, Button(Primary Fire)); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Update Every Frame(Eye Position(Event Player) + World Vector Of( + Vector(-1, -1.200, 1.800), Event Player, Rotation)), 1, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Start Rule(BotBastionFlameGunDamage, Do Nothing); + Wait(1.100, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(4, Ignore Condition); + Loop If Condition Is True; + } +} + +disabled rule("BOT: BASTION - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + disabled Event Player.BotSeePlayer == Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - CAN'T SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == False; + } + + actions + { + Event Player.BotSeePlayer = Null; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - MOVE TO BASTION'S TARGET (POSITION)") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotTargetPosition = Random Value In Array(Filtered Array(Global.BastionTargetPositions, Distance Between(Position Of( + Event Player), Current Array Element) > 3.500)); + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("BOT: BASTION - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + "SEE THE PLAYER" + If(Event Player.BotSeePlayer != Null); + Stop Holding Button(Event Player, Button(Secondary Fire)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer) - Vector(0, 0.500, + 0)), 100, To World, Direction and Turn Rate); + "SELF REPAIRING" + Else If(!Is Firing Secondary(Event Player) && Health(Event Player) < Max Health(Event Player)); + Start Holding Button(Event Player, Button(Secondary Fire)); + End; + "START FOLLOW PATH" + disabled If(!Event Player.BotIsPathFinding && !Event Player.BotDoesUniqueBehaviour); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled Wait(0.050, Ignore Condition); + disabled Event Player.BotTargetPosition = Random Value In Array(Global.BastionTargetPositions); + disabled Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Event Player.BotTargetPosition + Vector(0, 2, 0)), 100, + To World, Direction and Turn Rate); + disabled Start Rule(BotStartPathFinding, Do Nothing); + "REACHED PATH TARGET" + disabled Else If(Distance Between(Position Of(Event Player), Event Player.BotTargetPosition) <= 3); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled End; + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - ARTILLERY") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 30) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) > 18; + Distance Between(Eye Position(Event Player), Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Up * 99, Null, Event Player, False)) >= 35; + } + + actions + { + "TRYING TO CAPTURE TARGET" + Wait(0.800, Abort When False); + "CAPTURE TARGET" + Event Player.BotDoesUniqueBehaviour = True; + Stop Throttle In Direction(Event Player); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Update Every Frame(Eye Position(Event Player)), + Update Every Frame(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 1000, All Living Players(Team 1), Event Player, True)), Color(Sky Blue), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait(1.400, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Event Player.BotEventPosition = Position Of(Event Player.BotSeePlayer); + "SHOOT FROM ARTILLERY" + Event Player.BotBastionArtilleryDidShotsCount = 0; + For Player Variable(Event Player, BotLoopIterator1, 0, 4, 1); + Event Player.BotBastionArtilleryDidShotsCount += 1; + Play Effect(All Players(All Teams), Wrecking Ball Minefield Explosion Sound, Color(White), Eye Position(Event Player), 250); + Play Effect(All Players(All Teams), Pharah Barrage Explosion Effect, Color(Orange), Eye Position(Event Player) + World Vector Of( + Vector(0, 1.400, -0.700), Event Player, Rotation), 2); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) + World Vector Of(Vector(0, 1.400, + -0.700), Event Player, Rotation), Eye Position(Event Player) + World Vector Of(Vector(Random Real(-1, 1), Random Integer(40, + 80), Random Real(0.500, 1.500)), Event Player, Rotation), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + If(Is Dead(Event Player)); + Break; + End; + End; + disabled Call Subroutine(BotResetPathFinding); + disabled Start Rule(BotStartPathFinding, Do Nothing); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Wait(1.500, Ignore Condition); + Start Rule(BotBastionArtilleryDamage, Do Nothing); + Wait(4, Ignore Condition); + } +} + +rule("BOT: BASTION - PRIMARY FIRE") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 40) == True; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Stop Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Bastion; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + For Player Variable(Event Player, BotLoopIterator1, 0, 3, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Effect, Color(White), Event Player, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player, 100); + Wait(0.250, Ignore Condition); + End; + } +} + +rule("SUBROUTINE: BASTION - RESPAWN") +{ + event + { + Subroutine; + BotBastionRespawn; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + Call Subroutine(BotLandingFromSky); + Set Ammo(Event Player, 0, 0); + Wait Until(!Is Reloading(Event Player), 99999); + Event Player.BotTargetPosition = Objective Position(2); + } +} + +rule("SUBROUTINE: BASTION - ARTILLERY DAMAGE") +{ + event + { + Subroutine; + BotBastionArtilleryDamage; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = False; + "EXPLOSIONS OF ARTILLERY" + For Player Variable(Event Player, BotLoopIterator2, 0, Event Player.BotBastionArtilleryDidShotsCount, 1); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotEventPosition + Vector(0, 50, 0), + Event Player.BotEventPosition + Vector(Random Integer(-4, 4), -15, Random Integer(-4, 4)), Null, Event Player, True); + Damage(Players Within Radius(Event Player.BotEventPosition, 8, Team 1, Surfaces And Enemy Barriers), Event Player, 50); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Pharah Rocket Launcher Explosion Effect, Color(Orange), Event Player.BotEventPosition, 5); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Event Player.BotEventPosition, + Event Player.BotEventPosition + Vector(0, 60, 0), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + End; + } +} + +disabled rule("SUBROUTINE: BASTION - FLAME GUN DAMAGE") +{ + event + { + Subroutine; + BotBastionFlameGunDamage; + } + + actions + { + Event Player.BotRayCastHitPosition = Eye Position(Event Player) + World Vector Of(Vector(-1, -1.200, 1.800), Event Player, + Rotation); + "FIRE PARTICLES OF FLAME GUN" + For Player Variable(Event Player, BotLoopIterator1, 1, 13, 3); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotRayCastHitPosition, + Event Player.BotRayCastHitPosition + Facing Direction Of(Event Player) * Event Player.BotLoopIterator1, Null, Event Player, + True); + Damage(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Surfaces And Enemy Barriers), Event Player, 20); + Set Status(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Off), Event Player, Burning, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.BotEventPosition, 2.500); + Wait(0.200, Ignore Condition); + End; + Event Player.BotDoesUniqueBehaviour = False; + } +} + +disabled rule("=== ORISA + BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ORISA-BASTION - REACHED TARGET POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotIsPathFinding == True; + Distance Between(Position Of(Event Player), Global.BotOrisaTargetPosition) < 1.500; + } + + actions + { + Call Subroutine(BotResetPathFinding); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Vector(X Component Of(Global.GatePosition), -999, + Z Component Of(Global.GatePosition))), 80, To World, Direction and Turn Rate); + Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + disabled Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element) && Is In Line of Sight(Eye Position(Event Player), Position Of(Current Array Element), + Barriers Do Not Block LOS)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + Press Button(Event Player, Button(Ability 1)); + Wait Until(Y Component Of(Facing Direction Of(Event Player)) < -0.300, 99999); + Press Button(Event Player, Button(Ability 2)); + Wait(0.800, Ignore Condition); + Global.BotOrisaChild.BotDoesUniqueBehaviour = False; + Disallow Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ORISA-BASTION - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + While(Is Alive(Event Player)); + disabled Create Effect(All Players(All Teams), Bad Aura, Color(Purple), Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3.200, 1, Visible To Position and Radius); + disabled Event Player.BotEffects = Last Created Entity; + Wait(1.500, Ignore Condition); + disabled Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Press Button(Event Player, Button(Primary Fire)); + Press Button(Event Player, Button(Reload)); + Event Player.BotRayCastHitPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Facing Direction Of(Event Player) * 999, All Players(Team 1), All Players(Team 2), True); + "ANTI-SHIELD BUG" + Event Player.BotRayCastHitPosition = Event Player.BotRayCastHitPosition + Direction Towards(Event Player.BotRayCastHitPosition, + Eye Position(Event Player)) * 0.200; + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3, Event Player.BotRayCastHitPosition, Color(Purple), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Damage(Players Within Radius(Event Player.BotRayCastHitPosition, 4, Team 1, Surfaces And All Barriers), Event Player, 0.040); + Play Effect(All Players(All Teams), Pharah Concussive Blast Effect, Color(Purple), Event Player.BotRayCastHitPosition, 4); + Play Effect(All Players(All Teams), Pharah Concussive Blast Sound, Color(Purple), Event Player.BotRayCastHitPosition, 250); + Play Effect(All Players(All Teams), Bad Explosion, Color(Purple), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 3.300, 2); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Color(Purple), Eye Position(Event Player), 170); + If(Distance Between(Event Player.BotRayCastHitPosition, Global.GatePosition) < 4 && Is In Line of Sight( + Event Player.BotRayCastHitPosition, Global.GatePosition, Enemy Barriers Block LOS)); + Global.GateHealth -= 80; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Wait(0.150, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.060, Ignore Condition); + Wait Until(!Is Reloading(Event Player), 2.500); + End; + } +} + +rule("BOT: ORISA-BASTION - CAN'T SEE THE TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: ORISA-BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Orisa; + } + + actions + { + Allow Button(Event Player, Button(Ability 2)); + Kill(Global.BotOrisaChild, Null); + Detach Players(Global.BotOrisaChild); + Clear Status(Global.BotOrisaChild, Phased Out); + Set Damage Dealt(Global.BotOrisaChild, 100); + Global.BotOrisaChild.BotIsOrisaChild = False; + Global.BotOrisaChild = Null; + Global.BotOrisaParent = Null; + Start Forcing Player To Be Hero(Event Player, Hero(Widowmaker)); + } +} + +rule("SUBROUTINE: ORISA - RESPAWN") +{ + event + { + Subroutine; + BotOrisaRespawn; + } + + actions + { + Global.BotOrisaParent = Event Player; + "WAITING FOR ANY BASTION TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero(Bastion)), + 99999); + "SETUP BASTION AS CHILD" + Global.BotOrisaChild = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Bastion))[0]; + Global.BotOrisaChild.BotIsOrisaChild = True; + Global.BotOrisaChild.BotDoesUniqueBehaviour = True; + Wait(2, Ignore Condition); + Respawn(Global.BotOrisaChild); + Start Scaling Player(Global.BotOrisaChild, 1.800, False); + Set Damage Dealt(Global.BotOrisaChild, 2000); + Set Status(Global.BotOrisaChild, Null, Phased Out, 9999); + Disable Nameplates(Global.BotOrisaChild, All Players(All Teams)); + Set Facing(Global.BotOrisaChild, Vector(X Component Of(Facing Direction Of(Event Player)), 9999, Z Component Of( + Facing Direction Of(Event Player))), To World); + Start Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Wait Until(Is In Alternate Form(Global.BotOrisaChild), 5); + Stop Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Teleport(Global.BotOrisaChild, Position Of(Event Player)); + Attach Players(Global.BotOrisaChild, Global.BotOrisaParent, Vector(0, 1.800, 0.230)); + disabled Wait(1, Ignore Condition); + disabled Stop Holding Button(Global.BotOrisaChild, Button(Primary Fire)); + disabled Wait(0.250, Ignore Condition); + Call Subroutine(BotLandingFromSky); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 0 - ZENS, REINS, BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 0; + } + + actions + { + "CREATE BOTS - ZEN" + While(Count Of(All Players(Team 2)) < 13); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "BALL" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "REPLACE DEAD ZEN TO REIN" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) != 3); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 1 - WIDOW") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 1; + } + + actions + { + Global.IsNewWaveGameLogicProcessing = True; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Global.IsNewWaveGameLogicProcessing = False; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 3 - BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 3; + } + + actions + { + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 5 - REINS WAVE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 5; + } + + actions + { + "PREPARE WAVE - DESTROY WIDOW AND BALLS" + Destroy Dummy Bot(Team 2, Slot Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))[0])); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))[0]; + Kill(Global.DefaultCurrentBot, Null); + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + "BOSS WAVE" + Big Message(All Players(All Teams), Custom String("BOSS WAVE - {1} {0}", Hero Icon String(Hero(Reinhardt)), Hero(Reinhardt))); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) < 6); + Wait Until(Is True For Any(All Players(Team 2), Distance Between(Position Of(Current Array Element), Global.GatePosition) + > 13 && Hero Of(Current Array Element) == Hero(Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + disabled Wait(0.200, Ignore Condition); + disabled Set Max Health(Global.DefaultCurrentBot, 50); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) > 3); + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Reinhardt)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Reinhardt))[0]; + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(All Players(Team 2)) < 13); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Big Message(All Players(All Teams), Custom String("BOSS WAVE FINISHED!")); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 7 - BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 7; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 9 - ECHO, +1 BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 9; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Echo))) == 0); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + "FILL EMPTY SLOTS BY ZENS" + While(Count Of(All Players(Team 2)) < 12); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("Ana Nano Variable") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + } + + actions + { + Player Closest To Reticle(Event Player, Team 1).IsNanoed = 1; + } +} + +rule("IsNanoed") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.IsNanoed == True; + } + + actions + { + If(Is Dead(Event Player)); + Event Player.IsNanoed = 0; + End; + Wait(8, Ignore Condition); + Event Player.IsNanoed = 0; + } +} + +rule("money on kill") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + actions + { + If(Hero Of(Victim) == Hero(Zenyatta)); + All Players(Team 1).Money[0] += 5 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 5 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Reinhardt)); + All Players(Team 1).Money[0] += 15 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 15 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Wrecking Ball)); + All Players(Team 1).Money[0] += 20 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 20 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Widowmaker)); + All Players(Team 1).Money[0] += 25 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 25 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Bastion)); + All Players(Team 1).Money[0] += 50 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 50 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Echo)); + All Players(Team 1).Money[0] += 75 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 75 * (Victim.isBoss ? 3 : 1); + Else If(Hero Of(Victim) == Hero(Orisa)); + All Players(Team 1).Money[0] += 100 * (Victim.isBoss ? 3 : 1); + Global.StartMoney += 100 * (Victim.isBoss ? 3 : 1); + End; + } +} + +rule("Abilities and Hero Talents by Shingen and LemonAid") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.DamageDealt = 100; + Event Player.PlayerHealth = 100; + Event Player.Money[0] = 2400 + Global.StartMoney; + If(Custom String("{0}", Event Player) == Custom String("ShuriZma")); + Create HUD Text(Event Player, Custom String("Serverload: {0}, AVG {1}, Peak {2}", Server Load, Server Load Average, + Server Load Peak), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create HUD Text(Event Player, Custom String("Last SW: {0}, SW Active {1}", Event Player.lastSecondWind, + Event Player.secondWindActive), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + End; + } +} + +rule("Team 1 (Ability): Headhunter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[1] == True; + Event Was Critical Hit == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[1] * 40 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Ambush") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[2] == True; + Event Ability != Null; + (Y Component Of(Position Of(Event Player)) - Y Component Of(Position Of(Victim)) >= 3 || Absolute Value(Horizontal Angle Towards( + Victim, Event Player)) >= 90) == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[2] * 30 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Quick Fix") +{ + event + { + Player Earned Elimination; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[3] == True; + } + + actions + { + Heal(Event Player, Null, Event Player.Abilities[3] * 50); + Set Move Speed(Event Player, 100 + Event Player.Abilities[3] * 20); + Wait(5, Restart When True); + Set Move Speed(Event Player, 100); + } +} + +rule("Team 1 (Ability): Heavyweight") +{ + event + { + Player Dealt Knockback; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[4] == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[4] * 25 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Charged") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[5] == True; + Ultimate Charge Percent(Event Player) < Event Player.Abilities[5] * 20; + } + + actions + { + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + If(Is Duplicating(Event Player)); + Wait(0.016, Ignore Condition); + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + End; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Team 1 (Ability): Haste Primary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Primary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Primary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Primary Fire))); + } +} + +rule("Team 1 (Ability): Haste Secondary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Secondary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Secondary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Secondary Fire))); + } +} + +rule("Team 1 (Ability): Haste Ability 1") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 1)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 1))); + } +} + +rule("Team 1 (Ability): Haste Ability 2") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 2)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 2))); + } +} + +rule("Team 1 (Ability): Haste Jump") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Jump)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Jump), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Jump))); + } +} + +rule("Team 1 (Ability): Haste Crouch") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Crouch)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Crouch), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Crouch))); + } +} + +rule("Team 2 (Ability): Heavy Impact") +{ + event + { + Player Took Damage; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[7] == True; + } + + actions + { + Abort If(Random Real(-0.020, 1) > Event Damage / Max Health(Event Player)); + Set Status(Event Player, Attacker, Stunned, 1 * Attacker.Abilities[7]); + Wait(5, Ignore Condition); + } +} + +rule("Team 1 (Ability): Binding Heal") +{ + event + { + Player Dealt Healing; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[10] == True; + Healee != Event Player; + } + + actions + { + Set Player Health(Event Player, Health(Event Player) + Event Player.Abilities[10] * 0.250 * Event Healing); + } +} + +rule("Team 1 (Ability): Resilience") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[11] == True; + Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300; + } + + actions + { + Set Damage Received(Event Player, 70); + Wait Until(!(Event Player.Abilities[11] && Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Auto Repair") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.AutoRepair == True; + Global.GateHealth < Global.GateMaxHealth; + } + + actions + { + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2]); + Global.GateHealth += 10 * Global.AutoRepair; + Global.UpgradeGateMaxHealthValue += 10 * Global.AutoRepair; + Else; + Global.GateHealth += 5 * Global.AutoRepair; + Global.UpgradeGateMaxHealthValue += 5 * Global.AutoRepair; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(5, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ana Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ana), Button(Ability 1)), Custom String( + "Sleep Paralysis: Slept enemies cannot be woken up by damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Ana), Button(Ability 2)), Custom String( + "Multinade: Ana throws multiple Biotic Grenades")); + } +} + +rule("Brigitte Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Brigitte), Button(Ability 1)), Custom String( + "Heavy Iron: Hitting enemies with Whip Flail will root them in pace")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Brigitte), Button(Ultimate)), Custom String( + "Endeavor: Gain a health, damage and speed boost when your barrier breaks")); + } +} + +rule("Mercy Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mercy), Button(Ability 2)), Custom String( + "Angelic blessing: Healing an ally slowly charges their ultimate")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mercy), Button(Ultimate)), Custom String( + "Holy light missiles: Unleash blasts of holy light missiles during valkyrie")); + } +} + +rule("Lúcio Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Lúcio), Button(Secondary Fire)), Custom String( + "Healing Wave: Soundwave heals allies for 30% of their max HP")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Lúcio), Button(Ability 1)), Custom String( + "Reverse Amp: Amp It Up inflicts the opposite effect of the currently played song to enemies")); + } +} + +rule("Moira Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Moira), Button(Secondary Fire)), Custom String( + "Hose: Biotic Grasp primary will damage and push enemies back")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Moira), Button(Ability 2)), Custom String( + "Flourish: Biotic Orbs are 3x more effective")); + } +} + +rule("Baptiste Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String( + "Corrode: Regenerative Burst will damage and poison enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Breakthrough: Immortality Field HP threshold increased to 100%; allies inside gain ultimate")); + } +} + +rule("Ashe Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ashe), Button(Ability 2)), Custom String( + "Wildfire: Shooting a burning enemy ignites other nearby enemies")); + Event Player.HeroTalentText[2] = Array(Icon String(Fire), Custom String( + "Flare trigger: Coach gun instantly damages all burning enemies")); + } +} + +rule("D.Va Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(D.Va), Button(Secondary Fire)), Custom String( + "Voltage Grid: Defense Matrix will damage and root enemies it's casted over")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(D.Va), Button(Ability 1)), Custom String( + "Shooting Star: Boosters set enemies on fire")); + } +} + +rule("Genji Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Genji), Button(Ability 1)), Custom String( + "Venomous Strike: Swift Strike poisons enemies; heal for poison damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Genji), Button(Ultimate)), Custom String( + "Dragon's Breath: Dragonblade fires large explosive energy charges")); + } +} + +rule("Hanzo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Hanzo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "Stormbreak: Enemies eliminated by hanzo unleash a thundercloud")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Hanzo), Button(Ability 2)), Custom String( + "Punch II: Storm Arrows deal more damage and stun and knockback enemies")); + } +} + +rule("Widowmaker Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Widowmaker; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Widowmaker), Button(Ultimate)), Custom String( + "Kiss Of Death: Scoped critical hits against enemies below 30% health explode and instantly die")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Widowmaker), Button(Ability 2)), Custom String( + "Epidemic: Enemies hurt by Venom Mine unleash toxic pulses; heal for dealt damage")); + } +} + +rule("McCree Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Cassidy), Button(Ability 2)), Custom String( + "Panic: Flashbang puts enemies in fear; deal +120% more damage to enemies in fear")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Cassidy), Button(Ultimate)), Custom String( + "Clocked: Deadeye deals more damage and knocks enemies down")); + } +} + +rule("Reinhardt Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reinhardt), Button(Ability 2)), Custom String( + "Fire Blast: Fire Strike explodes as it deals damage, setting enemies on fire")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reinhardt), Button(Ultimate)), Custom String( + "Epicenter: Earthshatter travels in all directions")); + } +} + +rule("Soldier: 76 Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ultimate)), Custom String( + "Triple Threat: 2 more rockets are fired alongside Helix Rockets")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Soldier: 76), Button(Ability 1)), Custom String( + "Shoulder Check: Sprinting into enemies will damage and tackle them to the ground")); + } +} + +rule("Torbjörn Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Torbjörn), Button(Ability 2)), Custom String( + "Melting point: Unleash heatwaves during overload and molten core")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Torbjörn), Button(Ultimate)), Custom String( + "Roots Of Magma: Enemies trapped in Molten Core blots cannot move")); + } +} + +rule("Tracer Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Tracer), Button(Ability 2)), Custom String( + "Vortex: Recall pulls and roots enemies towards the activation point")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Tracer), Button(Ultimate)), Custom String( + "Chain Reaction: Pulse Bomb creates chain explosions on enemies damaged by it")); + } +} + +rule("Winston Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Winston), Button(Ability 2)), Custom String( + "Blast Barrier: Barrier Projector damages enemies inside the area")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Winston), Button(Ultimate)), Custom String( + "Next Generation: Eliminations during Primal Rage add +15% ultimate charge towards the next")); + } +} + +rule("Pharah Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Pharah; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ability 2)), Custom String( + "Head Trauma: Concussive Blast stuns and damages enemies for 25% of their max health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Pharah), Button(Ability 1)), Custom String( + "Thunderbird: Gain 150 shields and deal 4x the damage to barriers and objects")); + } +} + +rule("Bastion Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Bomblets: Bullets shot during sentry configuration are explosive")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ability 1)), Custom String( + "Tesla: A powerful mounted laser will autmotically attack one enemy at a time")); + } +} + +rule("Doomfist Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Jump)), Custom String( + "Phase Shifter: Immune to damage while any ability is active")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Doomfist), Button(Ultimate)), Custom String( + "Fissure: Meteor Strike leaves a large fissure behind that burns enemies over it")); + } +} + +rule("Echo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Focusing Optics: Focusing Beam damage ramp starts at 90% health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Streamline: Fire many more sticky bombs per burst")); + } +} + +rule("Junkrat Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Junkrat; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Fire), Custom String("Pyromania: All explosive attacks inflict fire damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Junkrat), Button(Ability 2)), Custom String( + "Short Fused: Steel Trap sets off violent explosions once triggered")); + } +} + +rule("Mei Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mei), Button(Ultimate)), Custom String( + "Cold Snap: Instantly freeze neaerby enemies once Cryo-Freeze expires")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mei), Button(Ability 2)), Custom String( + "Icebound: While Ice Wall is up, Icicles freeze and deal much more damage")); + } +} + +rule("Orisa Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Orisa), Button(Ability 1)), Custom String( + "Immovable Object: During Fortify, become immune and convert 50% of taken damage to healing")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Orisa), Button(Secondary Fire)), Custom String( + "Unstoppable Force: Halt! is much larger and pushes enemies. When triggered, it explodes violently")); + } +} + +rule("Reaper Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reaper), Button(Ability 1)), Custom String( + "shadow streak: shadow step creates a beam that damages enemies who cross")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reaper), Button(Ultimate)), Custom String( + "Loom: Traumatize enemies in front of you when using Wraith Form")); + } +} + +rule("Roadhog Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String("Stench: Roadhog constantly damages enemies nearby")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Roadhog), Button(Ability 1)), Custom String( + "Rusted Anchor: Hook deals more damage; Eliminations will reset hook cooldown")); + } +} + +rule("Sigma Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sigma), Button(Ability 1)), Custom String( + "Gravity Well: Kinetic Grasp gives invincibility")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sigma), Button(Ultimate)), Custom String( + "Gravity Channels: Gravitic Flux damages enemies for 75% of max hp instead of 50%")); + } +} + +rule("Sombra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sombra), Button(Secondary Fire)), Custom String( + "Malware: Enemies hacked or in fear take +100% more damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sombra), Button(Ultimate)), Custom String( + "Glitch: EMP leaves behind a large hack zone ")); + } +} + +rule("Symmetra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Symmetra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "High Voltage: Enemies eliminated by Symmetra explode and damage other enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ultimate)), Custom String( + "Energy Source: While Photon Barrier is active, all players regenerate health and gain ultimate")); + } +} + +rule("Wrecking Ball Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ultimate)), Custom String( + "Mirror Ball: Reflect 100% of taken damage to nearby enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ability 2)), Custom String( + "Distort: Adaptive Shields damages and hacks nearby enemies")); + } +} + +rule("Zarya Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zarya; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Zarya), Button(Ability 1)), Custom String( + "Augment: Health and barrier hp increased by 50%; barrier sized doubled")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Perpetual Energy: secondary inflicts burn damage that continues to last until the enemy dies")); + } +} + +rule("Zenyatta Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Vigor: The ally under the effect of Harmony Orb is immune to damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Zenyatta), Button(Ultimate)), Custom String( + "Perfect Balance: Transcendence damages enemies in a large proximity")); + } +} + +rule("Ana: Sleep Paralysis") +{ + event + { + Player Dealt Damage; + Team 1; + Ana; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Black), Victim, 1); + Wait(0.250, Ignore Condition); + Set Status(Victim, Null, Knocked Down, 5); + } +} + +rule("Ana: Multinade") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.AbilityCountdown = 4; + While(Event Player.AbilityCountdown > 0); + Wait(0.030, Ignore Condition); + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Cancel Primary Action(Event Player); + Wait(0.050, Ignore Condition); + Press Button(Event Player, Button(Ability 2)); + Event Player.AbilityCountdown -= 1; + End; + Wait(2, Ignore Condition); + } +} + +rule("Brigitte: Heavy Iron") +{ + event + { + Player Dealt Damage; + Team 1; + Brigitte; + } + + conditions + { + (Event Ability == Button(Primary Fire) || Event Ability == Button(Ability 1)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Victim, 1.500); + Set Status(Victim, Null, Rooted, 0.500); + Set Environment Credit Player(Victim, Event Player); + } +} + +rule("Brigitte: Endeavor") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Ability Cooldown(Event Player, Button(Secondary Fire)) >= 0.100; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Eye Position(Event Player), 15); + Heal(Players Within Radius(Event Player, 15, Team Of(Event Player), Off), Event Player, 200); + Event Player.DamageDealt *= 2.500; + Set Move Speed(Event Player, 100 * 1.750); + Add Health Pool To Player(Event Player, Armor, Max Health(Event Player) / 2, False, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(Is Dead(Event Player), 6); + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Move Speed(Event Player, 100); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Mercy: Angelic Blessing") +{ + event + { + Player Dealt Healing; + All; + Mercy; + } + + conditions + { + Event Player.Abilities[8] == True; + Healee != Event Player; + Normalized Health(Healee) < True; + } + + actions + { + Set Ultimate Charge(Healee, Ultimate Charge Percent(Healee) + 1); + Wait(0.400, Ignore Condition); + } +} + +rule("Mercy: Aurora") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ultimate(Event Player) == True; + } + + actions + { + Wait(1.500, Ignore Condition); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(All Teams), Event Player, True); + Create Beam Effect(All Players(All Teams), Mercy Heal Beam, Event Player, Event Player.Ability_Projectile1, Color(White), + Visible To Position and Radius); + Event Player.Effects_[3] = Last Created Entity; + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 70, Destination and Rate); + While(Event Player.Ability_End != Event Player.Ability_Projectile1); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Event Player.Ability_Projectile1, 1); + Wait(0.032, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[3]); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 120); + Loop If Condition Is True; + } +} + +rule("Lucio: Healing Wave") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4); + Heal(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 4, 4, Team Of(Event Player), Surfaces), + Event Player, Max Health(Filtered Array(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4, Team Of(Event Player), Surfaces), Is Alive(Current Array Element))) * 0.300); + } +} + +rule("Lucio: Reverse Amp") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + If(Is Using Ability 1(Event Player)); + Set Status(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Rooted, 4); + Else; + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 16.250); + End; + Play Effect(All Players(All Teams), Ring Explosion, Is Using Ability 1(Event Player) ? Color(Green) : Color(Yellow), Event Player, + 1); + Wait(0.400, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Hose") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Event Player.Abilities[8] == True; + Ability Resource(Event Player, Button(Primary Fire)) > False; + } + + actions + { + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Facing Direction Of(Event Player), 15, To World, + Cancel Contrary Motion); + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && !Is In Line of Sight(Current Array Element, Event Player, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Up, 8, To World, Cancel Contrary Motion); + Start Damage Over Time(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), + Distance Between(Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS)), Event Player, 1, 15); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Flourish - Damage") +{ + event + { + Player Dealt Damage; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("[Moira] Flourish - Healing") +{ + event + { + Player Dealt Healing; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Heal(Healee, Event Player, Event Healing * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Healee, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("Baptiste: Corrode") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 20); + Wait(0.200, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 12); + } +} + +rule("Baptiste: Breakthrough") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Status(Event Player, Unkillable) == True; + (Event Player.Abilities[12] ? Players On Hero(Hero(Baptiste), Team Of(Event Player)) : Empty Array).Abilities[12] == True; + } + + actions + { + Heal(Event Player, Event Player, 10000); + Set Status(Event Player, Null, Invincible, 0.800); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ashe: Firebourne") +{ + event + { + Player Dealt Damage; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability == Button(Primary Fire); + Has Status(Victim, Burning) == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Null, Burning, 10); + Start Damage Over Time(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Event Player, 10, 15); + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 5); + Wait(0.250, Ignore Condition); + } +} + +rule("Ashe: Taunt") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Damage(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, Burning)), + Event Player, 125); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Frozen, + 0.016); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Stunned, + 2); + } +} + +rule("D.Va: Voltage Grid") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 2, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 5, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 8, 0.500); + Wait(0.300, Ignore Condition); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Wait(0.016, Ignore Condition); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Loop If Condition Is True; + } +} + +rule("D.Va: Shooting Star") +{ + event + { + Player Dealt Knockback; + Team 1; + D.Va; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, 40); + Set Status(Victim, Null, Burning, 3); + Start Damage Over Time(Victim, Event Player, 3, 35); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 1); + } +} + +rule("Genji: Venomous Strike") +{ + event + { + Player Dealt Damage; + Team 1; + Genji; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 3, 25); + Start Damage Over Time(Victim, Event Player, 3, 25); + Damage(Victim, Event Player, 25); + Heal(Event Player, Event Player, 25); + } +} + +rule("Genji: Dragon's Breath") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is Firing Primary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Good Aura, Color(Lime Green), Event Player.Ability_Projectile1, 1, + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 80, Destination and Rate); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True); + Wait Until(Event Player.Ability_End == Event Player.Ability_Projectile1, 1); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Green), Event Player.Ability_Projectile1, 100); + Play Effect(All Players(All Teams), Bad Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Green), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 100); + } +} + +rule("[Hanzo] Stormbreak (Storm_Effects6)") +{ + event + { + Player Died; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[8] == True; + Hero Of(Attacker) == Hero(Hanzo); + } + + actions + { + Event Player.Storm_Projectile = Eye Position(Event Player); + Event Player.Storm_EndPoint = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Up * 12, Null, + All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Storm_Projectile, Event Player.Storm_EndPoint, 4, Destination and Rate); + Create Effect(All Players(All Teams), Cloud, Color(White), Vector(False, -0.500, False) + Event Player.Storm_Projectile, 4, + Visible To Position and Radius); + Event Player.Storm_Effects[3] = Last Created Entity; + Create Effect(All Players(All Teams), Bad Aura, Color(White), Event Player.Storm_Projectile, 3, Visible To Position and Radius); + Event Player.Storm_Effects[4] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(White), Event Player.Storm_Projectile, 3.500, Visible To Position and Radius); + Event Player.Storm_Effects[5] = Last Created Entity; + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Storm_Projectile, Ray Cast Hit Position( + Event Player.Storm_Projectile, Vector(0.100, 0, 0) + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), + False), Color(Aqua), Visible To Position and Radius); + Event Player.Storm_Effects[6] = Last Created Entity; + While(Distance Between(Event Player.Storm_Projectile, Event Player.Storm_EndPoint) > 1); + Wait(0.600, Ignore Condition); + Damage(Players Within Radius(Ray Cast Hit Position(Event Player.Storm_Projectile, Event Player.Storm_Projectile + Down * 1000, + Null, All Players(All Teams), False), 3, Team Of(Event Player), Surfaces), Attacker, 50); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + End; + Destroy Effect(Event Player.Storm_Effects[3]); + Destroy Effect(Event Player.Storm_Effects[4]); + Destroy Effect(Event Player.Storm_Effects[5]); + Destroy Effect(Event Player.Storm_Effects[6]); + } +} + +rule("Hanzo: Punch II") +{ + event + { + Player Dealt Damage; + Team 1; + Hanzo; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + Hero Of(Victim) != Hero(Torbjörn); + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.800); + Apply Impulse(Victim, Facing Direction Of(Event Player), 12, To World, Cancel Contrary Motion); + Apply Impulse(Victim, Up, 5, To World, Cancel Contrary Motion); + Set Environment Credit Player(Victim, Event Player); + Set Status(Victim, Null, Stunned, 1); + } +} + +rule("Widowmaker: Kiss Of Death") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + (Normalized Health(Victim) <= 0.300 || Event Damage >= Normalized Health(Victim) + Event Damage) == True; + Is Firing Secondary(Event Player) == True; + Event Ability == Button(Primary Fire); + Event Player.Abilities[8] == True; + Event Damage >= 40; + Event Was Critical Hit == True; + } + + actions + { + Kill(Victim, Event Player); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 2), Victim, 3); + Damage(Players Within Radius(Victim, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage * 1.500); + } +} + +rule("Widowmaker: Epidemic") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 8); + Play Effect(All Players(All Teams), Good Explosion, Color(Purple), Victim, 4); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Victim, 16); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Victim, 3); + Start Damage Over Time(Players Within Radius(Victim, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, 50); + Start Heal Over Time(Event Player, Event Player, 3, 50); + Wait(0.500, Ignore Condition); + } +} + +rule("McCree: Panic") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Victim.Feared_until = Total Time Elapsed + 3.500; + } +} + +rule("McCree: Panic - Damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), + Event Player.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 220, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("McCree: Clocked") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Damage(Victim, Event Player, Event Damage * 1.500); + Set Status(Victim, Null, Knocked Down, 3); + } +} + +rule("Reinhardt: Fire Blast") +{ + event + { + Player Dealt Damage; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Start Damage Over Time(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, 20); + Set Status(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Burning, 5); + } +} + +rule("Reinhardt: Epicenter") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is On Ground(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, Knocked Down, 2.500); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 10); + Damage(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, 50); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 20); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 30); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 40); + Wait(5, Ignore Condition); + } +} + +rule("[Soldier: 76] Rocket Assault Rifle") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile2 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(-2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Projectile1 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Position = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, + 0), Event Player, Rotation); + Event Player.Ability_End = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, 0), + Event Player, Rotation); + Chase Player Variable At Rate(Event Player, Ability_Position, Event Player.Ability_Projectile1, 60, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_End, Event Player.Ability_Projectile2, 60, Destination and Rate); + Wait Until(Event Player.Ability_Position == 0 && Event Player.Ability_End == 0, 2.500); + } +} + +rule("[Soldier: 76] First Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile1 != Event Player.Ability_Position; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_Position, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_Position, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_Position, 2.500); + Stop Chasing Player Variable(Event Player, Ability_Position); + Wait(0.016, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 80); + Stop Chasing Player Variable(Event Player, Ability_Position); + Event Player.Ability_Position = 0; + Event Player.Ability_Projectile1 = 0; + Wait(0.016, Ignore Condition); + } +} + +rule("[Soldier: 76] Second Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile2 != Event Player.Ability_End; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_End, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_End, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_End, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_End, 2.500); + Stop Chasing Player Variable(Event Player, Ability_End); + Damage(Players Within Radius(Event Player.Ability_End, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Event Player.Ability_End = 0; + Event Player.Ability_Projectile2 = 0; + } +} + +rule("Soldier: 76 - Init rockets") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile1 = Event Player.Ability_Position; + Event Player.Ability_Projectile2 = Event Player.Ability_End; + } +} + +rule("[Soldier: 76] Shoulder Check") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 3; + Is Alive(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) == True; + } + + actions + { + Damage(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Event Player, 55); + Set Status(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Null, Knocked Down, 1.500); + Apply Impulse(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Facing Direction Of(Event Player), 15, + To World, Cancel Contrary Motion); + Apply Impulse(Event Player, Vector(0, 8, 15), 15, To Player, Cancel Contrary Motion); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Closest Player To(Event Player, Opposite Team Of(Team Of( + Event Player))), 1); + Set Ability Cooldown(Event Player, Button(Melee), 0); + Press Button(Event Player, Button(Melee)); + Wait(1, Ignore Condition); + } +} + +rule("Torbjorn: Melting Point") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Event Player.Abilities[8] == True; + (Is Using Ability 2(Event Player) || Is Using Ultimate(Event Player)) == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Event Player, 8); + Play Effect(All Players(All Teams), Bad Explosion, Color(Yellow), Event Player, 8); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 16); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, + 25); + Set Status(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Off), Null, Burning, 3); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player, 100); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Torbjorn: Roots of Magma") +{ + event + { + Player Dealt Damage; + Team 1; + Torbjörn; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Set Status(Victim, Null, Rooted, 1); + Wait(1, Ignore Condition); + } +} + +rule("Tracer: Vortex") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, 0); + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 10); + Play Effect(All Players(All Teams), Ring Explosion, Color(Red), Position Of(Event Player), 24); + Play Effect(All Players(All Teams), Ring Explosion, Color(Yellow), Position Of(Event Player), 18); + Play Effect(All Players(All Teams), Ring Explosion, Color(Green), Position Of(Event Player), 12); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player), 6); + Set Environment Credit Player(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player); + } +} + +rule("Tracer: Vortex 2") +{ + event + { + Player Received Healing; + Team 2; + All; + } + + conditions + { + Healer.Abilities[8] == True; + Hero Of(Healer) == Hero(Tracer); + Is Using Ability 2(Healer) == True; + Event Ability == Null; + Event Damage <= 20; + } + + actions + { + Apply Impulse(Event Player, Up, 5, To World, Cancel Contrary Motion); + Wait(0.100, Ignore Condition); + Apply Impulse(Event Player, Direction Towards(Event Player, Healer), Distance Between(Event Player, Healer) * 3.500, To World, + Cancel Contrary Motion); + Set Status(Event Player, Null, Rooted, 1.300); + } +} + +rule("Tracer: Chain Reaction") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is True For Any(Filtered Array(All Players(Team Of(Event Player)), Current Array Element.Chain_Reaction_On), Distance Between( + Event Player, Current Array Element) <= 8 && True) == True; + Event Player.Chain_Reaction_Immune == False; + Event Player.Chain_Reaction_On == False; + Is Alive(Event Player) == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Event Player.Chain_Reaction_On = True; + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player, 3); + } +} + +rule("Tracer: Chain Reaction 2") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Event Player.Chain_Reaction_On == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Aqua), Event Player, 3); + Damage(Event Player, Players On Hero(Hero(Tracer), Opposite Team Of(Team Of(Event Player))), 200); + Wait(0.500, Ignore Condition); + Event Player.Chain_Reaction_Immune = True; + Event Player.Chain_Reaction_On = False; + Wait(2, Ignore Condition); + Event Player.Chain_Reaction_Immune = False; + } +} + +rule("Tracer: Chain Reaction 3") +{ + event + { + Player Dealt Damage; + Team 1; + Tracer; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Damage > 20; + Event Player.Abilities[12] == True; + } + + actions + { + Victim.Chain_Reaction_On = True; + } +} + +rule("[Winston] Electric Field") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 65); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Orb, Color(White), Event Player.Ability_Projectile1, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Stop Chasing Player Variable(Event Player, Ability_Resource); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Down * 1000, Null, + All Players(All Teams), False); + Wait(0.100, Ignore Condition); + Event Player.Ability_Resource = 5; + Wait(0.250, Ignore Condition); + Chase Player Variable At Rate(Event Player, Ability_Resource, 20, 7, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, Event Player.Ability_Resource, + Destination and Rate); + Wait(8.650, Restart When True); + Event Player.Ability_Active = False; + } +} + +rule("[Winston] Electric Field 2") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 33); + Play Effect(All Players(All Teams), Ring Explosion, Color(Blue), Event Player.Ability_Projectile1, 10); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 80); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Event Player.Ability_Projectile1, 12); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player.Ability_Projectile1, 125); + } +} + +rule("Winston: Next Generation") +{ + event + { + Player Earned Elimination; + Team 1; + Winston; + } + + conditions + { + Ultimate Charge Percent(Event Player) <= 80; + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 15); + } +} + +rule("Pharah: Head Trauma") +{ + event + { + Player Dealt Knockback; + Team 1; + Pharah; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Victim != Event Player; + } + + actions + { + Damage(Victim, Event Player, Max Health(Victim) * 0.300); + Set Status(Victim, Event Player, Knocked Down, 1); + Play Effect(All Players(All Teams), Good Explosion, Color(Team 1), Victim, 1); + } +} + +rule("Pharah: Thunderbird") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[12] == True; + Hero Of(Event Player) == Hero(Pharah); + } + + actions + { + Event Player.DamageDealt *= 4; + Start Damage Modification(All Players(All Teams), Event Player, 25, Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Add Health Pool To Player(Event Player, Shields, 150, True, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(!Event Player.Abilities[12] || Hero Of(Event Player) != Hero(Pharah), 99999); + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Stop Damage Modification(Event Player.Modification_Damage[1]); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + } +} + +rule("Orisa: Unstoppable Force") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Direction = Facing Direction Of(Event Player); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Sphere, Color(Green), Event Player.Ability_Projectile1, 4, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player) + Facing Direction Of(Event Player) * 0.500; + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 100, Null, All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 25, Destination and Rate); + Wait(0.250, Ignore Condition); + Wait Until((!Event Player.Gen_Available && Is Button Held(Event Player, Button(Secondary Fire))) || ( + Event Player.Ability_Projectile1 == Event Player.Ability_End), 99999); + Stop Chasing Player Variable(Event Player, Ability_Projectile1); + Wait(0.500, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, + 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Orisa: Availability for Halt!") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Available = True; + Wait Until(!Is Button Held(Event Player, Button(Secondary Fire)), 99999); + Event Player.Gen_Available = False; + } +} + +rule("Orisa: Drag effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Player.Ability_Active == True; + } + + actions + { + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Is Alive(Event Player) ? Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of( + Event Player)), Surfaces) : Empty Array, Event Player.Ability_Projectile1), 8, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Event Player.Ability_Projectile1, Event Player.Ability_End), 20, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Up, 5, + To Player, Cancel Contrary Motion); + Wait(0.200, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Orisa: Immoveable Object - Reduce dmg") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Damage Received(Event Player, 100 * 0.003); + Wait Until(!Is Using Ability 1(Event Player), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Orisa: Immovable Object - Healing") +{ + event + { + Player Took Damage; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Event Player, Null, Event Damage * 3); + } +} + +rule("[Reaper] Shadow Streak (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Event Player.Ability_Position = Position Of(Event Player) + Vector(0, 1, 0); + Wait(2, Abort When False); + Event Player.Ability_End = Position Of(Event Player) + Vector(0, 1, 0); + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Ability_End, Event Player.Ability_Position, Color(Black), + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player) || Is Using Ability 2(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage start to end (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players(Opposite Team Of(Team Of( + Event Player))), Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_Position, + Event Player.Ability_End, All Living Players(All Teams), Event Player, True), 1); + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage end to start (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Players(Opposite Team Of(Team Of(Event Player))), + Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_End, + Event Player.Ability_Position, All Living Players(All Teams), Event Player, True), 1); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Reaper: Loom") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Hacked, 1.500); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Rooted, 1.500); + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Event Player, 45); + } +} + +rule("Sigma: Gravity Well") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, 25); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Null, Rooted, 2); + Set Status(Event Player, Null, Invincible, 1); + Play Effect(Event Player, Ring Explosion, Color(Blue), Eye Position(Event Player), 50); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Sigma: Gravity Channels") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ultimate(Event Player)), Event Player, 150, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[12], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Echo: Focusing Optics") +{ + event + { + Player Dealt Damage; + Team 1; + Echo; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Normalized Health(Victim) > 0.500; + Normalized Health(Victim) <= 0.900; + Is Duplicating(Event Player) == False; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 3); + Play Effect(All Players(All Teams), Bad Explosion, Color(Violet), Victim, 0.500); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Wait(0.700, Abort When False); + Cancel Primary Action(Event Player); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Set Projectile Speed(Event Player, 100); + Wait(0.150, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Bomblets") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Is In Alternate Form(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Orange), Null + Ray Cast Hit Position(Eye Position(Event Player), + Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, All Living Players(Opposite Team Of(Team Of( + Event Player))), All Players(Team Of(Event Player)), True), 2); + Damage(Players Within Radius(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 2, + Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 12); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Taser - Loop damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is True For Any(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive(Current Array Element) + && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status(Current Array Element, + Phased Out) && Distance Between(Event Player, Current Array Element) <= 25) == True; + Is Alive(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Explosion Sound, Color(White), Event Player.Ability_Player, 80); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Event Player.Ability_Player, 1); + Event Player.Ability_Player = Filtered Array(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive( + Current Array Element) && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status( + Current Array Element, Phased Out) && Distance Between(Event Player, Current Array Element) <= 25); + Damage(Players Within Radius(Event Player.Ability_Player, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 30); + Wait(0.450, Ignore Condition); + Loop If Condition Is True; + Event Player.Ability_Player = Null; + } +} + +rule("Bastion: Taser - Visual beam") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player + Vector(False, 1, False), + Event Player.Ability_Player != Null ? Event Player.Ability_Player : Event Player, Color(Aqua), + Visible To Position Radius and Color); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[12], 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Sombra: Malware") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, + Hacked) || Current Array Element.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 200, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Sombra: Glitch") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Ability_Active = True; + Event Player.Ability_Position = Position Of(Event Player); + Create Effect(All Players(All Teams), Sphere, Color(Purple), Event Player.Ability_Position, 15, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait(8, Ignore Condition); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Sombra: Glitch - Loop") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Ability_Active == True; + } + + actions + { + Set Status(Players Within Radius(Event Player.Ability_Position, 15, Opposite Team Of(Team Of(Event Player)), Off), Null, Hacked, + 0.750); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Mei: Cold Snap") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Event Player, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Is Using Ability 1(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Damage(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Frozen, 2); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Rooted, 2); + Play Effect(All Players(All Teams), Ring Explosion, Color(White), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Sky Blue), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player) + Vector(0, 1, 0), 20); + } +} + +rule("Mei: Icebound") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Aqua), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Set Projectile Speed(Event Player, 200); + Wait Until(!Is Firing Secondary(Event Player), 99999); + Destroy Effect(Event Player.Effects_[2]); + Set Projectile Speed(Event Player, 100); + } +} + +rule("Mei: Icebound - Icicles hit") +{ + event + { + Player Dealt Damage; + Team 1; + Mei; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 1.250); + Set Status(Victim, Null, Frozen, 1); + Set Status(Victim, Null, Rooted, 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Victim, 1); + } +} + +rule("Wrecking Ball: Mirror Ball") +{ + event + { + Player Took Damage; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 4.500, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage); + Wait(0.100, Ignore Condition); + } +} + +rule("Wrecking Ball: Distort") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Set Status(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Hacked, Count Of( + Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces)) * 1.500); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Violet), Position Of(Event Player), 125); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Sound, Color(Purple), Position Of(Event Player), 16); + Play Effect(All Players(All Teams), Explosion Sound, Color(Violet), Position Of(Event Player), 80); + } +} + +rule("Symmetra: High voltage") +{ + event + { + Player Dealt Final Blow; + Team 1; + Symmetra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Victim, 10); + Play Effect(All Players(All Teams), Bad Explosion, Color(Aqua), Victim, 8); + Damage(Players Within Radius(Victim, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 150); + } +} + +rule("Symmetra: Energy Source") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is True For Any(Players On Hero(Hero(Symmetra), Team Of(Event Player)), Is Using Ultimate(Current Array Element) + && Current Array Element.Abilities[12]) == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 1, 40); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Event Player, 0.100); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Junkrat: Pyromania") +{ + event + { + Player Dealt Knockback; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability != Button(Melee); + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 2, 30); + Set Status(Victim, Null, Burning, 2); + } +} + +rule("Junkrat: Short Fused") +{ + event + { + Player Dealt Damage; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + } + + actions + { + Event Player.Ability_Countdown = 4; + While(Event Player.Ability_Countdown > 0); + Event Player.Ability_Countdown -= 1; + Event Player.Ability_Position = Position Of(Victim) + Vector(Random Real(-2, 2), Random Real(-2, 2), Random Real(-2, 2)); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 4); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Position, 4); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 35); + Set Status(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player, Stunned, 0.800); + Wait(0.200, Ignore Condition); + End; + } +} + +rule("Zenyatta: Vigor") +{ + event + { + Player Dealt Healing; + Team 1; + Zenyatta; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Healee, Null, Invincible, 1); + Wait(0.800, Ignore Condition); + } +} + +rule("Zenyatta: Perfect Balance") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Over Time(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 0.750, 200); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player, 24); + Wait(0.600, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Stench") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Violet), Event Player, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Roadhog: Stench effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 8; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 9); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Rusted Anchor") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ability 1(Event Player)), Event Player, 400, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Roadhog: Rusted Anchor - Reset cooldown") +{ + event + { + Player Earned Elimination; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ability 1(Event Player), 3); + Set Ability Cooldown(Event Player, Button(Ability 1), False); + } +} + +rule("Zarya: Augment") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Scaling Barriers(Event Player, 2, True); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5 + 50; + Set Max Health(Event Player, Event Player.PlayerHealth); + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Zarya), 99999); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Stop Scaling Barriers(Event Player); + } +} + +rule("Zarya: Perpetual Energy") +{ + event + { + Player Dealt Knockback; + Team 1; + Zarya; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Event Player.Abilities[12] == True; + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 9999, 15); + Set Status(Victim, Null, Burning, 9999); + } +} + +rule("Doomfist: Phase Shifter") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + (Is Firing Secondary(Event Player) || Is Using Ability 1(Event Player) || Is Using Ability 2(Event Player)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Event Player, Null, Phased Out, 1); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ultimate(Event Player), 99999); + Event Player.Ability_Position = Position Of(Event Player); + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player), 8); + Event Player.Ability_Active = False; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player.Ability_Position, 16); + While(Event Player.Ability_Active == True); + Damage(Players Within Radius(Event Player.Ability_Position, 8, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 34); + Wait(0.235, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[1]); + Destroy Effect(Event Player.Effects_[2]); + } +} + +rule("Team 1 (Perk): Sharpshooter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Global.Perk[0] == True; + Event Ability != Null; + Distance Between(Event Player, Victim) >= 10; + } + + actions + { + Damage(Victim, Event Player, 50 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Perk): Bulletstorm") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.Perk[1] == True; + (Ammo(Event Player, 0) < Max Ammo(Event Player, 0) || Ammo(Event Player, 1) < Max Ammo(Event Player, 1)) == True; + } + + actions + { + Set Ammo(Event Player, 0, 1000); + Set Ammo(Event Player, 1, 1000); + } +} + +rule("Team 1 Challenges") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + If(Global.Perk[2] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[17] = Last Text ID; + End; + If(Global.Perk[0] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[18] = Last Text ID; + End; + If(Global.Perk[1] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[19] = Last Text ID; + End; + If(Global.MaxHealthDone == 50); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + End; + } +} + +rule("Remove Auto Repair when Player leaves") +{ + event + { + Player Left Match; + Team 1; + All; + } + + actions + { + Global.AutoRepair -= Event Player.Abilities[16]; + } +} + +rule("Refund") +{ + event + { + Subroutine; + Refund; + } + + actions + { + "Refund Money" + Event Player.Money[0] += Event Player.Money[1]; + Event Player.Money[1] = 0; + "Reset Headhunter" + Event Player.Abilities[1] = 0; + "Reset Ambush" + Event Player.Abilities[2] = 0; + "Reset QuickFix" + Event Player.Abilities[3] = 0; + "Reset HeavyWeight" + Event Player.Abilities[4] = 0; + "Reset Charged" + Event Player.Abilities[5] = 0; + "Reset Haste" + Event Player.Abilities[6] = 0; + "Reset HeavyImpact" + Event Player.Abilities[7] = 0; + "Reset HeroTalent1" + Event Player.Abilities[8] = 0; + "Reset SecondWind" + Event Player.Abilities[9] = 0; + "Reset BindingHeal" + Event Player.Abilities[10] = 0; + "Reset Resilience" + Event Player.Abilities[11] = 0; + "Reset HeroTalent2" + Event Player.Abilities[12] = 0; + "Reset Damage" + Event Player.Abilities[13] = 0; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + "Reset Health" + Event Player.Abilities[14] = 0; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + If(Global.MaxHealthDone == 0); + End; + "Reset Healing" + Event Player.Abilities[15] = 0; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + "Reset AutoRepair" + Global.AutoRepair -= Event Player.Abilities[16]; + Event Player.Abilities[16] = 0; + } +} + +rule("Lucio Dash HUD Creation") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + } + + actions + { + If(Event Player.Lucio_Dash_Active == False); + Event Player.Lucio_Dash_Active = True; + Create HUD Text(Event Player, Null, Null, Custom String("{0} Slam on ground - Press: {1}", Ability Icon String(Hero(Wrecking Ball), + Button(Crouch)), Input Binding String(Button(Crouch))), Left, 1000, Color(White), Color(White), Color(White), + Visible To and String, Default Visibility); + Event Player.Lucio_Dash_Icon = Last Text ID; + End; + } +} + +rule("Lucio Dash Remove HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) != Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + } + + actions + { + Destroy HUD Text(Event Player.Lucio_Dash_Icon); + Event Player.Lucio_Dash_Active = False; + } +} + +rule("Lucio Dash") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + Is On Ground(Event Player) == False; + Is Button Held(Event Player, Button(Crouch)) == True; + } + + actions + { + Apply Impulse(Event Player, Down, 20, To World, Cancel Contrary Motion); + } +} + +rule("Ana Self-Nano") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + Ultimate Charge Percent(Event Player) == 100; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Abort If(Global.SelfNanoWorkshopSetting == False && Number Of Players(Team 1) > 1); + Wait(0.100, Ignore Condition); + If(Is Using Ultimate(Event Player) == False); + Create Dummy Bot(Hero(Ana), Team Of(Event Player), -1, Position Of(Event Player) + Backward, Eye Position(Event Player)); + Event Player.AnaEntityID = Last Created Entity; + Wait(0.100, Ignore Condition); + Set Ultimate Charge(Event Player.AnaEntityID, 100); + Start Facing(Event Player.AnaEntityID, Direction Towards(Eye Position(Event Player.AnaEntityID), Position Of(Event Player) + Up), + 1000, To World, Direction and Turn Rate); + Set Invisible(Event Player.AnaEntityID, All); + Set Status(Event Player.AnaEntityID, Null, Phased Out, 9999); + Wait(0.150, Ignore Condition); + Press Button(Event Player.AnaEntityID, Button(Ultimate)); + Set Ultimate Charge(Event Player, 0); + Wait(0.150, Ignore Condition); + Teleport(Event Player.AnaEntityID, Position Of(First Of(Spawn Points(Team Of(Event Player))))); + Wait(10, Ignore Condition); + Destroy Dummy Bot(Team Of(Event Player), Slot Of(Event Player.AnaEntityID)); + End; + } +} + +rule("Reinhard Charge Cancel") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + } + + actions + { + Wait(0.600, Ignore Condition); + Wait Until(Is Button Held(Event Player, Button(Ability 1)), 5); + Set Status(Event Player, Null, Rooted, 0.001); + Wait Until(Event Player.ReinPin, 1); + If(Event Player.ReinPin != 0); + Apply Impulse(Event Player.ReinPin, Facing Direction Of(Event Player), 15, To World, Cancel Contrary Motion); + End; + } +} + +disabled rule("Map Editor Walls") +{ + event + { + Ongoing - Global; + } +} + +rule("Initial Global") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Empty Array; + Global.AllDir = Empty Array; + Global.firstpos = Empty Array; + Global.secondpos = Empty Array; + Global.firstpoint2 = Empty Array; + Global.secondpoint2 = Empty Array; + Global.second = Empty Array; + Global.z = Empty Array; + Global.Wall_ID = Empty Array; + Global.g_beamType = Empty Array; + } +} + +rule("Initial Player") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.filterpos = 0; + Event Player.lastsavedpos = 0; + Event Player.closestbodypos = 0; + Event Player.fullbodypos = 0; + Event Player.prevpos_intersection = 0; + Event Player.active_wall = Empty Array; + Event Player.closestwall = Empty Array; + } +} + +rule("Collision Logic") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Event Player.lastsavedpos = (Eye Position(Event Player) + Position Of(Event Player)) / 2; + Wait(0.016, Ignore Condition); + Event Player.closestwall = Filtered Array(Global.AllPos, Distance Between(Global.AllPos[Current Array Index], Event Player) + <= Distance Between(Global.AllPos[Current Array Index], Global.firstpos[Current Array Index]) + || Event Player.active_wall[Current Array Index] == 1 || (Dot Product(Direction Towards(Current Array Element, + Event Player.lastsavedpos), Global.AllDir[Current Array Index]) > 0) != (Dot Product(Direction Towards(Current Array Element, + Event Player), Global.AllDir[Current Array Index]) > 0)); + For Player Variable(Event Player, x, 0, Count Of(Event Player.closestwall), 1); + Global.z = Index Of Array Value(Global.AllPos, Event Player.closestwall[Event Player.x]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3 || Global.Wall_ID[Global.z] == 5); + If(Y Component Of(Global.firstpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.firstpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.firstpos[Global.z]; + Else If(Y Component Of(Global.secondpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.secondpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.secondpos[Global.z]; + Else; + Event Player.closestbodypos = Position Of(Event Player); + End; + Event Player.fullbodypos = Vector(X Component Of(Eye Position(Event Player)), Y Component Of(Event Player.closestbodypos), + Z Component Of(Eye Position(Event Player))); + Event Player.filterpos = Event Player.fullbodypos + Global.AllDir[Global.z] * Dot Product( + Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) / Dot Product(Global.AllDir[Global.z], + Global.AllDir[Global.z]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3); + If((Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.lastsavedpos), Global.AllDir[Global.z]) > 0) != ( + Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.fullbodypos), Global.AllDir[Global.z]) > 0)); + Event Player.intersection_length = Dot Product(Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) + / Dot Product(Direction Towards(Event Player.lastsavedpos, Event Player.fullbodypos), Global.AllDir[Global.z]); + Event Player.prevpos_intersection = Event Player.fullbodypos + Direction Towards(Event Player.lastsavedpos, + Event Player.fullbodypos) * Vector(1, Empty Array, 1) * Event Player.intersection_length; + If(Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of( + Global.firstpos[Global.z]), Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], + Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of( + Global.firstpos[Global.z]), Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), + Direction Towards(Global.firstpos[Global.z], Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards( + Global.secondpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.prevpos_intersection)) + >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.secondpos[Global.z], Event Player.prevpos_intersection)) >= 0); + Cancel Primary Action(Event Player); + Teleport(Event Player, Event Player.prevpos_intersection + Direction Towards(Event Player.prevpos_intersection, + Event Player.lastsavedpos) * Vector(1, Empty Array, 1) * 2); + End; + End; + End; + Event Player.thickness = 0; + If(Global.Wall_ID[Global.z] == 5); + Event Player.thickness = 4; + Else; + Event Player.thickness = 1; + End; + If(Distance Between(Event Player.fullbodypos, Event Player.filterpos) <= Event Player.thickness && Dot Product(Direction Towards( + Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], Event Player.filterpos)) + >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.firstpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector( + X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), Z Component Of( + Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product( + Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), Y Component Of( + Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], + Event Player.filterpos)) >= 0); + If(!Global.is_Grounded); + Set Gravity(Event Player, 100); + End; + If(Event Player.active_wall[Global.z] == False); + Event Player.active_wall[Global.z] = 1; + If((Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3) && Global.is_Grounded == False); + Set Gravity(Event Player, 100); + Else If(Global.Wall_ID[Global.z] == 5); + Disable Movement Collision With Environment(Event Player, False); + End; + End; + If(Global.Wall_ID[Global.z] == 1); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos) * Vector(1, Empty Array, 1), 0.001, + To World, Cancel Contrary Motion); + Set Move Speed(Event Player, 100 - Dot Product(Direction Towards(Eye Position(Event Player), Eye Position(Event Player) + + World Vector Of(Throttle Of(Event Player), Event Player, Rotation)), Direction Towards(Event Player.filterpos, + Event Player.fullbodypos) * -1) * 100); + Else If(Global.Wall_ID[Global.z] == 3); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos), Speed Of(Event Player), To World, + Cancel Contrary Motion); + End; + Else; + Event Player.active_wall[Global.z] = 0; + Set Move Speed(Event Player, 100); + End; + End; + End; + Loop; + } +} + +rule("Reset") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Count Of(Filtered Array(Event Player.active_wall, Current Array Element != 0)) == 0; + } + + actions + { + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("Effect Creation") +{ + event + { + Ongoing - Global; + } + + actions + { + Wait(5, Ignore Condition); + If(Global.showwalls); + For Global Variable(x, 0, Count Of(Global.AllPos), 1); + If(Global.Wall_ID[Global.x] == 5); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Else; + Skip(Array(14, 0, 5, 10)[Index Of Array Value(Array(1, 2, 3), Global.g_beamType[Global.x]) + 1]); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(9); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(4); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + End; + Wait(0.016, Ignore Condition); + End; + End; + } +} + +rule("Wall Data") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Array(Vector(155.968, 12.470, -30.507), Vector(155.962, 12.472, -62.500), Vector(81.153, 6.453, -103.851), Vector( + 69.148, 6.474, -104.548)); + Global.AllDir = Array(Vector(-1, 0, -0.002), Vector(1, 0, -0.001), Vector(0, 0, 1), Vector(0.001, 0, 1)); + Global.firstpos = Array(Vector(155.971, 11.047, -31.771), Vector(155.964, 11.050, -61.229), Vector(79.761, 5.030, -103.852), + Vector(67.738, 5.022, -104.547)); + Global.secondpos = Array(Vector(155.965, 13.894, -29.242), Vector(155.960, 13.894, -63.771), Vector(82.544, 7.876, -103.851), + Vector(70.558, 7.925, -104.550)); + Global.firstpoint2 = Array(Vector(155.971, 13.894, -31.771), Vector(155.964, 13.894, -61.229), Vector(79.761, 7.876, -103.852), + Vector(67.738, 7.925, -104.547)); + Global.secondpoint2 = Array(Vector(155.965, 11.047, -29.242), Vector(155.960, 11.050, -63.771), Vector(82.544, 5.030, -103.851), + Vector(70.558, 5.022, -104.550)); + Global.z = 3; + Global.g_beamType = Array(1, 1, 1, 1); + Global.showwalls = True; + Global.Wall_ID = Array(5, 5, 5, 5); + } +} + +disabled rule("NEW SHOP") +{ + event + { + Ongoing - Global; + } +} + +rule("Setting Shop Position") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.ShopCamPos = 900 * Up; + Global.ShopPosAngle[1] = Direction From Angles(Horizontal Angle From Direction(Forward), Vertical Angle From Direction(Forward) + - 90); + Global.ShopPosAngle[0] = Cross Product(Global.ShopPosAngle[1], Forward); + Global.ShopBasePos = Global.ShopCamPos - 9 * Global.ShopPosAngle[1] + 142 * Forward; + } +} + +rule("Create Shop Buttons") +{ + event + { + Ongoing - Global; + } + + actions + { + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] + 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] - 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Refund"), + Global.ShopBasePos + 45 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 3, Do Not Clip, Visible To, Color(Green), + Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("[{0}] Leave", + Input Binding String(Button(Reload))), Global.ShopBasePos + 45 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 3, + Do Not Clip, Visible To and String, Color(Green), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("{0}$\n", Local Player.Money[0]), + Global.ShopBasePos + 36.500 * Global.ShopPosAngle[1], 3, Do Not Clip, Visible To and String, Color(White), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("▲"), Update Every Frame( + Global.ShopBasePos - (4 + Vertical Facing Angle Of(Local Player)) * Global.ShopPosAngle[1] + Horizontal Facing Angle Of( + Local Player) * Global.ShopPosAngle[0]), 4, Do Not Clip, Visible To Position and Color, Custom Color( + 245 + 10 * Sine From Radians(4 * Total Time Elapsed), 205 + 50 * Sine From Radians(4 * Total Time Elapsed), + 200 * Sine From Radians(4 * Total Time Elapsed), 255), Default Visibility); + "Headhunter" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[1] ? Custom String("Headhunter II\n  800$") : Custom String("Headhunter I\n  800$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[1] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Ambush" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[2] ? Custom String("Ambush II\n 800$") : Custom String("Ambush I\n 800$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[2] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Quick Fix" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[3] ? Custom String("Quick Fix II\n  700$") : Custom String("Quick Fix I\n  700$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[3] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavyweight" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[4] ? Custom String("Heavyweight II\n  1000$") : Custom String("Heavyweight I\n  1000$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[4] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Charged" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[5] ? Custom String("Charged II\n  700$") : Custom String("Charged I\n  700$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[5] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Haste" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[6] ? Custom String("Haste II\n 700$") : Custom String("Haste I\n 700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[6] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavy Impact" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[7] ? Custom String("Heavy Impact II\n  1000$") : Custom String("Heavy Impact I\n  1000$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[7] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 1" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 1\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[8] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "Second Wind" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[9] ? Custom String("Second Wind II\n   900$") : Custom String("Second Wind I\n   900$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[9] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Binding Heal" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[10] ? Custom String("Binding Heal II\n   700$") : Custom String("Binding Heal I\n   700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[10] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Resilience" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[11] ? Custom String("Resilience II\n  800$") : Custom String("Resilience I\n  800$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[11] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 2" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 2\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[12] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "PlusDamage" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Damage\n  400$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealth" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Health\n 400$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Healing\n  400$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, Visible To and String, + Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "+{0} Auto-Repair\n    400$", Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Global.AutoRepair < 5 ? Color(Green) : Color(Gray), Default Visibility); + "Use Update Every Frame to avoid showing the String when the cursor is out of bounds, resulting in 0\r\n ROW 0" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -33.750 ? Array(Custom String("Leave Buy Menu\n"), Custom String( + ""), Custom String(""), Custom String("Refund your money\n"))[Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) + / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, + Color(White), Default Visibility); + "ROW 1" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 22.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -11.250 ? Array(Custom String("Increase your damage by 5%\n"), + Local Player.Abilities[9] ? Custom String( + "Second Wind II: 60% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds") + : Custom String( + "Second Wind I: 30% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds"), + Local Player.Abilities[5] ? Custom String("Charged II: Ultimates cost 40% less\n") : Custom String( + "Charged I: Ultimates cost 20% less\n"), Local Player.Abilities[1] ? Custom String( + "Headhunter II: Critical hits deal 80% more damage\n") : Custom String("Headhunter I: Critical hits deal 40% more damage\n")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 2" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 36.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 11.250 ? Array(Custom String("Increase your health by 5%\n"), + Local Player.Abilities[10] ? Custom String("Binding Heal II: Heal yourself for 50% the amount when healing allies\n") + : Custom String("Binding Heal I: Heal yourself for 25% the amount when healing allies\n"), + Local Player.Abilities[6] ? Custom String( + " Haste II: Ability cooldown is reduced by 50%\nDoes not affect abilities with multiple charges") : Custom String( + " Haste I: Ability cooldown is reduced by 25%\nDoes not affect abilities with multiple charges"), + Local Player.Abilities[2] ? Custom String("Ambush II: Deal 60% more damage when attacking enemies from behind or above\n") + : Custom String("Ambush I: Deal 30% more damage when attacking enemies from behind or above\n"))[Round To Integer(( + Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 3" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 83.750) < 72.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 33.750 ? Array(Custom String("Increase your healing by 5%\n"), + Local Player.Abilities[11] ? Custom String("Resilience II: Take 30% less damage while below 60% health\n") : Custom String( + "Resilience I: Take 30% less damage while below 30% health\n"), Local Player.Abilities[7] ? Custom String( + "Heavy Impact II: Every hit has a chance to stun the enemy for 2 seconds\n") : Custom String( + "Heavy Impact I: Every hit has a chance to stun the enemy for 1 second\n"), Local Player.Abilities[3] ? Custom String( + "Quick Fix II: Eliminations restore 100 HP and shortly increase speed by 40%\n") : Custom String( + "Quick Fix I: Eliminations restore 50 HP and shortly increase speed by 20%\n"))[Round To Integer((Horizontal Facing Angle Of( + Local Player) + 90) / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, + Visible To and String, Color(White), Default Visibility); + "ROW 4" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 133) < 99.250 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 56.250 ? Array(Custom String( + "Increase your auto-repair by {0}/5s\n", Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Custom String("{0}", Local Player.HeroTalentText[2][1]), Custom String("{0}", Local Player.HeroTalentText[1][1]), + Local Player.Abilities[4] ? Custom String( + "Heavyweight II: Your knock back attacks deal 50% more damage and knock back\n            You receive 33% less knock back") + : Custom String( + "Heavyweight I: Your knock back attacks deal 25% more damage and knock back\n            You receive 20% less knock back")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + } +} + +rule("Toggle Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + !Is Dummy Bot(Event Player) == True; + Is Button Held(Event Player, Button(Reload)) == True; + !Is Communicating Any Emote(Event Player) == True; + } + + actions + { + If(Event Player.isInMenu == False); + Wait Until(!Is Button Held(Event Player, Button(Reload)), 0.500); + If(!Is Button Held(Event Player, Button(Reload))); + Abort; + End; + End; + Event Player.isInMenu = !Event Player.isInMenu; + } +} + +rule("Open Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == True; + } + + actions + { + Event Player.PlayerFacing = Facing Direction Of(Event Player); + Start Camera(Event Player, Global.ShopCamPos, Global.ShopCamPos + Forward, 0); + Disable Hero HUD(Event Player); + Call Subroutine(DisablePlayer); + Set Aim Speed(Event Player, 200); + } +} + +rule("Close Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == False; + } + + actions + { + Stop Camera(Event Player); + Enable Hero HUD(Event Player); + Call Subroutine(EnablePlayer); + Set Aim Speed(Event Player, 100); + Set Facing(Event Player, Event Player.PlayerFacing, To World); + } +} + +rule("Subroutine: Disable Player") +{ + event + { + Subroutine; + DisablePlayer; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + Set Primary Fire Enabled(Event Player, False); + Set Secondary Fire Enabled(Event Player, False); + Set Ability 1 Enabled(Event Player, False); + Set Ability 2 Enabled(Event Player, False); + Set Melee Enabled(Event Player, False); + Set Jump Enabled(Event Player, False); + Set Crouch Enabled(Event Player, False); + Disallow Button(Event Player, Button(Ultimate)); + } +} + +rule("Subroutine: Enable Player") +{ + event + { + Subroutine; + EnablePlayer; + } + + actions + { + Stop Forcing Throttle(Event Player); + Set Primary Fire Enabled(Event Player, True); + Set Secondary Fire Enabled(Event Player, True); + Set Ability 1 Enabled(Event Player, True); + Set Ability 2 Enabled(Event Player, True); + Set Melee Enabled(Event Player, True); + Set Jump Enabled(Event Player, True); + Set Crouch Enabled(Event Player, True); + Allow Button(Event Player, Button(Ultimate)); + } +} + +rule("Buy Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Primary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + Event Player.isInMenu = !Event Player.isInMenu; + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Money[1] != 0); + Call Subroutine(Refund); + Else; + Small Message(Local Player, Custom String("You don't have anything to refund!")); + End; + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[13] += 1; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 2); + If(Event Player.Money[0] >= 900); + Event Player.Money[0] -= 900; + Event Player.Money[1] += 900; + Event Player.Abilities[9] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[5] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[1] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[14] += 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[10] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[6] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[2] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[15] += 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[11] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[7] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[3] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Global.AutoRepair != 5); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Global.AutoRepair += 1; + Event Player.Abilities[16] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[12] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[8] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[4] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + End; + } +} + +rule("Refund Single Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Secondary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[13] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[13] -= 1; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 0); + Event Player.Money[0] += 900; + Event Player.Money[1] -= 900; + Event Player.Abilities[9] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[5] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[1] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[14] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[14] -= 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[10] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[6] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[2] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[15] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[15] -= 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[11] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[7] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[3] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[16] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Global.AutoRepair -= 1; + Event Player.Abilities[16] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[12] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[8] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[4] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + End; + } +} + +rule("Create Player HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Custom String("{0}{1}", + Event Player, Event Player.isInMenu ? Custom String("(In Shop)") : Custom String("")), Custom String("{0}{1}", Is Alive( + Event Player) ? Custom String("{0} HP", Round To Integer(Health(Event Player), Up)) : Custom String("Dead"), Custom String( + ", {0}$", Event Player.Money)), Left, Local Player == Event Player ? -1 : Slot Of(Event Player), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), + Visible To Sort Order String and Color, Default Visibility); + Create HUD Text(Event Player.Abilities[13] || Global.DamageDone ? Event Player : Null, Null, Null, Custom String("+{0}% Damage", + Global.DamageDone + Event Player.Abilities[13] * 5), Left, 913, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[9] ? Event Player : Null, Null, Null, Custom String("Second Wind {0}", + Event Player.Abilities[9] == 1 ? Custom String("I") : Custom String("II")), Left, 908, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[5] ? Event Player : Null, Null, Null, Custom String("Charged {0}", + Event Player.Abilities[5] == 1 ? Custom String("I") : Custom String("II")), Left, 905, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[1] ? Event Player : Null, Null, Null, Custom String("Headhunter {0}", + Event Player.Abilities[1] == 1 ? Custom String("I") : Custom String("II")), Left, 901, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[14] || Global.MaxHealthDone ? Event Player : Null, Null, Null, Custom String("+{0}% Health", + Global.MaxHealthDone + Event Player.Abilities[14] * 5), Left, 914, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[10] ? Event Player : Null, Null, Null, Custom String("Binding Heal {0}", + Event Player.Abilities[10] == 1 ? Custom String("I") : Custom String("II")), Left, 909, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[6] ? Event Player : Null, Null, Null, Custom String("Haste {0}", + Event Player.Abilities[6] == 1 ? Custom String("I") : Custom String("II")), Left, 906, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[2] ? Event Player : Null, Null, Null, Custom String("Ambush {0}", + Event Player.Abilities[2] == 1 ? Custom String("I") : Custom String("II")), Left, 902, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[15] ? Event Player : Null, Null, Null, Custom String("+{0}% Healing", + Event Player.Abilities[15] * 5), Left, 915, Color(White), Color(White), Color(Turquoise), Visible To and String, + Default Visibility); + Create HUD Text(Event Player.Abilities[11] ? Event Player : Null, Null, Null, Custom String("Resilience {0}", + Event Player.Abilities[11] == 1 ? Custom String("I") : Custom String("II")), Left, 910, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[7] ? Event Player : Null, Null, Null, Custom String("Heavy Impact {0}", + Event Player.Abilities[7] == 1 ? Custom String("I") : Custom String("II")), Left, 907, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[3] ? Event Player : Null, Null, Null, Custom String("Quick Fix {0}", + Event Player.Abilities[3] == 1 ? Custom String("I") : Custom String("II")), Left, 903, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Global.AutoRepair ? Event Player : Null, Null, Null, Custom String("{0} total Auto-Repair/5s", + Global.AutoRepair * (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5)), Left, 916, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[2][0], Event Player.HeroTalentText[2][1]), Top, 902, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("Hero Talent 2"), Left, 912, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[1][0], Event Player.HeroTalentText[1][1]), Top, 901, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("Hero Talent 1"), Left, 911, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[4] ? Event Player : Null, Null, Null, Custom String("Heavyweight {0}", + Event Player.Abilities[4] == 1 ? Custom String("I") : Custom String("II")), Left, 904, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + } +} + +rule("Rein Pin detect") +{ + event + { + Player Dealt Knockback; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 1); + Has Status(Victim, Stunned) == True; + } + + actions + { + Event Player.ReinPin = Victim; + Wait(1, Ignore Condition); + Event Player.ReinPin = Null; + } +} + +rule("Boss Rotation") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.activeBoss == True; + } + + actions + { + If(Global.bossRotation == 0 || Global.bossRotation == 3); + Global.bossRotation = 1; + Global.lastBoss[1] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 1); + Global.bossRotation = 2; + Global.lastBoss[2] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 2); + Global.bossRotation = 3; + Global.lastBoss[3] = Hero Of(Global.activeBoss); + End; + } +} + +rule("15 minutes hud") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 10; + } + + actions + { + Create HUD Text(All Players(Team 1), Global.activeBoss ? Custom String("Boss: {0}, HP: {1}/{2}", Hero Of(Global.activeBoss), + Health(Global.activeBoss), Max Health(Global.activeBoss)) : Custom String(""), Null, Null, Top, 900, Color(Red), Color(White), + Color(White), Visible To and String, Default Visibility); + } +} + +rule("debug") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + (Is Button Held(Event Player, Button(Primary Fire)) && Is Button Held(Event Player, Button(Crouch))) == True; + } + + actions + { + Global.TimeSec = 59; + } +} + +disabled rule("debug") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + } + + actions + { + Create HUD Text(Local Player, Custom String("{0}", Position Of(Local Player)), Null, Null, Left, 0, Color(Yellow), Color(White), + Color(White), Visible To and String, Default Visibility); + Set Status(Event Player, Null, Invincible, 9999); + Set Status(Event Player, Null, Phased Out, 9999); + } +} + +rule("ending 1 part 1") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + } + + actions + { + Big Message(All Players(Team 1), Custom String("Exfiltration available! (optional - ends the mode)")); + Create In-World Text(All Players(Team 1), Custom String( + "Exfiltration available! Gather here!\n{0}/{1} Players ready to exfiltrate!", Count Of(Filtered Array(All Players(Team 1), + Distance Between(Vector(186, 11, -46.500), Current Array Element) <= 9)), Count Of(All Players(Team 1))), Vector(186, 15, + -46.500), 1.200, Do Not Clip, Visible To and String, Color(Green), Default Visibility); + } +} + +rule("ending 1 part 2") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + Distance Between(Vector(186, 11, -46.500), All Players(Team 1)) <= 9; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GG! YOU DID IT!")); + Destroy All Dummy Bots; + Disable Movement Collision With Environment(All Players(Team 1), True); + Start Accelerating(All Players(Team 1), Up, 100, 5, To World, Direction Rate and Max Speed); + Wait(5, Ignore Condition); + Declare Team Victory(Team 1); + } +} + +rule("Team 1 (Ability): Second Wind save life") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[9] == True; + Event Player.secondWindActive == True; + Health(Event Player) == 1; + } + + actions + { + Small Message(All Players(All Teams), Custom String("{0} received a second wind!", Event Player)); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Green), Event Player, 1); + Clear Status(Event Player, Unkillable); + Set Player Health(Event Player, Max Health(Event Player)); + Event Player.lastSecondWind = 30; + Event Player.secondWindActive = 0; + } +} + +rule("Team 1 (Ability): Second Wind after buying") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[9] == True; + Event Player.secondWindActive == False; + Event Player.lastSecondWind == 0; + } + + actions + { + If(Random Integer(1, 100) > Event Player.Abilities[9] * 30); + Wait(30, Ignore Condition); + Loop; + End; + Set Status(Event Player, Null, Unkillable, 9999); + Event Player.secondWindActive = 1; + } +} + +rule("Team 1 (Ability): Second Wind counter") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Player.lastSecondWind > 0; + } + + actions + { + Wait(1, Ignore Condition); + Event Player.lastSecondWind -= 1; + Loop If Condition Is True; + } +} \ No newline at end of file diff --git a/defendTheCastleExtended/old_versions/c122.ow b/defendTheCastleExtended/old_versions/c122.ow new file mode 100644 index 0000000..c3abe4c --- /dev/null +++ b/defendTheCastleExtended/old_versions/c122.ow @@ -0,0 +1,9311 @@ +settings +{ + main + { + Description: "Defend Castle v0.6.c122 by HuKuTa94#2589 modified by ShuriZma#2349 - J1K6F (Code Version: v090) - Defend the gate, kill enemies and don't allow them to damage the gate! Torb, Brig and Rein can repair the gate but beware! You never know what the enemy might be hiding until now! Special Thanks to: Shingen#21859 for the Abilities, LemonAid#11644 for the Hero Talents & Josbird for teaching me about Menus! Find the Original Mode on: workshop.codes/BQEGS PS: SHINGEN PLS COME BACK" + Mode Name: "Defend Castle v0.6.c122" + } + + lobby + { + Max Spectators: 0 + Max Team 1 Players: 4 + Max Team 2 Players: 0 + Return To Lobby: Never + Swap Teams After Match: No + } + + modes + { + Escort + { + enabled maps + { + Havana + } + } + + Team Deathmatch + { + enabled maps + { + } + } + + General + { + Game Mode Start: Immediately + Spawn Health Packs: Disabled + } + } + + workshop + { + Ana can nano herself even if there are other players only if no player targeted: On + Story Heroes: Off + } + + extensions + { + Beam Effects + Kinetic Explosion Effects + Explosion Sounds + Play More Effects + Spawn More Dummy Bots + } +} + +variables +{ + global: + 0: GatePosition + 1: ZenSpawnPositions + 2: SpawnPositionMaxId + 3: LoopIterator1 + 4: BigBossSpawnPositions + 5: PlayerSpawnPositions + 6: GateHealthChase + 7: GateHealth + 8: GateMaxHealth + 9: GateProgressBarColorCurrent + 10: GateProgressBarColorComponent + 11: GateHealthEvent + 12: BastionTargetPositions + 13: SniperPositions + 14: BallSpawnPositions + 15: ZenRespawnTime + 16: TimeMin + 17: TimeSec + 18: DefaultCurrentBot + 19: DefaultHeroBotsPool + 20: DefaultHeroBotsPoolCurrentId + 21: IsDebug + 22: BotOrisaParent + 23: IsStoryHeroes + 24: BotOrisaChild + 25: GateRepairPosition + 26: BotOrisaTargetPosition + 27: BotEchoRespawnPosition + 28: BotEchoTeleportPositions + 29: UpgradeGateMaxHealthValue + 30: UpgradeGateMaxHealthHudId + 31: UpgradePlayerMaxHealthValue + 32: UpgradePlayerMaxHealthHudId + 33: UpgradeCriticalDamageValue + 34: UpgradeCriticalDamageHudId + 35: UpgradeMaxAmmoValue + 36: UpgradeMaxAmmoHudId + 37: UpgradeMaxAmmoMaxValue + 38: UpgradePlayerMaxHealthMaxValue + 39: UpgradeCriticalDamageMaxValue + 40: UpgradeGateMaxHealthMaxValue + 41: DamageDone + 42: IsDebugAINavigation + 43: GameLogicCountOfUniqueHeroes + 44: IsNewWaveGameLogicProcessing + 45: AutoRepair + 46: UpgradePerkSharpshooterValue + 47: Perk + 48: MaxHealthDone + 49: StartMoney + 50: Time5Min + 51: SelfNanoWorkshopSetting + 52: ShopCamPos + 53: ShopBasePos + 54: ShopPosAngle + 55: activeBoss + 56: bossTrigger + 57: bossRotation + 58: lastBoss + 59: Time10Min + 60: MoneyMult + 61: challengeCount + 62: UpgradeBossHealthValue + 112: AllPos + 113: AllDir + 114: firstpos + 115: secondpos + 116: firstpoint2 + 117: secondpoint2 + 118: second + 119: z + 120: Wall_ID + 121: showwalls + 122: is_Grounded + 123: g_beamType + 124: x + 125: NodePositions + 126: NodeConnections + 127: DistanceMatrix + + player: + 0: BotSeePlayer + 1: BotDoesUniqueBehaviour + 2: BotEffects + 3: BotRayCastHitPosition + 4: BotEventPosition + 5: CurrentHero + 6: IsDead + 7: IsRespawning + 8: BotBastionArtilleryDidShotsCount + 9: BotCounter + 10: HasBadStatus + 11: EventHealth + 12: HealOverTimeId + 13: BotIsOrisaChild + 14: BotEchoCapturedPlayer + 15: BotPlayersInRadius + 16: BotLoopIterator2 + 17: BotWidowShotTime + 18: BotWidowTeleportTime + 19: IsNanoed + 20: AbilityHUD + 21: Lucio_Dash_Active + 22: Lucio_Dash_Icon + 23: AnaEntityID + 24: Abilities + 25: Money + 26: HeroTalentText + 27: DamageDealt + 28: PlayerHealth + 29: AbilityCountdown + 30: HP_Pool + 31: Effects_ + 32: Ability_Projectile1 + 33: Ability_End + 34: Storm_Projectile + 35: Storm_EndPoint + 36: Storm_Effects + 37: Feared_until + 38: Modification_Damage + 39: Ability_Projectile2 + 40: Ability_Position + 41: Chain_Reaction_On + 42: Chain_Reaction_Immune + 43: Ability_Active + 44: Ability_Resource + 45: secondWindActive + 46: isInMenu + 47: ReinPin + 48: PlayerFacing + 49: isBoss + 50: Gen_Direction + 51: Gen_Available + 52: Ability_Player + 53: Ability_Countdown + 54: lastSecondWind + 105: filterpos + 106: lastsavedpos + 107: closestbodypos + 108: fullbodypos + 109: prevpos_intersection + 110: active_wall + 111: closestwall + 112: x + 113: intersection_length + 114: thickness + 115: BotCancelPathFinding + 116: BotLoopIterator1 + 117: BotTempArray + 118: BotTargetPlayer + 119: BotTargetPosition + 120: BotClosestNodeIdToTarget + 121: BotClosestNodeIdToBot + 122: BotPrevNodeId + 123: BotNextNodeId + 124: BotNextNodePosition + 125: BotCurrentDistanceToTarget + 126: BotShortestDistanceToTarget + 127: BotIsPathFinding +} + +subroutines +{ + 0: BotBastionArtilleryDamage + 1: BotBastionFlameGunDamage + 2: BotBastionRespawn + 3: GateProgressBarColor + 4: BotZenyattaRespawn + 5: BotWidowRespawn + 6: BotBallRespawn + 7: GameLogicAddNextHeroInGame + 8: BotOrisaRespawn + 9: BotLandingFromSky + 10: BotEchoRespawn + 11: BotEchoDetachPlayer + 12: BotEchoFlyToPlayer + 13: BotEchoFlyToPortal + 14: GameLogicSetBotProperties + 15: DisablePlayer + 16: BotApearFromUnderground + 17: BotReinRespawn + 18: PlayerInit + 19: BotInit + 20: PlayerRespawn + 21: BotRespawn + 22: BotWidowBadStatus + 23: GameLogicWave0 + 24: Refund + 25: EnablePlayer + 26: GateRepair + 124: BotStartPathFinding + 125: BotGetClosestNodeIdToTarget + 126: BotGetNextNodeIdAndPosition + 127: BotResetPathFinding +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("MAP: HAVANA") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Havana); + } + + actions + { + Global.NodePositions = Array(Vector(147.588, 6.425, -46.749), Vector(136.181, 6.425, -57.159), Vector(130.189, 6.425, -63.781), + Vector(123.305, 6.425, -57.983), Vector(125.678, 6.504, -46.633), Vector(114.485, 7.471, -46.699), Vector(138.743, 6.425, + -32.974), Vector(126.498, 6.425, -39.920), Vector(124.572, 10.434, -34.300), Vector(138.605, 5.359, -18.647), Vector(119.009, + 2.331, -31.024), Vector(121.138, 5.228, -19.933), Vector(126.722, 6.425, -29.505), Vector(102.762, 3.157, -33.609), Vector( + 76.030, 7.418, -74.087), Vector(83.720, 9.425, -33.744), Vector(97.439, 7.238, -42.379), Vector(86.252, 12.416, -47.261), + Vector(65.178, 11.425, -73.187), Vector(97.466, 7.269, -50.596), Vector(113.039, 7.424, -37.337), Vector(106.179, 7.450, + -46.143), Vector(90.086, 7.411, -44.653), Vector(78.752, 7.418, -62.140), Vector(82.124, 7.428, -44.229), Vector(90.675, 7.231, + -51.234), Vector(85.717, 4.692, -63.446), Vector(90.830, 4.330, -70.697), Vector(102.425, 2.387, -72.817), Vector(81.443, + 4.425, -81.648), Vector(70.743, 6.418, -81.495), Vector(69.738, 6.419, -96.344), Vector(127.586, 12.643, -63.344), Vector( + 118.911, 13.468, -58.008), Vector(102.885, 1.092, -56.579), Vector(100.009, 2.967, -67.139), Vector(106.703, 0.465, -44.628), + Vector(81.695, 7.418, -52.140), Vector(126.979, 12.393, -55.079), Vector(153.720, 18.578, -21.745), Vector(155.301, 18.619, + -17.595), Vector(133.043, 10.425, -26.625), Vector(114.646, 7.278, -57.336), Vector(95.160, 3.688, -81.194), Vector(78.456, + 5.418, -93.581), Vector(75.455, 5.418, -101.492), Vector(148.071, 9.432, -32.123), Vector(146.706, 9.425, -27.858), Vector( + 144.273, 9.445, -63.119), Vector(144.278, 9.454, -58.447)); + Global.NodeConnections = Array(Array(1, 6, 4, 7), Array(2, 1, 4, 6, 7, 0, 49), Array(1, 3), Array(2, 4, 42), Array(3, 1, 5, 7, 6, + 1, 0), Array(4, 7, 20, 21, 19, 16, 42), Array(7, 1, 4, 1, 9, 12, 0, 46), Array(4, 5, 6, 1, 1, 12, 0), Array(7, 41), Array(6, + 11), Array(11, 13), Array(9, 10, 13), Array(6, 7, 10), Array(10, 16, 36), Array(18, 23, 30), Array(17, 24), Array(13, 19, 22, + 21, 25, 5), Array(15, 22, 25, 23), Array(14), Array(16, 21, 22, 26, 27, 35, 25, 5), Array(5, 13, 10), Array(19, 16, 5, 13, 22, + 34), Array(16, 19, 21, 24, 25), Array(14, 25, 26, 37), Array(22, 15, 37), Array(23, 22, 19, 16, 26, 27, 35, 37), Array(25, 19, + 27, 35, 29), Array(19, 26, 25, 29, 35, 43), Array(35, 34, 43), Array(27, 26, 30, 43, 44), Array(29, 14, 31), Array(30, 29, 45), + Array(33, 38, 1, 48), Array(32, 38, 42), Array(35, 36, 28), Array(28, 19, 25, 27, 26, 34), Array(13, 34), Array(25, 23, 24), + Array(5, 4, 1, 6, 1, 32, 33, 0), Array(40), Array(39), Array(6, 8, 47, 46), Array(3, 5, 34), Array(28, 27, 29, 44), Array(29, + 43, 45), Array(44, 31), Array(6, 47), Array(46, 41), Array(49, 32), Array(1, 0, 6, 48)); + Global.DistanceMatrix = Array(Array(0, 1, 2, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, + 4, 5, 4, 4, 5, 5, 5, 0, 0, 4, 3, 5, 6, 7, 2, 3, 3, 2), Array(1, 0, 1, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, + 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 3, 4, 4, 4, 5, 5, 4, 0, 0, 4, 3, 5, 6, 7, 2, 3, 2, 1), Array(2, 1, 0, 1, 2, 3, 2, 2, 6, 3, 4, 4, + 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 4, 6, 7, 8, 4, 5, 3, 4, 4, 6, 5, 0, 0, 5, 2, 5, 6, 7, 3, 4, 3, 2), Array(2, 2, + 1, 0, 1, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, 5, 6, 2, 3, 3, 5, 6, 0, 0, 5, 1, 4, + 5, 6, 3, 4, 4, 3), Array(1, 1, 2, 1, 0, 1, 1, 1, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, + 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, 2, 3, 3, 2), Array(2, 2, 3, 2, 1, 0, 2, 1, 6, 3, 2, 3, 2, 2, 4, 4, 1, 5, 5, 1, 1, 1, 2, 3, + 3, 2, 2, 2, 3, 3, 4, 5, 5, 6, 2, 2, 3, 3, 6, 0, 0, 5, 1, 3, 4, 5, 3, 4, 4, 3), Array(1, 1, 2, 2, 1, 2, 0, 1, 4, 1, 2, 2, 1, 3, + 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 4, 5, 4, 4, 4, 5, 5, 0, 0, 3, 3, 5, 6, 7, 1, 2, 3, 2), Array(1, 1, 2, 2, + 1, 1, 1, 0, 5, 2, 2, 3, 1, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, + 2, 3, 3, 2), Array(2, 2, 3, 3, 2, 2, 2, 1, 0, 3, 3, 4, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, + 5, 5, 6, 0, 0, 1, 3, 5, 6, 7, 2, 2, 4, 3), Array(2, 2, 3, 3, 2, 3, 1, 2, 5, 0, 2, 1, 2, 2, 6, 6, 3, 7, 7, 4, 4, 4, 4, 5, 5, 4, + 5, 5, 5, 6, 7, 8, 5, 6, 4, 5, 3, 5, 6, 0, 0, 4, 4, 6, 7, 8, 2, 3, 4, 3), Array(4, 4, 5, 5, 4, 3, 3, 4, 7, 2, 0, 1, 4, 1, 5, 5, + 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 7, 8, 3, 4, 2, 4, 8, 0, 0, 6, 4, 5, 6, 7, 4, 5, 6, 5), Array(3, 3, 4, 4, 3, 3, + 2, 3, 6, 1, 1, 0, 3, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 6, 7, 3, 4, 2, 4, 7, 0, 0, 5, 4, 5, 6, 7, 3, 4, + 5, 4), Array(2, 2, 3, 3, 2, 2, 1, 1, 5, 2, 1, 2, 0, 2, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, 3, 5, + 6, 0, 0, 4, 3, 5, 6, 7, 2, 3, 4, 3), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 3, 1, 2, 4, 0, 4, 4, 1, 5, 5, 2, 3, 2, 2, 3, 3, 2, 3, 3, + 3, 4, 5, 6, 7, 8, 2, 3, 1, 3, 8, 0, 0, 7, 3, 4, 5, 6, 5, 6, 6, 5), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 5, 6, 6, 4, 0, 4, 3, 5, + 1, 3, 5, 4, 3, 1, 3, 2, 2, 3, 4, 2, 1, 2, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 3, 3, 3, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, + 5, 10, 7, 5, 6, 6, 4, 3, 0, 3, 1, 4, 3, 5, 3, 2, 2, 1, 2, 3, 3, 4, 4, 4, 5, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 4, 5, 6, 7, 8, + 8, 7), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 3, 3, 0, 4, 4, 1, 2, 1, 1, 2, 2, 1, 2, 2, 3, 3, 4, 5, 6, 7, 2, 2, 2, 2, + 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 1, 2, 0, 3, 2, 4, 2, 1, 1, 2, 1, 2, 2, + 3, 3, 3, 4, 8, 9, 3, 2, 4, 2, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 6, 7, 7, 5, 1, 5, 4, 6, + 0, 4, 6, 5, 4, 2, 4, 3, 3, 4, 5, 3, 2, 3, 10, 11, 5, 4, 6, 3, 11, 0, 0, 10, 6, 4, 4, 4, 8, 9, 9, 8), Array(3, 3, 4, 3, 2, 1, 3, + 2, 7, 4, 3, 4, 3, 2, 3, 3, 1, 4, 4, 0, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 3, 4, 6, 7, 2, 1, 3, 2, 7, 0, 0, 6, 2, 2, 3, 4, 4, 5, 5, + 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 3, 1, 2, 3, 1, 5, 5, 2, 6, 6, 2, 0, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 6, 7, 3, 3, 2, 4, 7, + 0, 0, 6, 2, 4, 5, 6, 4, 5, 5, 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 4, 3, 1, 4, 5, 1, 2, 0, 1, 3, 2, 2, 2, 2, 2, + 3, 4, 5, 6, 7, 1, 2, 2, 3, 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 3, 2, 1, 3, 4, + 1, 3, 1, 0, 2, 1, 1, 2, 2, 3, 3, 4, 5, 7, 8, 2, 2, 3, 2, 8, 0, 0, 7, 3, 3, 4, 5, 5, 6, 6, 5), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, + 6, 4, 5, 5, 3, 1, 3, 2, 4, 2, 2, 4, 3, 2, 0, 2, 1, 1, 2, 3, 2, 2, 3, 8, 9, 3, 2, 4, 1, 9, 0, 0, 8, 4, 3, 3, 4, 6, 7, 7, 6), + Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 3, 1, 2, 2, 4, 2, 4, 2, 1, 2, 0, 2, 3, 3, 4, 4, 4, 5, 8, 9, 3, 3, 4, 1, 9, 0, + 0, 8, 4, 4, 5, 6, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 2, 3, 1, 4, 3, 1, 3, 2, 1, 1, 2, 0, 1, 1, 2, 2, + 3, 4, 7, 8, 2, 1, 3, 1, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, + 3, 2, 2, 2, 3, 1, 0, 1, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 2, 2, 3, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, + 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 0, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 1, 2, 3, 5, 6, 6, 5), Array( + 5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 4, 5, 3, 6, 5, 2, 4, 3, 3, 3, 4, 2, 2, 2, 0, 2, 3, 4, 8, 9, 1, 1, 2, 3, 9, 0, 0, 8, + 4, 1, 2, 3, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 2, 5, 3, 6, 3, 2, 4, 3, 3, 3, 4, 2, 1, 1, 2, 0, 1, 2, + 8, 9, 3, 2, 4, 3, 9, 0, 0, 8, 4, 1, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 1, 5, 4, 6, 2, 3, 5, 4, + 4, 2, 4, 3, 2, 2, 3, 1, 0, 1, 9, 10, 4, 3, 5, 3, 10, 0, 0, 9, 5, 2, 2, 2, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, + 7, 6, 5, 2, 6, 4, 7, 3, 3, 5, 4, 4, 3, 5, 3, 2, 2, 3, 1, 1, 0, 9, 10, 4, 3, 5, 4, 10, 0, 0, 9, 5, 2, 2, 1, 7, 8, 8, 7), Array( + 2, 1, 2, 3, 2, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 4, 5, 6, 7, 0, 1, 3, 4, 4, 5, 1, 0, 0, 5, + 2, 5, 6, 7, 3, 4, 1, 2), Array(2, 2, 3, 2, 2, 2, 2, 3, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, + 1, 0, 2, 3, 3, 5, 1, 0, 0, 5, 1, 4, 5, 6, 3, 4, 2, 3), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 5, 3, 4, 5, 2, 4, 5, 3, 6, 5, 2, 4, 3, + 3, 3, 4, 2, 2, 2, 1, 3, 4, 5, 8, 9, 0, 1, 1, 3, 9, 0, 0, 8, 4, 2, 3, 4, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, + 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 1, 1, 2, 3, 4, 7, 8, 1, 0, 2, 2, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(5, 5, + 6, 5, 4, 3, 5, 4, 9, 4, 2, 3, 5, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 8, 9, 1, 2, 0, 4, 9, 0, 0, 8, 4, 3, + 4, 5, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 2, 2, 3, 3, 2, 4, 3, 2, 1, 1, 1, 2, 2, 3, 3, 3, 4, 8, 9, + 3, 2, 4, 0, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(1, 1, 2, 2, 1, 1, 1, 2, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, + 4, 3, 3, 3, 4, 4, 5, 6, 1, 1, 3, 3, 4, 4, 0, 0, 0, 4, 2, 4, 5, 6, 2, 3, 2, 2), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(2, 2, 3, 3, 2, 3, 1, 2, 1, 2, 3, 3, 2, + 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 0, 4, 6, 7, 8, 1, 1, 4, 3), Array(3, 3, 2, + 1, 2, 1, 3, 2, 7, 4, 3, 4, 3, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 6, 7, 1, 2, 2, 4, 7, 0, 0, 6, 0, 3, 4, + 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 3, 5, 3, 6, 4, 2, 4, 3, 3, 3, 4, 2, 2, 1, 1, 1, 2, 3, 8, 9, 2, + 2, 3, 3, 9, 0, 0, 8, 4, 0, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 3, 6, 4, 7, 4, 3, 5, 4, 4, 4, 5, + 3, 2, 2, 2, 1, 2, 2, 9, 10, 3, 3, 4, 4, 10, 0, 0, 9, 5, 1, 0, 1, 7, 8, 8, 7), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 7, 8, 7, 6, + 3, 7, 5, 8, 4, 4, 6, 5, 5, 4, 6, 4, 3, 3, 3, 2, 2, 1, 10, 11, 4, 4, 5, 5, 11, 0, 0, 10, 6, 2, 1, 0, 8, 9, 9, 8), Array(2, 2, 3, + 3, 2, 3, 1, 2, 3, 2, 3, 3, 2, 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 2, 4, 6, 7, + 8, 0, 1, 4, 3), Array(3, 3, 4, 4, 3, 4, 2, 3, 2, 3, 4, 4, 3, 5, 8, 8, 5, 9, 9, 5, 5, 5, 6, 7, 7, 6, 6, 6, 7, 7, 8, 9, 6, 7, 6, + 6, 6, 7, 7, 0, 0, 1, 5, 7, 8, 9, 1, 0, 5, 4), Array(2, 2, 3, 4, 3, 3, 2, 3, 6, 3, 4, 4, 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, + 5, 5, 5, 5, 6, 7, 8, 1, 2, 4, 5, 5, 6, 2, 0, 0, 5, 3, 6, 7, 8, 3, 4, 0, 1), Array(1, 1, 2, 3, 2, 3, 1, 2, 5, 2, 3, 3, 2, 4, 7, + 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 2, 3, 5, 5, 5, 6, 3, 0, 0, 4, 4, 6, 7, 8, 2, 3, 1)); + } +} + +rule("SUBROUTINE: BOT - RESET PATH FINDING") +{ + event + { + Subroutine; + BotResetPathFinding; + } + + actions + { + Event Player.BotTargetPlayer = -1; + Event Player.BotTargetPosition = -1; + Event Player.BotPrevNodeId = -1; + Event Player.BotClosestNodeIdToTarget = -1; + Event Player.BotNextNodeId = -1; + Event Player.BotNextNodePosition = -1; + Event Player.BotIsPathFinding = False; + Event Player.BotCancelPathFinding = False; + Stop Throttle In Direction(Event Player); + disabled Stop Facing(Event Player); + } +} + +rule("SUBROUTINE: BOT - START PATH FINDING") +{ + event + { + Subroutine; + BotStartPathFinding; + } + + actions + { + disabled Abort If(Event Player.BotIsPathFinding == True); + Call Subroutine(BotGetNextNodeIdAndPosition); + disabled Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Event Player.BotIsPathFinding = True; + } +} + +rule("SUBROUTINE: BOT - GET NEXT NODE ID AND POSITION") +{ + event + { + Subroutine; + BotGetNextNodeIdAndPosition; + } + + actions + { + "BOT JUST START FOLLOW PATH OR LOST NEXT NODE" + If(Event Player.BotPrevNodeId == -1); + Event Player.BotClosestNodeIdToBot = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array(Global.NodePositions, + Is In Line of Sight(Position Of(Event Player) + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS) == True), + Distance Between(Position Of(Event Player), Current Array Element))[0]); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + "NEXT NODE IS TARGET (DISTANCE TO TARGET NODE = 1)" + If(Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1); + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToTarget; + "CHECK CONNECTIONS OF REACHED NODE" + Else; + Event Player.BotShortestDistanceToTarget = 999; + Event Player.BotCurrentDistanceToTarget = Event Player.BotShortestDistanceToTarget; + Event Player.BotTempArray = Global.NodeConnections[Event Player.BotClosestNodeIdToBot]; + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotTempArray), 1); + Event Player.BotCurrentDistanceToTarget = Global.DistanceMatrix[Event Player.BotTempArray[Event Player.BotLoopIterator1]][Event Player.BotClosestNodeIdToTarget]; + If(Event Player.BotCurrentDistanceToTarget < Event Player.BotShortestDistanceToTarget); + Event Player.BotShortestDistanceToTarget = Event Player.BotCurrentDistanceToTarget; + Event Player.BotNextNodeId = Event Player.BotTempArray[Event Player.BotLoopIterator1]; + End; + End; + End; + "NEXT NODE IS HIGHER THAN BOT AND BOT DIDN'T REACH CLOSEST NODE" + If(Y Component Of(Position Of(Event Player)) - Y Component Of(Global.NodePositions[Event Player.BotNextNodeId]) + < -3 && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + "BOT CAN SEE TARGET POSITION AND NEXT NODE IS TARGET" + Else If( + Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1 && Is In Line of Sight( + Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotTargetPosition + Vector(0, 2, 0), Barriers Do Not Block LOS)); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Abort; + "BOT CAN'T SEE NEXT NODE AND PREV NODE != REACHED NODE" + Else If(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), + Global.NodePositions[Event Player.BotNextNodeId] + Vector(0, 2, 0), Barriers Do Not Block LOS) + == False && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + End; + Event Player.BotNextNodePosition = Global.NodePositions[Event Player.BotNextNodeId]; + } +} + +rule("SUBROUTINE: BOT - GET CLOSEST NODE ID AND POSITION TO TARGET") +{ + event + { + Subroutine; + BotGetClosestNodeIdToTarget; + } + + actions + { + Event Player.BotTargetPosition = Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Event Player.BotTargetPosition; + Event Player.BotClosestNodeIdToTarget = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array( + Global.NodePositions, Is In Line of Sight(Event Player.BotTargetPosition + Vector(0, 2, 0), Current Array Element, + Barriers Do Not Block LOS) == True), Distance Between(Event Player.BotTargetPosition, Current Array Element))[0]); + } +} + +rule("BOT: PATH FINDING - START") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + (Event Player.BotTargetPosition != -1 || Event Player.BotTargetPlayer != -1) == True; + } + + actions + { + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - CANCEL") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotCancelPathFinding == True; + } + + actions + { + Start Rule(BotResetPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - LOST THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + (Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotNextNodePosition + Vector(0, 2.500, 0), + Barriers Do Not Block LOS) == False && Speed Of In Direction(Event Player, Throttle Of(Event Player)) < 2) == True; + } + + actions + { + Wait(0.500, Abort When False); + "RESET PREV NODE ID TO INFORM BOT THAT IT LOST NEXT NODE" + Event Player.BotPrevNodeId = -1; + "TRY FIND NEW NEXT NODE" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodeId), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +rule("BOT: PATH FINDING - REACHED THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotClosestNodeIdToTarget >= 0; + (Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotNextNodePosition), 0, Z Component Of(Event Player.BotNextNodePosition))) < 0.850) == True; + } + + actions + { + Event Player.BotPrevNodeId = Event Player.BotNextNodeId; + Event Player.BotClosestNodeIdToBot = Event Player.BotNextNodeId; + "BOT'S TARGET IS PLAYER" + If(Event Player.BotTargetPlayer != -1); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + Event Player.BotCurrentDistanceToTarget = Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of( + Position Of(Event Player))), Vector(X Component Of(Event Player.BotTargetPosition), 0, Z Component Of( + Event Player.BotTargetPosition))); + "BOT REACHED THE TARGET NODE OR TARGET POSITION" + If(Event Player.BotNextNodeId == Event Player.BotClosestNodeIdToTarget || Event Player.BotCurrentDistanceToTarget <= 0.850); + "BOT DIDN'T REACH TARGET POSITION" + If(Event Player.BotCurrentDistanceToTarget > 0.850); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Skip(6); + "BOT REACHED TARGET" + Else; + Call Subroutine(BotResetPathFinding); + Abort; + End; + End; + "CONTINUE FOLLOW PATH" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: GAME MODE INIT - WORKSHOP SETTINGS") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.IsDebug = False; + Global.IsDebugAINavigation = False; + Global.GateMaxHealth = Workshop Setting Integer(Custom String("DEFEND CASTLE"), Custom String("GATE MAX HEALTH"), 500, 100, 1000, + 0); + Global.MoneyMult = Workshop Setting Real(Custom String("DEFEND CASTLE"), Custom String("Money Multiplicator"), 1, 0.5, 2, + 0); + Global.IsStoryHeroes = Workshop Setting Toggle(Custom String("DEFEND CASTLE"), Custom String("Story Heroes"), True, 0); + Global.SelfNanoWorkshopSetting = Workshop Setting Toggle(Custom String("Ana Self Nano"), Custom String( + "Ana can nano herself even if there are other players (only if no player targeted)"), False, 0); + } +} + +rule("GLOBAL: GAME MODE INIT - COMMON PROPERTIES") +{ + event + { + Ongoing - Global; + } + + actions + { + Create HUD Text(All Players(All Teams), Null, Null, Custom String( + "DEFEND CASTLE v0.6.c122 BY HUKUTA94#2589\r\nmodified by ShuriZma#2349\r\nDiscord: discord.shurizma.de\r\n{0}", Custom String( + "Special Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents &\nJosbird for teaching me about Menus{0}", + Custom String("{0}", Custom String(" \nPS: SHINGEN PLS COME BACK")))), Right, -1000, Null, Null, Color(White), Visible To, + Default Visibility); + Global.GateRepairPosition = Vector(153, 8, -46.500); + Global.GatePosition = Vector(148.800, 6, -46.400); + Global.BallSpawnPositions = Array(Vector(104, 7, -46), Vector(106, 2, -31)); + Global.SniperPositions = Array(Vector(154, 18, -22.600), Vector(86, 12, -46.600), Vector(80.880, 11.300, -71.600), Vector(98, 9, + -19)); + Global.ZenSpawnPositions = Array(Vector(79.500, 5, -100), Vector(90, 4, -88), Vector(65, 11, -70), Vector(85, 4, -68), Vector(96, + 2, -73), Vector(84, 7, -47), Vector(95, 9, -34), Vector(108, 1.700, -28), Vector(113, 7, -37), Vector(123, 5, -19), Vector(144, + 5, -19), Vector(123, 6, -39), Vector(123, 6, -61), Vector(129, 6, -30.500), Vector(135, 6, -63)); + Global.PlayerSpawnPositions = Array(Vector(153.300, 10, -63.800), Vector(153.300, 10, -61.700), Vector(153.300, 10, -31.700), + Vector(153.300, 10, -29.600)); + Global.BigBossSpawnPositions = Array(Vector(78, 4, -84), Vector(95, 4, -82)); + Global.BastionTargetPositions = Array(Vector(131, 12, -62), Vector(115, 7, -46), Objective Position(2), Vector(136, 10, -27)); + Global.SpawnPositionMaxId = 2; + Global.BotOrisaTargetPosition = Vector(104, 7, -46); + Global.BotEchoRespawnPosition = Vector(130, 23, -44); + Global.BotEchoTeleportPositions = Array(Vector(88, 23, -79), Vector(108, 18, -27)); + Global.DefaultHeroBotsPool = Array(Hero(Zenyatta), Hero(Widowmaker), Null, Hero(Bastion), Hero(Echo), Hero(Bastion)); + Global.ZenRespawnTime = 10; + Global.GameLogicCountOfUniqueHeroes = 5; + Global.lastBoss = Array(Null, Null, Null, Null); + Create Effect(All Players(Team 1), Ring, Color(Sky Blue), Vector(186, 11, -46.500), 9, Visible To Position and Radius); + } +} + +disabled rule("PLAYER: DEBUG - PRESS INTERACT") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Host Player == True; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + disabled Modify Player Score(Event Player, 10); + disabled Global.GateHealth -= 5; + disabled Start Rule(GateProgressBarColor, Restart Rule); + Global.TimeSec = 59; + Set Status(Event Player, Null, Phased Out, 9999); + disabled Set Ultimate Charge(Event Player, 100); + disabled Kill(Event Player, Null); + disabled Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: DEBUG - AI NAVIGATION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.IsDebugAINavigation == True; + } + + actions + { + For Global Variable(LoopIterator1, 0, Count Of(Global.NodePositions), 1); + Create Effect(All Players(All Teams), Sphere, Color(Red), Global.NodePositions[Global.LoopIterator1], 0.850, Visible To); + Create In-World Text(All Players(All Teams), Custom String("NODE {0}", Global.LoopIterator1), + Global.NodePositions[Global.LoopIterator1], 1.200, Clip Against Surfaces, Visible To, Color(White), Default Visibility); + End; + } +} + +disabled rule("GLOBAL: DEBUG - CREATE BOTS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + Create Dummy Bot(Hero(Bastion), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + Create Dummy Bot(Hero(Orisa), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +disabled rule("PLAYER: DEBUG - INFOS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + Host Player == Event Player; + Has Spawned(Event Player) == True; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Create HUD Text(Event Player, Custom String("POS {0}\r\nFACING {1}", Position Of(Event Player), Facing Direction Of(Event Player)), + Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + Create HUD Text(Event Player, Custom String("SERVER PERFORMANCE\r\nLOAD {0}%\r\nPEAK {1}%\r\nAVG {2}%", Server Load, + Server Load Peak, Server Load Average), Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create Progress Bar HUD Text(Event Player, 45, Custom String("45 / 100 KILLS"), Left, -99, Color(Blue), Color(White), + Visible To Values and Color, Default Visibility); + disabled Create HUD Text(Event Player, Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Null, Custom String( + "LEVEL 1 - 50 AMMO CLIP"), Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + "ЭФФЕКТ С ОФФСЕТОМ ОТ ПОЗИЦИИ ГЛАЗ" + disabled Create Beam Effect(All Players(All Teams), Bad Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + Facing Direction Of( + Event Player) * 3, Eye Position(Event Player) + Facing Direction Of(Event Player) * 50, Color(Purple), + Visible To Position and Radius); + } +} + +disabled rule("=== TEAM UPGRADES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: TEAM UPGRADES - INIT") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.UpgradeMaxAmmoMaxValue[0] = 250; + Global.UpgradeMaxAmmoMaxValue[1] = 500; + Global.UpgradeMaxAmmoMaxValue[2] = 1000; + Global.UpgradeCriticalDamageMaxValue[0] = 10; + Global.UpgradeCriticalDamageMaxValue[1] = 10; + Global.UpgradeCriticalDamageMaxValue[2] = 10; + Global.UpgradePlayerMaxHealthMaxValue[0] = 2500; + Global.UpgradePlayerMaxHealthMaxValue[1] = 5000; + Global.UpgradePlayerMaxHealthMaxValue[2] = 10000; + Global.UpgradeGateMaxHealthMaxValue[0] = Round To Integer(Global.GateMaxHealth + Global.GateMaxHealth * 0.500, Up); + Global.UpgradeGateMaxHealthMaxValue[1] = Global.UpgradeGateMaxHealthMaxValue[0] + Global.UpgradeGateMaxHealthMaxValue[0]; + Global.UpgradeGateMaxHealthMaxValue[2] = Global.UpgradeGateMaxHealthMaxValue[1] + Global.UpgradeGateMaxHealthMaxValue[1]; + Abort If(Global.IsDebug == False); + Global.UpgradeMaxAmmoMaxValue[0] = 1; + Global.UpgradeCriticalDamageMaxValue[0] = 1; + Global.UpgradePlayerMaxHealthMaxValue[0] = 1; + Global.UpgradeGateMaxHealthMaxValue[0] = 1; + Global.UpgradeMaxAmmoMaxValue[1] = 1; + Global.UpgradeCriticalDamageMaxValue[1] = 1; + Global.UpgradePlayerMaxHealthMaxValue[1] = 1; + Global.UpgradeGateMaxHealthMaxValue[1] = 1; + Global.UpgradeMaxAmmoMaxValue[2] = 1; + Global.UpgradeCriticalDamageMaxValue[2] = 1; + Global.UpgradePlayerMaxHealthMaxValue[2] = 1; + Global.UpgradeGateMaxHealthMaxValue[2] = 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GATE'S MAX HEALTH UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Global.GateMaxHealth = Global.UpgradeGateMaxHealthMaxValue[0]; + Global.GateHealth = Global.GateMaxHealth; + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Right, 1, Color( + Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X GATE REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[1]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X GATE REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X GATE REPAIR"), Right, 2, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X AUTO-REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[2]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[2] = Last Text ID; + Global.GateHealth = Global.GateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 3 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X AUTO-REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X AUTO-REPAIR"), Right, 3, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.UpgradeGateMaxHealthHudId[2] = Last Text ID; + Global.GateHealth = Global.GateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - PLAYER'S MAX HEALTH - DEALT HEALING") +{ + event + { + Player Received Healing; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + disabled Healer != Event Player; + Global.UpgradePlayerMaxHealthValue < Global.UpgradePlayerMaxHealthMaxValue[2]; + } + + actions + { + Global.UpgradePlayerMaxHealthValue += Event Healing; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +50%"), Right, 4, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("Up You Go: You respawn twice as fast"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[1]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.MaxHealthDone = 50; + All Players(Team 1).PlayerHealth = 100 + Global.MaxHealthDone + All Players(Team 1).Abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).PlayerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK UP YOU GO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("UP YOU GO UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String("Up You Go"), + Right, 5, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +100%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[2]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[2] = Last Text ID; + Set Respawn Max Time(All Players(Team 1), 5); + Heal(All Players(Team 1), Null, 9999); + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.Perk[2] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[17] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH 2 UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +100%"), Right, 6, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[2] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.MaxHealthDone = 150; + All Players(Team 1).PlayerHealth = 100 + Global.MaxHealthDone + All Players(Team 1).Abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).PlayerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Hero Of(Victim) == Hero(Widowmaker); + Global.UpgradeCriticalDamageValue < Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradeCriticalDamageValue += 1; + Small Message(All Players(Team 1), Custom String("CRITICAL DAMAGE CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - CRITICAL DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("CRITICAL DAMAGE 150% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "CRITICAL DAMAGE 150%"), Right, 7, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String( + "Sharpshooter: Deal 40% more damage to enemies that are further than 15 meters away"), Custom String("KILL ECHO {0}/{1}", + Global.UpgradePerkSharpshooterValue, Global.UpgradeCriticalDamageMaxValue[1]), Left, 14, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - UNLOCKED") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.500); + } +} + +rule("PLAYER: UPGRADE - PERK SHARPSHOOTER - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Echo); + Global.UpgradePerkSharpshooterValue < Global.UpgradeCriticalDamageMaxValue[1]; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradePerkSharpshooterValue += 1; + Small Message(All Players(Team 1), Custom String("SHARPSHOOTER CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - PERK SHARPSHOOTER - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("SHARPSHOOTER UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Sharpshooter"), Right, 8, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("-10% BOSS HEALTH"), Custom String("KILL Bosses {0}/{1}", + Global.UpgradeBossHealthValue, Global.UpgradeCriticalDamageMaxValue[2]), Left, 14, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[2] = Last Text ID; + Global.Perk[0] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[18] = Last Text ID; + Global.challengeCount += 1; + } +} + +disabled rule("PLAYER: UPGRADE - -10% BOSS HEALTH - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]; + Global.UpgradeBossHealthValue < Global.UpgradeCriticalDamageMaxValue[2]; + Victim.isBoss == 1; + } + + actions + { + Global.UpgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - -10% BOSS HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("-10% BOSS HEALTH UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "-10% BOSS HEALTH"), Right, 9, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[2] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - MAX AMMO - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Zenyatta); + Global.UpgradeMaxAmmoValue < Global.UpgradeMaxAmmoMaxValue[2]; + } + + actions + { + If(Event Player.isBoss == 1); + Global.UpgradeMaxAmmoValue += 10; + Else; + Global.UpgradeMaxAmmoValue += 1; + End; + } +} + +rule("GLOBAL: UPGRADE - MAX AMMO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("MAX AMMO 200% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "MAX AMMO 200%"), Right, 10, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("Bulletstorm: Your weapon can hold unlimited ammo"), + Custom String("KILL {2}: {0}/{1}", Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[1], Hero(Zenyatta)), Left, 15, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0) * 2); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1) * 2); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0)); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1)); + End; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK BULLETSTORM - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("BULLETSTORM UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Bulletstorm"), Right, 11, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("+50% DAMAGE"), Custom String("KILL {2}: {0}/{1}", + Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[2], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[2] = Last Text ID; + Global.Perk[1] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[19] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - +50% DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("+50% DAMAGE UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "+50% DAMAGE"), Right, 12, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[2] = Last Text ID; + Global.DamageDone = 50; + All Players(Team 1).DamageDealt = 100 + Global.DamageDone + All Players(Team 1).Abilities[13] * 5; + Set Damage Dealt(All Players(Team 1), All Players(Team 1).DamageDealt); + Global.challengeCount += 1; + } +} + +disabled rule("=== GAME PHASES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: ASEMBLING PHASE - MAKE CHALLENGES HUDS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Assembling Heroes == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Disable Inspector Recording; + Set Match Time(20); + End; + Create In-World Text(All Players(Team 1), Custom String(" {0}\r\nREPAIR\r\n {1}", Hero Icon String(Hero(Torbjörn)), + Ability Icon String(Hero(Bastion), Button(Secondary Fire))), Global.GatePosition + Vector(0, 1.400, 0), 1.200, Do Not Clip, + Visible To, Color(White), Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("TEAM CHALLENGES"), Left, 11, Color(White), Color(Blue), Color( + White), Visible To, Default Visibility); + "UPGRADE - GATE'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String( + "GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Custom String("REPAIR GATE {0}/{1} HP", + Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[0]), Left, 12, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 2, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - PLAYER'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +50%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[0]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 4, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - CRITICAL DAMAGE" + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("CRITICAL DAMAGE 150%"), Custom String( + "KILL WIDOW WITH HEADSHOT: {0}/{1}", Global.UpgradeCriticalDamageValue, Global.UpgradeCriticalDamageMaxValue[0]), Left, 14, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 6, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - MAX AMMO" + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("MAX AMMO 200%"), Custom String("KILL {2}: {0}/{1}", + Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[0], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Custom String("HOLD {0} - Reload to open the shop", Input Binding String(Button(Reload))), + Null, Null, Top, 1000, Color(Yellow), Color(White), Color(White), Visible To and String, Default Visibility); + } +} + +rule("GLOBAL: SETUP PHASE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Set Match Time(20); + End; + Set Objective Description(All Players(All Teams), Custom String("DEFEND GATE"), Visible To and String); + } +} + +rule("GLOBAL: GAME IN PROGRESS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + } + + actions + { + Set Match Time(3599); + Pause Match Time; + Disable Built-In Game Mode Scoring; + Disable Built-In Game Mode Announcer; + Disable Built-In Game Mode Completion; + Disable Game Mode HUD(All Players(All Teams)); + Disable Game Mode In-World UI(All Players(All Teams)); + Global.GateHealth = Global.GateMaxHealth; + Global.GateHealthChase = Global.GateHealth; + Global.GateProgressBarColorComponent = 255; + Global.GateProgressBarColorCurrent = Color(White); + Create Progress Bar HUD Text(All Players(Team 1), Global.GateHealthChase * 100 / Global.GateMaxHealth, Custom String( + "GATE {0}/{1}", Global.GateHealth, Global.GateMaxHealth), Top, 1, Global.GateProgressBarColorCurrent, Color(White), + Visible To Values and Color, Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("SURVIVED TIME: {0}:{1}", Global.TimeMin, + Global.TimeSec < 10 ? Custom String("0{0}", Global.TimeSec) : Global.TimeSec), Top, 2, Color(White), Color(White), Color( + White), Visible To and String, Default Visibility); + Start Rule(GameLogicWave0, Do Nothing); + } +} + +disabled rule("=== GAME - MAIN LOGIC ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: DEFEAT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.IsDebug == False; + Global.GateHealth <= 0; + } + + actions + { + Declare Team Victory(Team 2); + } +} + +rule("GLOBAL: TIMER - MAIN GAME LOOP") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + disabled Global.GateHealth > 0; + } + + actions + { + Wait(1, Ignore Condition); + Global.TimeSec += 1; + If(Global.TimeSec == 60); + Global.TimeSec = 0; + Global.TimeMin += 1; + Global.Time5Min = Round To Integer(Global.TimeMin / 5, Down); + Global.Time10Min = Round To Integer(Global.TimeMin / 10, Down); + Global.SpawnPositionMaxId += 1; + disabled Start Rule(GameLogicAddNextHeroInGame, Restart Rule); + Else If(Global.TimeSec == 30); + Global.SpawnPositionMaxId += 1; + End; + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GAME LOGIC - ADD NEXT HERO IN GAME") +{ + event + { + Subroutine; + GameLogicAddNextHeroInGame; + } + + actions + { + "REDUCE RESPAWN TIME FOR ZENS" + disabled Global.ZenRespawnTime -= 1.500; + disabled Global.ZenRespawnTime = Max(1, Global.ZenRespawnTime); + disabled Set Respawn Max Time(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Global.DefaultHeroBotsPool[0]), + Global.ZenRespawnTime); + "ALL HEROES WAS ADDED IN GAME" + Abort If(Global.DefaultHeroBotsPoolCurrentId == Count Of(Global.DefaultHeroBotsPool) - 1); + Global.DefaultHeroBotsPoolCurrentId += 1; + "ВРЕМЕННЫЙ КОСТЫЛЬ ЧТОБЫ ЭХО ЗАМЕНИЛА ХАМСТЕРА" + If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Hero(Echo)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Abort; + End; + "ABORT IF NEXT HERO IN ARRAY ORDER IS NULL" + Abort If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Null); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId], Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("SUBROUTINE: GAME LOGIC - SET BOT PROPERTIES") +{ + event + { + Subroutine; + GameLogicSetBotProperties; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + If(Global.TimeMin >= 10); + If(Filtered Array(Global.lastBoss, Current Array Element == Hero Of(Event Player)) == False); + If(Global.activeBoss == False); + If(Global.bossTrigger < Global.TimeMin); + Global.bossTrigger = Global.TimeMin; + Global.activeBoss = Event Player; + Event Player.isBoss = 1; + Big Message(All Players(Team 1), Custom String("BOSS SPAWNED - {0}", Hero Of(Event Player))); + End; + End; + End; + End; + "PROPERTIES BY DEFAULT" + Set Gravity(Event Player, 100); + Set Damage Dealt(Event Player, 100); + Set Respawn Max Time(Event Player, 10); + Start Scaling Player(Event Player, 1, False); + "INDIVIDUAL HERO'S PROPERTIES" + If(Hero Of(Event Player) == Hero(Zenyatta)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 30); + Set Max Health(Event Player, 5 * (100 + Global.TimeMin * 10) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 1.500, False); + Else; + If(20 + 3 * Number Of Players(Team 1) + 3 * Global.TimeMin > 75); + Set Move Speed(Event Player, 75); + Else; + Set Move Speed(Event Player, 20 + 3 * Count Of(All Players(Team 1)) + 3 * Global.TimeMin); + End; + Set Max Health(Event Player, 100 + Global.TimeMin * 10); + End; + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 20); + Set Max Health(Event Player, 5 * (70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + If(30 + Global.TimeMin + 2.500 * Global.Time5Min > 40); + Set Move Speed(Event Player, 40); + Else; + Set Move Speed(Event Player, 30 + Global.TimeMin + 2.500 * Global.Time5Min); + End; + Set Ultimate Charge(Event Player, 0); + Set Max Health(Event Player, 70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + If(Event Player.isBoss == 1); + Set Damage Dealt(Event Player, 2 * (85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min)); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 5 * (100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Event Player.BotCounter = 0; + Set Damage Dealt(Event Player, 85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Bastion)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 50); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Start Scaling Player(Event Player, 3, False); + Set Max Health(Event Player, 5 * (155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Else; + Set Move Speed(Event Player, 80); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Start Scaling Player(Event Player, 2, False); + Set Max Health(Event Player, 155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Orisa)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 5 * (220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Set Move Speed(Event Player, 30 + 5 * Global.Time5Min); + Else; + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min); + Set Move Speed(Event Player, 90 + 5 * Global.Time5Min); + End; + Else If(Hero Of(Event Player) == Hero(Echo)); + If(Event Player.isBoss == 1); + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 70 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 5 * (90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 130 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.500, False); + Set Move Speed(Event Player, 70); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 5 * (55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Else; + disabled Start Scaling Player(Event Player, 0.850, False); + Set Move Speed(Event Player, 110); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin); + End; + End; + Wait(0.250, Ignore Condition); + "FILL HEALTH" + Heal(Event Player, Null, 100000); + } +} + +disabled rule("=== GATE ===") +{ + event + { + Ongoing - Global; + } +} + +rule("Subroutine: GATE REPAIR") +{ + event + { + Subroutine; + GateRepair; + } + + actions + { + Small Message(Event Player, Custom String("REPAIR +2% ULTIMATE")); + "UPGRADE - GATE'S MAX HEALTH" + If(Global.UpgradeGateMaxHealthValue < Global.UpgradeGateMaxHealthMaxValue[2]); + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.UpgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.UpgradeGateMaxHealthValue += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + End; + End; + "HEAL GATE" + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.GateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.GateHealth += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + "CHARGE ULTIMATE" + Else; + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + End; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + } +} + +rule("TORB: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Has Spawned(Event Player) == True; + Weapon(Event Player) == 2; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(Is Using Ability 2(Event Player) == True ? 0.350 : 0.700, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Brig: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 5; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Rein: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + Is Game In Progress == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Call Subroutine(GateRepair); + Wait(0.850, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GATE PROGRESS BAR COLOR") +{ + event + { + Subroutine; + GateProgressBarColor; + } + + actions + { + Stop Chasing Global Variable(GateHealthChase); + Chase Global Variable Over Time(GateHealthChase, Global.GateHealth, 0.100, Destination and Duration); + "GATE WAS DAMAGED" + If(Global.GateHealth < Global.GateHealthEvent); + For Global Variable(LoopIterator1, 0, 3, 1); + Global.GateProgressBarColorCurrent = Color(Red); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(White); + Wait(0.030, Ignore Condition); + End; + "GATE WAS REPAIRED" + Else; + Global.GateProgressBarColorCurrent = Color(Green); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(Yellow); + Wait(0.030, Ignore Condition); + End; + Global.GateHealthEvent = Global.GateHealth; + Global.GateProgressBarColorComponent = Global.GateHealth * 255 / Global.GateMaxHealth; + Global.GateProgressBarColorCurrent = Custom Color(255, Global.GateProgressBarColorComponent, Global.GateProgressBarColorComponent, + 255); + } +} + +disabled rule("=== COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("ALL: INIT") +{ + event + { + Player Joined Match; + All; + All; + } + + actions + { + "ALL (COMMON) INIT" + Event Player.IsDead = True; + Disable Kill Feed(Event Player); + Disable Game Mode In-World UI(Event Player); + Disable Death Spectate Target HUD(Event Player); + "BOT INIT" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotInit); + "PLAYER INIT" + Else; + Call Subroutine(PlayerInit); + End; + } +} + +rule("SUBROUTINE: BOT - INIT") +{ + event + { + Subroutine; + BotInit; + } + + actions + { + "INIT VARS" + Event Player.HasBadStatus = False; + Event Player.IsRespawning = False; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEventPosition = Vector(9999, 999, 9999); + "DISABLE ALL FOR BOT" + Disable Hero HUD(Event Player); + Disable Messages(Event Player); + Disable Text Chat(Event Player); + Disable Scoreboard(Event Player); + Disable Game Mode HUD(Event Player); + Disable Death Spectate All Players(Event Player); + Disable Voice Chat(Event Player, True, True, True); + "INIT AI NAVIGATION VARS" + Call Subroutine(BotResetPathFinding); + } +} + +rule("SUBROUTINE: PLAYER - INIT") +{ + event + { + Subroutine; + PlayerInit; + } + + actions + { + "STORY HEROES" + If(Global.IsStoryHeroes); + Reset Player Hero Availability(Event Player); + Set Player Allowed Heroes(Event Player, Array(Hero(Ana), Hero(Brigitte), Hero(Mercy), Hero(Lúcio), Hero(Moira), Hero(Baptiste), + Hero(Ashe), Hero(D.Va), Hero(Genji), Hero(Hanzo), Hero(Widowmaker), Hero(Cassidy), Hero(Reinhardt), Hero(Soldier: 76), Hero( + Torbjörn), Hero(Tracer), Hero(Winston), Hero(Pharah))); + End; + "TEAM CHALLENGE - PLAYER'S MAX HEALTH" + If(Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0]); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + End; + If(Is Game In Progress); + Disable Game Mode HUD(Event Player); + End; + } +} + +rule("ALL: RESPAWN") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + (Hero Of(Event Player) != Event Player.CurrentHero || Event Player.IsDead == True) == True; + } + + actions + { + Event Player.IsDead = False; + "BOT RESPAWN" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotRespawn); + If(Global.IsDebugAINavigation); + Create Beam Effect(All Players(All Teams), Good Beam, Eye Position(Event Player), Event Player.BotNextNodePosition, Color(Green), + Visible To Position and Radius); + End; + "PLAYER RESPAWN" + Else; + Call Subroutine(PlayerRespawn); + End; + "MUST BE AFTER ALL RESPAWN SUBROUTINES!" + Event Player.CurrentHero = Hero Of(Event Player); + } +} + +rule("SUBROUTINE: BOT - RESPAWN") +{ + event + { + Subroutine; + BotRespawn; + } + + actions + { + "RESET COMMON PROPERTIES" + Event Player.IsRespawning = True; + Enable Nameplates(Event Player, All Players(Team 1)); + Call Subroutine(BotResetPathFinding); + disabled If(Hero Of(Event Player) != Event Player.CurrentHero); + Call Subroutine(GameLogicSetBotProperties); + disabled End; + "INDIVIDUAL HERO'S RESPAWN SCRIPTS" + If(Hero Of(Event Player) == Hero(Bastion)); + Call Subroutine(BotBastionRespawn); + Else If(Hero Of(Event Player) == Hero(Zenyatta)); + Call Subroutine(BotZenyattaRespawn); + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + Call Subroutine(BotWidowRespawn); + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Call Subroutine(BotBallRespawn); + Else If(Hero Of(Event Player) == Hero(Orisa)); + Call Subroutine(BotOrisaRespawn); + Else If(Hero Of(Event Player) == Hero(Echo)); + Call Subroutine(BotEchoRespawn); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Call Subroutine(BotReinRespawn); + End; + Event Player.IsRespawning = False; + } +} + +rule("SUBROUTINE: PLAYER - RESPAWN") +{ + event + { + Subroutine; + PlayerRespawn; + } + + actions + { + "TEAM CHALLENGE - MAX AMMO" + If(Hero Of(Event Player) != Event Player.CurrentHero && Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]); + Set Max Ammo(Event Player, 0, Ammo(Event Player, 0) * 2); + Set Max Ammo(Event Player, 1, Ammo(Event Player, 1) * 2); + Set Ammo(Event Player, 0, Max Ammo(Event Player, 0)); + Set Ammo(Event Player, 1, Max Ammo(Event Player, 1)); + End; + "MUST BE AFTER TEAM CHALLENGE MAX AMMO!" + disabled Event Player.CurrentHero = Hero Of(Event Player); + "PLAYER RESPAWN" + Set Status(Event Player, Null, Phased Out, 3); + Set Facing(Event Player, Vector(-1, 0, 0), To World); + Teleport(Event Player, Global.PlayerSpawnPositions[Slot Of(Event Player) == Count Of(Global.PlayerSpawnPositions) ? Random Integer( + 0, Count Of(Global.PlayerSpawnPositions) - 1) : Slot Of(Event Player)]); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + } +} + +rule("PLAYER: DEATH") +{ + event + { + Player Died; + Team 1; + All; + } + + actions + { + If(Hero Of(Event Player) == Hero(Roadhog)); + Event Player.Abilities[8] -= 1; + Wait(Global.Perk[2] ? 5 : 10, Ignore Condition); + Event Player.Abilities[8] += 1; + End; + disabled If(Event Player.lastSecondWind > 0); + disabled Event Player.lastSecondWind = 0; + disabled End; + Event Player.IsDead = True; + } +} + +rule("BOT: DEATH") +{ + event + { + Player Died; + Team 2; + All; + } + + actions + { + If(Event Player.isBoss == 1); + If(Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]); + If(Global.UpgradeBossHealthValue < Global.UpgradeCriticalDamageMaxValue[2]); + Global.UpgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + End; + End; + Event Player.isBoss = 0; + Global.activeBoss = Null; + Big Message(All Players(Team 1), Custom String("BOSS DIED - {0}", Hero Of(Event Player))); + End; + Event Player.IsDead = True; + Event Player.HasBadStatus = False; + Event Player.BotDoesUniqueBehaviour = False; + Disable Nameplates(Event Player, All Players(Team 1)); + disabled Stop Holding Button(Event Player, Button(Ability 1)); + disabled Stop Holding Button(Event Player, Button(Primary Fire)); + disabled Stop Holding Button(Event Player, Button(Secondary Fire)); + "BOT HAS 1 EFFECT IN VAR (NOT ARRAY)" + Skip If(!Entity Exists(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects); + "BOT HAS MORE THEN 1 EFFECT IN VAR (ARRAY)" + Skip If(Count Of(Event Player.BotEffects) == 0, 3); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects[Event Player.BotLoopIterator1]); + End; + } +} + +disabled rule("=== BOT COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BAD STATUS") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + Event Player.HasBadStatus = True; + "PROCESS BAD STATUS" + If(Hero Of(Event Player) == Hero(Widowmaker)); + Start Rule(BotWidowBadStatus, Do Nothing); + End; + Wait Until(!Has Status(Event Player, Knocked Down) && !Has Status(Event Player, Asleep) && !Has Status(Event Player, Frozen) + && !Has Status(Event Player, Stunned), 15); + Event Player.HasBadStatus = False; + } +} + +rule("SUBROUTINE: BOT - LANDING FROM SKY") +{ + event + { + Subroutine; + BotLandingFromSky; + } + + actions + { + Stop Throttle In Direction(Event Player); + "SET RESPAWN POSITION" + Event Player.BotEventPosition = Random Value In Array(Global.BigBossSpawnPositions); + "CREATE EFFECTS" + disabled Create Effect(All Players(All Teams), Light Shaft, Color(Red), Event Player.BotEventPosition, 3, Visible To); + disabled Event Player.BotEffects = Last Created Entity; + "RESPAWN IN LIGHT SHAFT EFFECT" + Teleport(Event Player, Event Player.BotEventPosition + Vector(0, 25, 0)); + Wait(0.020, Ignore Condition); + "SLOW LANDING" + Set Gravity(Event Player, 50); + While(Is In Air(Event Player) == True); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Position Of(Event Player) + Vector(0, -2.700, 0), 2); + Wait(0.250, Ignore Condition); + End; + Set Gravity(Event Player, 100); + disabled Destroy Effect(Event Player.BotEffects); + "LANDING EFFECTS" + Play Effect(All Players(All Teams), Wrecking Ball Piledriver Impact Effect, Custom Color(105, 87, 46, 255), Position Of( + Event Player), 8); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Sound, Color(White), Position Of(Event Player), 150); + } +} + +rule("SUBROUTINE: BOT - APPEAR FROM UNDERGROUND") +{ + event + { + Subroutine; + BotApearFromUnderground; + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1); + Wait(0.200, Ignore Condition); + Set Gravity(Event Player, 20); + Disable Movement Collision With Environment(Event Player, True); + Teleport(Event Player, Global.ZenSpawnPositions[Random Integer(Min(Global.TimeMin, Count Of(Global.ZenSpawnPositions) - 10), Min( + Global.SpawnPositionMaxId, Count Of(Global.ZenSpawnPositions) - 4))] + Vector(0, -1.500, 0)); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Sigma Accretion Impact Effect, Custom Color(220, 175, 100, 255), Eye Position(Event Player), + 3); + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(Gray), Eye Position(Event Player), 50); + Apply Impulse(Event Player, Up, 3.500, To World, Cancel Contrary Motion); + Wait(0.400, Ignore Condition); + Clear Status(Event Player, Knocked Down); + Set Gravity(Event Player, 100); + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("=== PLAYER MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("PLAYER: DARKNESS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + !Entity Exists(Event Player.BotEffects) == True; + } + + actions + { + Disable Nameplates(Event Player, All Players(All Teams)); + Start Forcing Player Outlines(Event Player, All Players(All Teams), False, Color(White), Default); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 14), 25, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(-5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + } +} + +rule("PLAYER: HEALTH REGEN") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + actions + { + Stop Heal Over Time(Event Player.HealOverTimeId); + Event Player.EventHealth = Health(Event Player); + Wait(4, Ignore Condition); + "TOOK DAMAGE, RESET REGENERATION TIMER" + Loop If(Is Alive(Event Player) && Event Player.EventHealth > Health(Event Player)); + Start Heal Over Time(Event Player, Null, 3, Max Health(Event Player) / 3); + Event Player.HealOverTimeId = Last Heal Over Time ID; + } +} + +disabled rule("=== NERFS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("REINHARDT: ANTI-CHARGE FOR BASTION & ORISA") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Using Ability 1(Event Player) == True; + Hero Of(Ray Cast Hit Player(Eye Position(Event Player) + Vector(0, 2, 0), Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 2, All Living Players(Team 2), Event Player, True)) == (Hero(Bastion) == True || Hero( + Orisa) == True); + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1.500); + } +} + +rule("HOG: ANTI-HOOK FOR BASTION & ORISA") +{ + event + { + Player Dealt Damage; + Team 1; + Roadhog; + } + + conditions + { + Event Ability == Button(Ability 1); + (Hero Of(Victim) == Hero(Bastion) || Hero Of(Victim) == Hero(Orisa)) == True; + } + + actions + { + Set Status(Event Player, Null, Stunned, 0.005); + } +} + +disabled rule("=== ZENYATTA ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ZEN - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Zenyatta; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + } + + actions + { + Set Ammo(Event Player, 0, 0); + Communicate(Event Player, Hello); + disabled Call Subroutine(BotResetPathFinding); + Wait(1.500, Ignore Condition); + Abort If(Is Dead(Event Player) == True); + Kill(Event Player, Null); + } +} + +rule("BOT: ZEN - DEATH") +{ + event + { + Player Died; + Team 2; + Zenyatta; + } + + actions + { + "EFFECT" + Play Effect(All Players(All Teams), Junkrat Frag Launcher Explosion Effect, Color(Red), Eye Position(Event Player), 2.500); + Play Effect(All Players(All Teams), Ashe Dynamite Explosion Sound, Color(Red), Eye Position(Event Player), 70); + "DAMAGE AND APPLY IMPULSE TO PLAYERS" + Event Player.BotPlayersInRadius = Players Within Radius(Position Of(Event Player), 2.500, All Teams, Surfaces And Enemy Barriers); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotPlayersInRadius), 1); + Apply Impulse(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Direction Towards(Position Of(Event Player), + Eye Position(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1])), 5, To World, Incorporate Contrary Motion); + If(Team Of(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1]) == Team 1); + Damage(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Event Player, 50); + End; + End; + "DAMAGE GATE" + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 125; + Else; + Global.GateHealth -= 25; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Respawn(Event Player); + Abort; + End; + "KILLED BY PLAYER" + Teleport(Event Player, Vector(0, -999, 0)); + Wait(2, Ignore Condition); + Respawn(Event Player); + Wait(2, Ignore Condition); + } +} + +rule("SUBROUTINE: ZEN - RESPAWN") +{ + event + { + Subroutine; + BotZenyattaRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WRECKING BALL ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BALL - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + disabled Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Set Ammo(Event Player, 0, 0); + Wait(1, Ignore Condition); + Set Ultimate Charge(Event Player, 100); + Start Holding Button(Event Player, Button(Ultimate)); + Wait Until(Is Using Ultimate(Event Player), 0.600); + Abort If(Is Dead(Event Player)); + Kill(Event Player, Null); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Effect, Color(Orange), Eye Position(Event Player), 6); + Play Effect(All Players(All Teams), DVa Self Destruct Explosion Sound, Color(White), Eye Position(Event Player), 250); + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 300; + Else; + Global.GateHealth -= 150; + End; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Damage(Players Within Radius(Eye Position(Event Player), 7, Team 1, Surfaces And All Barriers), Event Player, 200); + } +} + +rule("BOT: BALL - ALTERNATIVE FORM") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is In Alternate Form(Event Player) == False; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is In Alternate Form(Event Player), 10); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: BALL - DEATH") +{ + event + { + Player Died; + Team 2; + Wrecking Ball; + } + + actions + { + Stop Holding Button(Event Player, Button(Ability 1)); + Stop Holding Button(Event Player, Button(Ultimate)); + } +} + +rule("SUBROUTINE: BALL - RESPAWN") +{ + event + { + Subroutine; + BotBallRespawn; + } + + actions + { + "RESPAWN IN AIR" + Teleport(Event Player, Random Value In Array(Global.BallSpawnPositions) + Vector(0, 20, 0)); + Stop Holding Button(Event Player, Button(Ultimate)); + Wait(0.250, Ignore Condition); + "LANDING" + Start Holding Button(Event Player, Button(Crouch)); + Wait Until(Is On Ground(Event Player), 9999); + Stop Holding Button(Event Player, Button(Crouch)); + "LANDING IMPACT EFFECT" + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(White), Event Player, 150); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Effect, Color(Gray), Position Of(Event Player), 10); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Eye Position(Event Player), 1.500, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + "PATH FINDING TO GATE" + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +disabled rule("=== ECHO ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ECHO - FLY ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is Using Ability 1(Event Player) == False; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), 0); + Press Button(Event Player, Button(Ability 1)); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - BEAM ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Using Ability 1(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == True; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - BAD STATUS - RESET BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.HasBadStatus == True; + disabled (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + Wait Until(Event Player.HasBadStatus, 7); + } +} + +rule("BOT: ECHO - CAN'T SEE PORTAL - APPLY IMPULSE") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == True; + Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Wait(0.300, Abort When False); + Apply Impulse(Event Player, Vector(Random Integer(-1, 1), 1, Random Integer(-1, 1)), 20, To World, Incorporate Contrary Motion); + Wait(1, Ignore Condition); + If(!Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + Event Player.BotTargetPosition = Global.BotEchoRespawnPosition; + Start Rule(BotStartPathFinding, Restart Rule); + Else; + Call Subroutine(BotResetPathFinding); + End; + Loop If Condition Is True; + } +} + +disabled rule("BOT: ECHO - MAIN LOGIC - BACKUP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(!Event Player.BotIsPathFinding); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Is In Line of Sight(Eye Position(Event Player), + Eye Position(Current Array Element), Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), + Position Of(Current Array Element)))[0]; + End; + "NO PLAYERS IN VIEW RANGE" + disabled If(Event Player.BotSeePlayer == Null); + disabled Stop Throttle In Direction(Event Player); + disabled End; + "FLY TO PLAYER" + If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + > 4 && Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + "ACTIVATE FOCUS BEAM" + Else If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + < 4 && Event Player.BotDoesUniqueBehaviour == False && Event Player.HasBadStatus == False); + Event Player.BotDoesUniqueBehaviour = True; + Set Status(Event Player.BotSeePlayer, Event Player, Stunned, 1); + Set Status(Event Player.BotSeePlayer, Event Player, Hacked, 99999); + Attach Players(Event Player.BotSeePlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + "TELEPORT PLAYER TO AWAY" + Else If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotSeePlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotSeePlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotSeePlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + "BEGIN TO FLY TO THE PORTAL" + Else If(Event Player.BotDoesUniqueBehaviour == True); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + End; + "TELEPORT PLAYER SO FAR" + If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotEchoCapturedPlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotEchoCapturedPlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + End; + "BEGIN TO FLY TO THE PORTAL WITH A PLAYER" + If(Event Player.BotDoesUniqueBehaviour); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotEchoCapturedPlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - DEFEND PORTAL") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + } + + actions + { + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPlayer); + } +} + +rule("BOT: ECHO - PATH FINDING TO PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Call Subroutine(BotStartPathFinding); + } +} + +rule("BOT: ECHO - ATTACH PLAYER BY BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotEchoCapturedPlayer == Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 3; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Event Player.BotEchoCapturedPlayer = Event Player.BotSeePlayer; + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Stunned, 0.700); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Hacked, 10); + Attach Players(Event Player.BotEchoCapturedPlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - PLAYER DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Dead(Event Player.BotEchoCapturedPlayer) != Null; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - DEATH") +{ + event + { + Player Died; + Team 2; + Echo; + } + + actions + { + Call Subroutine(BotEchoDetachPlayer); + Stop Holding Button(Event Player, Button(Jump)); + Wait(5, Ignore Condition); + Teleport(Event Player, Vector(0, 999, 0)); + Start Forcing Player To Be Hero(Event Player, Hero(Orisa)); + } +} + +rule("SUBROUTINE: ECHO - RESPAWN") +{ + event + { + Subroutine; + BotEchoRespawn; + } + + actions + { + Event Player.BotCounter = 0; + Event Player.BotEffects = Empty Array; + Create Effect(All Players(All Teams), Good Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Energy Sound, Color(White), Global.BotEchoRespawnPosition, 200, Visible To); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Chase Player Variable Over Time(Event Player, BotCounter, 3, 0.800, Destination and Duration); + Play Effect(All Players(All Teams), Sombra EMP Explosion Effect, Color(Sky Blue), Global.BotEchoRespawnPosition, 12); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Null, Global.BotEchoRespawnPosition, 100); + Wait(3, Ignore Condition); + Teleport(Event Player, Global.BotEchoRespawnPosition); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Global.BotEchoRespawnPosition, 2.500); + Play Effect(All Players(All Teams), Debuff Impact Sound, Null, Global.BotEchoRespawnPosition, 100); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PLAYER") +{ + event + { + Subroutine; + BotEchoFlyToPlayer; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Stop Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PORTAL") +{ + event + { + Subroutine; + BotEchoFlyToPortal; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - DETACH PLAYER") +{ + event + { + Subroutine; + BotEchoDetachPlayer; + } + + actions + { + Detach Players(Event Player.BotEchoCapturedPlayer); + Clear Status(Event Player.BotEchoCapturedPlayer, Hacked); + "IF PLAYER INSIDE THE WALL" + If(Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotEchoCapturedPlayer), Barriers Do Not Block LOS)); + Teleport(Event Player.BotEchoCapturedPlayer, Position Of(Event Player)); + End; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEchoCapturedPlayer = Null; + } +} + +disabled rule("=== REINHARDT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: REIN - SET PLAYER AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + disabled Event Player.BotIsPathFinding == False; + "BOT IS FAR FROM GATES" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Global.GatePosition), 0, Z Component Of(Global.GatePosition))) > 20; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET CLOSEST PLAYER TO BOT AS TARGET AND FOLLOW HIM" + Event Player.BotTargetPlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - SET GATE AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "BOT DOESN'T FOLLOW PLAYER" + Event Player.BotTargetPlayer == -1; + "CAN'T SEE ANY PLAYER" + disabled Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), !Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET GATE AS TARGET" + Event Player.BotTargetPosition = Global.GatePosition; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - TARGET DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer != -1; + Is Dead(Event Player.BotTargetPlayer) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + } +} + +rule("BOT: REIN - ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) < 4; + "CAN ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) < 4; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + "TARGET IS PLAYER" + Abort If(Event Player.BotTargetPlayer != -1); + If(Event Player.isBoss == 1); + "TARGET IS GATE" + Global.GateHealth -= 25; + Else; + Global.GateHealth -= 5; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: REIN - STOP ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) > 4; + "CAN'T ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) > 4; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + } +} + +rule("BOT: REIN - USE SHIELD") +{ + event + { + Player Took Damage; + Team 2; + Reinhardt; + } + + conditions + { + Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) > 3; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Attacker)), 200, To World, + Direction and Turn Rate); + Start Holding Button(Event Player, Button(Secondary Fire)); + Wait Until(Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) < 3, 3); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("BOT: REIN - CHARGE IN GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer == -1; + Is Using Ability 1(Event Player) == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == True; + Is In View Angle(Event Player, Global.GatePosition, 7.500) == True; + } + + actions + { + disabled Wait(0.800, Abort When False); + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is Using Ability 1(Event Player), 1); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: REIN - DEATH") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("SUBROUTINE: REIN - RESPAWN") +{ + event + { + Subroutine; + BotReinRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WIDOW ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: WIDOW - SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer == Null; + Event Player.HasBadStatus == False; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Event Player.BotWidowShotTime = Total Time Elapsed + (Global.TimeMin >= 9 ? Random Real(2, 5) : Random Real(5, 10)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 9999, To World, + Direction and Turn Rate); + } +} + +rule("BOT: WIDOW - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer != Null; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowShotTime; + } + + actions + { + Press Button(Event Player, Button(Primary Fire)); + Stop Facing(Event Player); + Event Player.BotSeePlayer = Null; + } +} + +rule("BOT: WIDOW - Aim Sound") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Alive(Event Player) == True; + Is In Line of Sight(Eye Position(Players On Hero(Hero(Widowmaker), Team 2)), Eye Position(Event Player), Barriers Do Not Block LOS) + == True; + Is Alive(Players On Hero(Hero(Widowmaker), Team 2)) == True; + Players On Hero(Hero(Widowmaker), Team 2).BotSeePlayer == True; + } + + actions + { + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 100); + Wait(1, Abort When False); + Loop If Condition Is True; + } +} + +rule("BOT: WIDOW - TELEPORT TO NEW POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowTeleportTime; + } + + actions + { + Event Player.BotWidowTeleportTime = Total Time Elapsed + 28; + Event Player.BotWidowShotTime = Total Time Elapsed + Random Real(1, 1.600); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Event Player, 1); + Wait(0.016, Ignore Condition); + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + } +} + +rule("BOT: WIDOW - DEATH") +{ + event + { + Player Died; + Team 2; + Widowmaker; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + Wait(0.250, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - RESPAWN") +{ + event + { + Subroutine; + BotWidowRespawn; + } + + actions + { + "RESPAWN ON RANDOM SNIPER POSITION" + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Wait(0.700, Ignore Condition); + Start Holding Button(Event Player, Button(Secondary Fire)); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait Until(Is Dead(Event Player), 99999); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - BAD STATUS") +{ + event + { + Subroutine; + BotWidowBadStatus; + } + + actions + { + Stop Facing(Event Player); + Destroy Effect(Event Player.BotEffects); + Wait Until(!Event Player.HasBadStatus, 15); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + } +} + +disabled rule("=== BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("BOT: BASTION - FLAME GUN") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 50) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 8; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Stop Holding Button(Event Player, Button(Primary Fire)); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Update Every Frame(Eye Position(Event Player) + World Vector Of( + Vector(-1, -1.200, 1.800), Event Player, Rotation)), 1, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Start Rule(BotBastionFlameGunDamage, Do Nothing); + Wait(1.100, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(4, Ignore Condition); + Loop If Condition Is True; + } +} + +disabled rule("BOT: BASTION - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + disabled Event Player.BotSeePlayer == Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - CAN'T SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == False; + } + + actions + { + Event Player.BotSeePlayer = Null; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - MOVE TO BASTION'S TARGET (POSITION)") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotTargetPosition = Random Value In Array(Filtered Array(Global.BastionTargetPositions, Distance Between(Position Of( + Event Player), Current Array Element) > 3.500)); + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("BOT: BASTION - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + "SEE THE PLAYER" + If(Event Player.BotSeePlayer != Null); + Stop Holding Button(Event Player, Button(Secondary Fire)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer) - Vector(0, 0.500, + 0)), 100, To World, Direction and Turn Rate); + "SELF REPAIRING" + Else If(!Is Firing Secondary(Event Player) && Health(Event Player) < Max Health(Event Player)); + Start Holding Button(Event Player, Button(Secondary Fire)); + End; + "START FOLLOW PATH" + disabled If(!Event Player.BotIsPathFinding && !Event Player.BotDoesUniqueBehaviour); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled Wait(0.050, Ignore Condition); + disabled Event Player.BotTargetPosition = Random Value In Array(Global.BastionTargetPositions); + disabled Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Event Player.BotTargetPosition + Vector(0, 2, 0)), 100, + To World, Direction and Turn Rate); + disabled Start Rule(BotStartPathFinding, Do Nothing); + "REACHED PATH TARGET" + disabled Else If(Distance Between(Position Of(Event Player), Event Player.BotTargetPosition) <= 3); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled End; + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - ARTILLERY") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 30) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) > 18; + Distance Between(Eye Position(Event Player), Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Up * 99, Null, Event Player, False)) >= 35; + } + + actions + { + "TRYING TO CAPTURE TARGET" + Wait(0.800, Abort When False); + "CAPTURE TARGET" + Event Player.BotDoesUniqueBehaviour = True; + Stop Throttle In Direction(Event Player); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Update Every Frame(Eye Position(Event Player)), + Update Every Frame(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 1000, All Living Players(Team 1), Event Player, True)), Color(Sky Blue), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait(1.400, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Event Player.BotEventPosition = Position Of(Event Player.BotSeePlayer); + "SHOOT FROM ARTILLERY" + Event Player.BotBastionArtilleryDidShotsCount = 0; + For Player Variable(Event Player, BotLoopIterator1, 0, 4, 1); + Event Player.BotBastionArtilleryDidShotsCount += 1; + Play Effect(All Players(All Teams), Wrecking Ball Minefield Explosion Sound, Color(White), Eye Position(Event Player), 250); + Play Effect(All Players(All Teams), Pharah Barrage Explosion Effect, Color(Orange), Eye Position(Event Player) + World Vector Of( + Vector(0, 1.400, -0.700), Event Player, Rotation), 2); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) + World Vector Of(Vector(0, 1.400, + -0.700), Event Player, Rotation), Eye Position(Event Player) + World Vector Of(Vector(Random Real(-1, 1), Random Integer(40, + 80), Random Real(0.500, 1.500)), Event Player, Rotation), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + If(Is Dead(Event Player)); + Break; + End; + End; + disabled Call Subroutine(BotResetPathFinding); + disabled Start Rule(BotStartPathFinding, Do Nothing); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Wait(1.500, Ignore Condition); + Start Rule(BotBastionArtilleryDamage, Do Nothing); + Wait(4, Ignore Condition); + } +} + +rule("BOT: BASTION - PRIMARY FIRE") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 40) == True; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Stop Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Bastion; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + For Player Variable(Event Player, BotLoopIterator1, 0, 3, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Effect, Color(White), Event Player, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player, 100); + Wait(0.250, Ignore Condition); + End; + } +} + +rule("SUBROUTINE: BASTION - RESPAWN") +{ + event + { + Subroutine; + BotBastionRespawn; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + Call Subroutine(BotLandingFromSky); + Set Ammo(Event Player, 0, 0); + Wait Until(!Is Reloading(Event Player), 99999); + Event Player.BotTargetPosition = Objective Position(2); + } +} + +rule("SUBROUTINE: BASTION - ARTILLERY DAMAGE") +{ + event + { + Subroutine; + BotBastionArtilleryDamage; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = False; + "EXPLOSIONS OF ARTILLERY" + For Player Variable(Event Player, BotLoopIterator2, 0, Event Player.BotBastionArtilleryDidShotsCount, 1); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotEventPosition + Vector(0, 50, 0), + Event Player.BotEventPosition + Vector(Random Integer(-4, 4), -15, Random Integer(-4, 4)), Null, Event Player, True); + Damage(Players Within Radius(Event Player.BotEventPosition, 8, Team 1, Surfaces And Enemy Barriers), Event Player, 50); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Pharah Rocket Launcher Explosion Effect, Color(Orange), Event Player.BotEventPosition, 5); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Event Player.BotEventPosition, + Event Player.BotEventPosition + Vector(0, 60, 0), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + End; + } +} + +disabled rule("SUBROUTINE: BASTION - FLAME GUN DAMAGE") +{ + event + { + Subroutine; + BotBastionFlameGunDamage; + } + + actions + { + Event Player.BotRayCastHitPosition = Eye Position(Event Player) + World Vector Of(Vector(-1, -1.200, 1.800), Event Player, + Rotation); + "FIRE PARTICLES OF FLAME GUN" + For Player Variable(Event Player, BotLoopIterator1, 1, 13, 3); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotRayCastHitPosition, + Event Player.BotRayCastHitPosition + Facing Direction Of(Event Player) * Event Player.BotLoopIterator1, Null, Event Player, + True); + Damage(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Surfaces And Enemy Barriers), Event Player, 20); + Set Status(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Off), Event Player, Burning, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.BotEventPosition, 2.500); + Wait(0.200, Ignore Condition); + End; + Event Player.BotDoesUniqueBehaviour = False; + } +} + +disabled rule("=== ORISA + BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ORISA-BASTION - REACHED TARGET POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotIsPathFinding == True; + Distance Between(Position Of(Event Player), Global.BotOrisaTargetPosition) < 1.500; + } + + actions + { + Call Subroutine(BotResetPathFinding); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Vector(X Component Of(Global.GatePosition), -999, + Z Component Of(Global.GatePosition))), 80, To World, Direction and Turn Rate); + Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + disabled Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element) && Is In Line of Sight(Eye Position(Event Player), Position Of(Current Array Element), + Barriers Do Not Block LOS)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + Press Button(Event Player, Button(Ability 1)); + Wait Until(Y Component Of(Facing Direction Of(Event Player)) < -0.300, 99999); + Press Button(Event Player, Button(Ability 2)); + Wait(0.800, Ignore Condition); + Global.BotOrisaChild.BotDoesUniqueBehaviour = False; + Disallow Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ORISA-BASTION - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + While(Is Alive(Event Player)); + disabled Create Effect(All Players(All Teams), Bad Aura, Color(Purple), Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3.200, 1, Visible To Position and Radius); + disabled Event Player.BotEffects = Last Created Entity; + Wait(1.500, Ignore Condition); + disabled Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Press Button(Event Player, Button(Primary Fire)); + Press Button(Event Player, Button(Reload)); + Event Player.BotRayCastHitPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Facing Direction Of(Event Player) * 999, All Players(Team 1), All Players(Team 2), True); + "ANTI-SHIELD BUG" + Event Player.BotRayCastHitPosition = Event Player.BotRayCastHitPosition + Direction Towards(Event Player.BotRayCastHitPosition, + Eye Position(Event Player)) * 0.200; + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3, Event Player.BotRayCastHitPosition, Color(Purple), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Damage(Players Within Radius(Event Player.BotRayCastHitPosition, 4, Team 1, Surfaces And All Barriers), Event Player, 0.040); + Play Effect(All Players(All Teams), Pharah Concussive Blast Effect, Color(Purple), Event Player.BotRayCastHitPosition, 4); + Play Effect(All Players(All Teams), Pharah Concussive Blast Sound, Color(Purple), Event Player.BotRayCastHitPosition, 250); + Play Effect(All Players(All Teams), Bad Explosion, Color(Purple), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 3.300, 2); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Color(Purple), Eye Position(Event Player), 170); + If(Distance Between(Event Player.BotRayCastHitPosition, Global.GatePosition) < 4 && Is In Line of Sight( + Event Player.BotRayCastHitPosition, Global.GatePosition, Enemy Barriers Block LOS)); + Global.GateHealth -= 80; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Wait(0.150, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.060, Ignore Condition); + Wait Until(!Is Reloading(Event Player), 2.500); + End; + } +} + +rule("BOT: ORISA-BASTION - CAN'T SEE THE TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: ORISA-BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Orisa; + } + + actions + { + Allow Button(Event Player, Button(Ability 2)); + Kill(Global.BotOrisaChild, Null); + Detach Players(Global.BotOrisaChild); + Clear Status(Global.BotOrisaChild, Phased Out); + Set Damage Dealt(Global.BotOrisaChild, 100); + Global.BotOrisaChild.BotIsOrisaChild = False; + Global.BotOrisaChild = Null; + Global.BotOrisaParent = Null; + Start Forcing Player To Be Hero(Event Player, Hero(Widowmaker)); + } +} + +rule("SUBROUTINE: ORISA - RESPAWN") +{ + event + { + Subroutine; + BotOrisaRespawn; + } + + actions + { + Global.BotOrisaParent = Event Player; + "WAITING FOR ANY BASTION TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero(Bastion)), + 99999); + "SETUP BASTION AS CHILD" + Global.BotOrisaChild = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Bastion))[0]; + Global.BotOrisaChild.BotIsOrisaChild = True; + Global.BotOrisaChild.BotDoesUniqueBehaviour = True; + Wait(2, Ignore Condition); + Respawn(Global.BotOrisaChild); + Start Scaling Player(Global.BotOrisaChild, 1.800, False); + Set Damage Dealt(Global.BotOrisaChild, 2000); + Set Status(Global.BotOrisaChild, Null, Phased Out, 9999); + Disable Nameplates(Global.BotOrisaChild, All Players(All Teams)); + Set Facing(Global.BotOrisaChild, Vector(X Component Of(Facing Direction Of(Event Player)), 9999, Z Component Of( + Facing Direction Of(Event Player))), To World); + Start Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Wait Until(Is In Alternate Form(Global.BotOrisaChild), 5); + Stop Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Teleport(Global.BotOrisaChild, Position Of(Event Player)); + Attach Players(Global.BotOrisaChild, Global.BotOrisaParent, Vector(0, 1.800, 0.230)); + disabled Wait(1, Ignore Condition); + disabled Stop Holding Button(Global.BotOrisaChild, Button(Primary Fire)); + disabled Wait(0.250, Ignore Condition); + Call Subroutine(BotLandingFromSky); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 0 - ZENS, REINS, BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 0; + } + + actions + { + "CREATE BOTS - ZEN" + While(Count Of(All Players(Team 2)) < 13); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "BALL" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "REPLACE DEAD ZEN TO REIN" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) != 3); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 1 - WIDOW") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 1; + } + + actions + { + Global.IsNewWaveGameLogicProcessing = True; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Global.IsNewWaveGameLogicProcessing = False; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 3 - BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 3; + } + + actions + { + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 5 - REINS WAVE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 5; + } + + actions + { + "PREPARE WAVE - DESTROY WIDOW AND BALLS" + Destroy Dummy Bot(Team 2, Slot Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))[0])); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))[0]; + Kill(Global.DefaultCurrentBot, Null); + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + "BOSS WAVE" + Big Message(All Players(All Teams), Custom String("BOSS WAVE - {1} {0}", Hero Icon String(Hero(Reinhardt)), Hero(Reinhardt))); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) < 6); + Wait Until(Is True For Any(All Players(Team 2), Distance Between(Position Of(Current Array Element), Global.GatePosition) + > 13 && Hero Of(Current Array Element) == Hero(Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + disabled Wait(0.200, Ignore Condition); + disabled Set Max Health(Global.DefaultCurrentBot, 50); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) > 3); + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Reinhardt)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Reinhardt))[0]; + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(All Players(Team 2)) < 13); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Big Message(All Players(All Teams), Custom String("BOSS WAVE FINISHED!")); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 7 - BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 7; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 9 - ECHO, +1 BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 9; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Echo))) == 0); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + "FILL EMPTY SLOTS BY ZENS" + While(Count Of(All Players(Team 2)) < 12); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("Ana Nano Variable") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + } + + actions + { + Player Closest To Reticle(Event Player, Team 1).IsNanoed = 1; + } +} + +rule("IsNanoed") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.IsNanoed == True; + } + + actions + { + If(Is Dead(Event Player)); + Event Player.IsNanoed = 0; + End; + Wait(8, Ignore Condition); + Event Player.IsNanoed = 0; + } +} + +rule("money on kill") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + actions + { + If(Hero Of(Victim) == Hero(Zenyatta)); + All Players(Team 1).Money[0] += 10 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 10 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Reinhardt)); + All Players(Team 1).Money[0] += 20 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 20 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Wrecking Ball)); + All Players(Team 1).Money[0] += 25 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 25 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Widowmaker)); + All Players(Team 1).Money[0] += 30 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 30 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Bastion)); + All Players(Team 1).Money[0] += 50 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 50 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Echo)); + All Players(Team 1).Money[0] += 75 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 75 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Orisa)); + All Players(Team 1).Money[0] += 100 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 100 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + } +} + +rule("Abilities and Hero Talents by Shingen and LemonAid") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.DamageDealt = 100; + Event Player.PlayerHealth = 100; + Event Player.Money[0] = 2400 + Global.StartMoney; + If(Custom String("{0}", Event Player) == Custom String("ShuriZma")); + Create HUD Text(Event Player, Custom String("Serverload: {0}, AVG {1}, Peak {2}", Server Load, Server Load Average, + Server Load Peak), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create HUD Text(Event Player, Custom String("Last SW: {0}, SW Active {1}", Event Player.lastSecondWind, + Event Player.secondWindActive), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + End; + } +} + +rule("Team 1 (Ability): Headhunter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[1] == True; + Event Was Critical Hit == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[1] * 40 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Ambush") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[2] == True; + Event Ability != Null; + (Y Component Of(Position Of(Event Player)) - Y Component Of(Position Of(Victim)) >= 3 || Absolute Value(Horizontal Angle Towards( + Victim, Event Player)) >= 90) == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[2] * 30 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Quick Fix") +{ + event + { + Player Earned Elimination; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[3] == True; + } + + actions + { + Heal(Event Player, Null, Event Player.Abilities[3] * 50); + Set Move Speed(Event Player, 100 + Event Player.Abilities[3] * 20); + Wait(5, Restart When True); + Set Move Speed(Event Player, 100); + } +} + +rule("Team 1 (Ability): Heavyweight") +{ + event + { + Player Dealt Knockback; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[4] == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[4] * 25 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Charged") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[5] == True; + Ultimate Charge Percent(Event Player) < Event Player.Abilities[5] * 20; + } + + actions + { + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + If(Is Duplicating(Event Player)); + Wait(0.016, Ignore Condition); + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + End; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Team 1 (Ability): Haste Primary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Primary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Primary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Primary Fire))); + } +} + +rule("Team 1 (Ability): Haste Secondary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Secondary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Secondary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Secondary Fire))); + } +} + +rule("Team 1 (Ability): Haste Ability 1") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 1)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 1))); + } +} + +rule("Team 1 (Ability): Haste Ability 2") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 2)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 2))); + } +} + +rule("Team 1 (Ability): Haste Jump") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Jump)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Jump), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Jump))); + } +} + +rule("Team 1 (Ability): Haste Crouch") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Crouch)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Crouch), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Crouch))); + } +} + +rule("Team 2 (Ability): Heavy Impact") +{ + event + { + Player Took Damage; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[7] == True; + } + + actions + { + Abort If(Random Real(-0.020, 1) > Event Damage / Max Health(Event Player)); + Set Status(Event Player, Attacker, Stunned, 1 * Attacker.Abilities[7]); + Wait(5, Ignore Condition); + } +} + +rule("Team 1 (Ability): Binding Heal") +{ + event + { + Player Dealt Healing; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[10] == True; + Healee != Event Player; + } + + actions + { + Set Player Health(Event Player, Health(Event Player) + Event Player.Abilities[10] * 0.250 * Event Healing); + } +} + +rule("Team 1 (Ability): Resilience") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[11] == True; + Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300; + } + + actions + { + Set Damage Received(Event Player, 70); + Wait Until(!(Event Player.Abilities[11] && Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Auto Repair") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.AutoRepair == True; + Global.GateHealth < Global.GateMaxHealth; + } + + actions + { + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2]); + Global.GateHealth += 10 * Global.AutoRepair; + Global.UpgradeGateMaxHealthValue += 10 * Global.AutoRepair; + Else; + Global.GateHealth += 5 * Global.AutoRepair; + Global.UpgradeGateMaxHealthValue += 5 * Global.AutoRepair; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(5, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ana Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ana), Button(Ability 1)), Custom String( + "Sleep Paralysis: Slept enemies cannot be woken up by damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Ana), Button(Ability 2)), Custom String( + "Multinade: Ana throws multiple Biotic Grenades")); + } +} + +rule("Brigitte Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Brigitte), Button(Ability 1)), Custom String( + "Heavy Iron: Hitting enemies with Whip Flail will root them in pace")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Brigitte), Button(Ultimate)), Custom String( + "Endeavor: Gain a health, damage and speed boost when your barrier breaks")); + } +} + +rule("Mercy Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mercy), Button(Ability 2)), Custom String( + "Angelic blessing: Healing an ally slowly charges their ultimate")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mercy), Button(Ultimate)), Custom String( + "Holy light missiles: Unleash blasts of holy light missiles during valkyrie")); + } +} + +rule("Lúcio Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Lúcio), Button(Secondary Fire)), Custom String( + "Healing Wave: Soundwave heals allies for 30% of their max HP")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Lúcio), Button(Ability 1)), Custom String( + "Reverse Amp: Amp It Up inflicts the opposite effect of the currently played song to enemies")); + } +} + +rule("Moira Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Moira), Button(Secondary Fire)), Custom String( + "Hose: Biotic Grasp primary will damage and push enemies back")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Moira), Button(Ability 2)), Custom String( + "Flourish: Biotic Orbs are 3x more effective")); + } +} + +rule("Baptiste Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String( + "Corrode: Regenerative Burst will damage and poison enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Breakthrough: Immortality Field HP threshold increased to 100%; allies inside gain ultimate")); + } +} + +rule("Ashe Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ashe), Button(Ability 2)), Custom String( + "Wildfire: Shooting a burning enemy ignites other nearby enemies")); + Event Player.HeroTalentText[2] = Array(Icon String(Fire), Custom String( + "Flare trigger: Coach gun instantly damages all burning enemies")); + } +} + +rule("D.Va Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(D.Va), Button(Secondary Fire)), Custom String( + "Voltage Grid: Defense Matrix will damage and root enemies it's casted over")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(D.Va), Button(Ability 1)), Custom String( + "Shooting Star: Boosters set enemies on fire")); + } +} + +rule("Genji Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Genji), Button(Ability 1)), Custom String( + "Venomous Strike: Swift Strike poisons enemies; heal for poison damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Genji), Button(Ultimate)), Custom String( + "Dragon's Breath: Dragonblade fires large explosive energy charges")); + } +} + +rule("Hanzo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Hanzo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "Stormbreak: Enemies eliminated by hanzo unleash a thundercloud")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Hanzo), Button(Ability 2)), Custom String( + "Punch II: Storm Arrows deal more damage and stun and knockback enemies")); + } +} + +rule("Widowmaker Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Widowmaker; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Widowmaker), Button(Ultimate)), Custom String( + "Kiss Of Death: Scoped critical hits against enemies below 30% health explode and instantly die")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Widowmaker), Button(Ability 2)), Custom String( + "Epidemic: Enemies hurt by Venom Mine unleash toxic pulses; heal for dealt damage")); + } +} + +rule("McCree Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Cassidy), Button(Ability 2)), Custom String( + "Panic: Flashbang puts enemies in fear; deal +120% more damage to enemies in fear")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Cassidy), Button(Ultimate)), Custom String( + "Clocked: Deadeye deals more damage and knocks enemies down")); + } +} + +rule("Reinhardt Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reinhardt), Button(Ability 2)), Custom String( + "Fire Blast: Fire Strike explodes as it deals damage, setting enemies on fire")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reinhardt), Button(Ultimate)), Custom String( + "Epicenter: Earthshatter travels in all directions")); + } +} + +rule("Soldier: 76 Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ultimate)), Custom String( + "Triple Threat: 2 more rockets are fired alongside Helix Rockets")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Soldier: 76), Button(Ability 1)), Custom String( + "Shoulder Check: Sprinting into enemies will damage and tackle them to the ground")); + } +} + +rule("Torbjörn Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Torbjörn), Button(Ability 2)), Custom String( + "Melting point: Unleash heatwaves during overload and molten core")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Torbjörn), Button(Ultimate)), Custom String( + "Roots Of Magma: Enemies trapped in Molten Core blots cannot move")); + } +} + +rule("Tracer Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Tracer), Button(Ability 2)), Custom String( + "Vortex: Recall pulls and roots enemies towards the activation point")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Tracer), Button(Ultimate)), Custom String( + "Chain Reaction: Pulse Bomb creates chain explosions on enemies damaged by it")); + } +} + +rule("Winston Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Winston), Button(Ability 2)), Custom String( + "Blast Barrier: Barrier Projector damages enemies inside the area")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Winston), Button(Ultimate)), Custom String( + "Next Generation: Eliminations during Primal Rage add +15% ultimate charge towards the next")); + } +} + +rule("Pharah Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Pharah; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ability 2)), Custom String( + "Head Trauma: Concussive Blast stuns and damages enemies for 25% of their max health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Pharah), Button(Ability 1)), Custom String( + "Thunderbird: Gain 150 shields and deal 4x the damage to barriers and objects")); + } +} + +rule("Bastion Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Bomblets: Bullets shot during sentry configuration are explosive")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ability 1)), Custom String( + "Tesla: A powerful mounted laser will autmotically attack one enemy at a time")); + } +} + +rule("Doomfist Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Jump)), Custom String( + "Phase Shifter: Immune to damage while any ability is active")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Doomfist), Button(Ultimate)), Custom String( + "Fissure: Meteor Strike leaves a large fissure behind that burns enemies over it")); + } +} + +rule("Echo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Focusing Optics: Focusing Beam damage ramp starts at 90% health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Streamline: Fire many more sticky bombs per burst")); + } +} + +rule("Junkrat Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Junkrat; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Fire), Custom String("Pyromania: All explosive attacks inflict fire damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Junkrat), Button(Ability 2)), Custom String( + "Short Fused: Steel Trap sets off violent explosions once triggered")); + } +} + +rule("Mei Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mei), Button(Ultimate)), Custom String( + "Cold Snap: Instantly freeze neaerby enemies once Cryo-Freeze expires")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mei), Button(Ability 2)), Custom String( + "Icebound: While Ice Wall is up, Icicles freeze and deal much more damage")); + } +} + +rule("Orisa Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Orisa), Button(Ability 1)), Custom String( + "Immovable Object: During Fortify, become immune and convert 50% of taken damage to healing")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Orisa), Button(Secondary Fire)), Custom String( + "Unstoppable Force: Halt! is much larger and pushes enemies. When triggered, it explodes violently")); + } +} + +rule("Reaper Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reaper), Button(Ability 1)), Custom String( + "shadow streak: shadow step creates a beam that damages enemies who cross")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reaper), Button(Ultimate)), Custom String( + "Loom: Traumatize enemies in front of you when using Wraith Form")); + } +} + +rule("Roadhog Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String("Stench: Roadhog constantly damages enemies nearby")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Roadhog), Button(Ability 1)), Custom String( + "Rusted Anchor: Hook deals more damage; Eliminations will reset hook cooldown")); + } +} + +rule("Sigma Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sigma), Button(Ability 1)), Custom String( + "Gravity Well: Kinetic Grasp gives invincibility")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sigma), Button(Ultimate)), Custom String( + "Gravity Channels: Gravitic Flux damages enemies for 75% of max hp instead of 50%")); + } +} + +rule("Sombra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sombra), Button(Secondary Fire)), Custom String( + "Malware: Enemies hacked or in fear take +100% more damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sombra), Button(Ultimate)), Custom String( + "Glitch: EMP leaves behind a large hack zone ")); + } +} + +rule("Symmetra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Symmetra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "High Voltage: Enemies eliminated by Symmetra explode and damage other enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ultimate)), Custom String( + "Energy Source: While Photon Barrier is active, all players regenerate health and gain ultimate")); + } +} + +rule("Wrecking Ball Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ultimate)), Custom String( + "Mirror Ball: Reflect 100% of taken damage to nearby enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ability 2)), Custom String( + "Distort: Adaptive Shields damages and hacks nearby enemies")); + } +} + +rule("Zarya Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zarya; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Zarya), Button(Ability 1)), Custom String( + "Augment: Health and barrier hp increased by 50%; barrier sized doubled")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Perpetual Energy: secondary inflicts burn damage that continues to last until the enemy dies")); + } +} + +rule("Zenyatta Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Vigor: The ally under the effect of Harmony Orb is immune to damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Zenyatta), Button(Ultimate)), Custom String( + "Perfect Balance: Transcendence damages enemies in a large proximity")); + } +} + +rule("Ana: Sleep Paralysis") +{ + event + { + Player Dealt Damage; + Team 1; + Ana; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Black), Victim, 1); + Wait(0.250, Ignore Condition); + Set Status(Victim, Null, Knocked Down, 5); + } +} + +rule("Ana: Multinade") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.AbilityCountdown = 4; + While(Event Player.AbilityCountdown > 0); + Wait(0.030, Ignore Condition); + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Cancel Primary Action(Event Player); + Wait(0.050, Ignore Condition); + Press Button(Event Player, Button(Ability 2)); + Event Player.AbilityCountdown -= 1; + End; + Wait(2, Ignore Condition); + } +} + +rule("Brigitte: Heavy Iron") +{ + event + { + Player Dealt Damage; + Team 1; + Brigitte; + } + + conditions + { + (Event Ability == Button(Primary Fire) || Event Ability == Button(Ability 1)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Victim, 1.500); + Set Status(Victim, Null, Rooted, 0.500); + Set Environment Credit Player(Victim, Event Player); + } +} + +rule("Brigitte: Endeavor") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Ability Cooldown(Event Player, Button(Secondary Fire)) >= 0.100; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Eye Position(Event Player), 15); + Heal(Players Within Radius(Event Player, 15, Team Of(Event Player), Off), Event Player, 200); + Event Player.DamageDealt *= 2.500; + Set Move Speed(Event Player, 100 * 1.750); + Add Health Pool To Player(Event Player, Armor, Max Health(Event Player) / 2, False, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(Is Dead(Event Player), 6); + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Move Speed(Event Player, 100); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Mercy: Angelic Blessing") +{ + event + { + Player Dealt Healing; + All; + Mercy; + } + + conditions + { + Event Player.Abilities[8] == True; + Healee != Event Player; + Normalized Health(Healee) < True; + } + + actions + { + Set Ultimate Charge(Healee, Ultimate Charge Percent(Healee) + 1); + Wait(0.400, Ignore Condition); + } +} + +rule("Mercy: Aurora") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ultimate(Event Player) == True; + } + + actions + { + Wait(1.500, Ignore Condition); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(All Teams), Event Player, True); + Create Beam Effect(All Players(All Teams), Mercy Heal Beam, Event Player, Event Player.Ability_Projectile1, Color(White), + Visible To Position and Radius); + Event Player.Effects_[3] = Last Created Entity; + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 70, Destination and Rate); + While(Event Player.Ability_End != Event Player.Ability_Projectile1); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Event Player.Ability_Projectile1, 1); + Wait(0.032, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[3]); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 120); + Loop If Condition Is True; + } +} + +rule("Lucio: Healing Wave") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4); + Heal(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 4, 4, Team Of(Event Player), Surfaces), + Event Player, Max Health(Filtered Array(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4, Team Of(Event Player), Surfaces), Is Alive(Current Array Element))) * 0.300); + } +} + +rule("Lucio: Reverse Amp") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + If(Is Using Ability 1(Event Player)); + Set Status(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Rooted, 4); + Else; + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 16.250); + End; + Play Effect(All Players(All Teams), Ring Explosion, Is Using Ability 1(Event Player) ? Color(Green) : Color(Yellow), Event Player, + 1); + Wait(0.400, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Hose") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Event Player.Abilities[8] == True; + Ability Resource(Event Player, Button(Primary Fire)) > False; + } + + actions + { + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Facing Direction Of(Event Player), 15, To World, + Cancel Contrary Motion); + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && !Is In Line of Sight(Current Array Element, Event Player, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Up, 8, To World, Cancel Contrary Motion); + Start Damage Over Time(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), + Distance Between(Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS)), Event Player, 1, 15); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Flourish - Damage") +{ + event + { + Player Dealt Damage; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("[Moira] Flourish - Healing") +{ + event + { + Player Dealt Healing; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Heal(Healee, Event Player, Event Healing * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Healee, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("Baptiste: Corrode") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 20); + Wait(0.200, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 12); + } +} + +rule("Baptiste: Breakthrough") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Status(Event Player, Unkillable) == True; + (Event Player.Abilities[12] ? Players On Hero(Hero(Baptiste), Team Of(Event Player)) : Empty Array).Abilities[12] == True; + } + + actions + { + Heal(Event Player, Event Player, 10000); + Set Status(Event Player, Null, Invincible, 0.800); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ashe: Firebourne") +{ + event + { + Player Dealt Damage; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability == Button(Primary Fire); + Has Status(Victim, Burning) == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Null, Burning, 10); + Start Damage Over Time(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Event Player, 10, 15); + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 5); + Wait(0.250, Ignore Condition); + } +} + +rule("Ashe: Taunt") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Damage(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, Burning)), + Event Player, 125); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Frozen, + 0.016); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Stunned, + 2); + } +} + +rule("D.Va: Voltage Grid") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 2, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 5, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 8, 0.500); + Wait(0.300, Ignore Condition); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Wait(0.016, Ignore Condition); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Loop If Condition Is True; + } +} + +rule("D.Va: Shooting Star") +{ + event + { + Player Dealt Knockback; + Team 1; + D.Va; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, 40); + Set Status(Victim, Null, Burning, 3); + Start Damage Over Time(Victim, Event Player, 3, 35); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 1); + } +} + +rule("Genji: Venomous Strike") +{ + event + { + Player Dealt Damage; + Team 1; + Genji; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 3, 25); + Start Damage Over Time(Victim, Event Player, 3, 25); + Damage(Victim, Event Player, 25); + Heal(Event Player, Event Player, 25); + } +} + +rule("Genji: Dragon's Breath") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is Firing Primary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Good Aura, Color(Lime Green), Event Player.Ability_Projectile1, 1, + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 80, Destination and Rate); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True); + Wait Until(Event Player.Ability_End == Event Player.Ability_Projectile1, 1); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Green), Event Player.Ability_Projectile1, 100); + Play Effect(All Players(All Teams), Bad Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Green), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 100); + } +} + +rule("[Hanzo] Stormbreak (Storm_Effects6)") +{ + event + { + Player Died; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[8] == True; + Hero Of(Attacker) == Hero(Hanzo); + } + + actions + { + Event Player.Storm_Projectile = Eye Position(Event Player); + Event Player.Storm_EndPoint = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Up * 12, Null, + All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Storm_Projectile, Event Player.Storm_EndPoint, 4, Destination and Rate); + Create Effect(All Players(All Teams), Cloud, Color(White), Vector(False, -0.500, False) + Event Player.Storm_Projectile, 4, + Visible To Position and Radius); + Event Player.Storm_Effects[3] = Last Created Entity; + Create Effect(All Players(All Teams), Bad Aura, Color(White), Event Player.Storm_Projectile, 3, Visible To Position and Radius); + Event Player.Storm_Effects[4] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(White), Event Player.Storm_Projectile, 3.500, Visible To Position and Radius); + Event Player.Storm_Effects[5] = Last Created Entity; + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Storm_Projectile, Ray Cast Hit Position( + Event Player.Storm_Projectile, Vector(0.100, 0, 0) + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), + False), Color(Aqua), Visible To Position and Radius); + Event Player.Storm_Effects[6] = Last Created Entity; + While(Distance Between(Event Player.Storm_Projectile, Event Player.Storm_EndPoint) > 1); + Wait(0.600, Ignore Condition); + Damage(Players Within Radius(Ray Cast Hit Position(Event Player.Storm_Projectile, Event Player.Storm_Projectile + Down * 1000, + Null, All Players(All Teams), False), 3, Team Of(Event Player), Surfaces), Attacker, 50); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + End; + Destroy Effect(Event Player.Storm_Effects[3]); + Destroy Effect(Event Player.Storm_Effects[4]); + Destroy Effect(Event Player.Storm_Effects[5]); + Destroy Effect(Event Player.Storm_Effects[6]); + } +} + +rule("Hanzo: Punch II") +{ + event + { + Player Dealt Damage; + Team 1; + Hanzo; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + Hero Of(Victim) != Hero(Torbjörn); + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.800); + Apply Impulse(Victim, Facing Direction Of(Event Player), 12, To World, Cancel Contrary Motion); + Apply Impulse(Victim, Up, 5, To World, Cancel Contrary Motion); + Set Environment Credit Player(Victim, Event Player); + Set Status(Victim, Null, Stunned, 1); + } +} + +rule("Widowmaker: Kiss Of Death") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + (Normalized Health(Victim) <= 0.300 || Event Damage >= Normalized Health(Victim) + Event Damage) == True; + Is Firing Secondary(Event Player) == True; + Event Ability == Button(Primary Fire); + Event Player.Abilities[8] == True; + Event Damage >= 40; + Event Was Critical Hit == True; + } + + actions + { + Kill(Victim, Event Player); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 2), Victim, 3); + Damage(Players Within Radius(Victim, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage * 1.500); + } +} + +rule("Widowmaker: Epidemic") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 8); + Play Effect(All Players(All Teams), Good Explosion, Color(Purple), Victim, 4); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Victim, 16); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Victim, 3); + Start Damage Over Time(Players Within Radius(Victim, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, 50); + Start Heal Over Time(Event Player, Event Player, 3, 50); + Wait(0.500, Ignore Condition); + } +} + +rule("McCree: Panic") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Victim.Feared_until = Total Time Elapsed + 3.500; + } +} + +rule("McCree: Panic - Damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), + Event Player.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 220, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("McCree: Clocked") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Damage(Victim, Event Player, Event Damage * 1.500); + Set Status(Victim, Null, Knocked Down, 3); + } +} + +rule("Reinhardt: Fire Blast") +{ + event + { + Player Dealt Damage; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Start Damage Over Time(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, 20); + Set Status(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Burning, 5); + } +} + +rule("Reinhardt: Epicenter") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is On Ground(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, Knocked Down, 2.500); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 10); + Damage(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, 50); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 20); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 30); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 40); + Wait(5, Ignore Condition); + } +} + +rule("[Soldier: 76] Rocket Assault Rifle") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile2 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(-2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Projectile1 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Position = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, + 0), Event Player, Rotation); + Event Player.Ability_End = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, 0), + Event Player, Rotation); + Chase Player Variable At Rate(Event Player, Ability_Position, Event Player.Ability_Projectile1, 60, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_End, Event Player.Ability_Projectile2, 60, Destination and Rate); + Wait Until(Event Player.Ability_Position == 0 && Event Player.Ability_End == 0, 2.500); + } +} + +rule("[Soldier: 76] First Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile1 != Event Player.Ability_Position; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_Position, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_Position, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_Position, 2.500); + Stop Chasing Player Variable(Event Player, Ability_Position); + Wait(0.016, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 80); + Stop Chasing Player Variable(Event Player, Ability_Position); + Event Player.Ability_Position = 0; + Event Player.Ability_Projectile1 = 0; + Wait(0.016, Ignore Condition); + } +} + +rule("[Soldier: 76] Second Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile2 != Event Player.Ability_End; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_End, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_End, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_End, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_End, 2.500); + Stop Chasing Player Variable(Event Player, Ability_End); + Damage(Players Within Radius(Event Player.Ability_End, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Event Player.Ability_End = 0; + Event Player.Ability_Projectile2 = 0; + } +} + +rule("Soldier: 76 - Init rockets") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile1 = Event Player.Ability_Position; + Event Player.Ability_Projectile2 = Event Player.Ability_End; + } +} + +rule("[Soldier: 76] Shoulder Check") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 3; + Is Alive(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) == True; + } + + actions + { + Damage(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Event Player, 55); + Set Status(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Null, Knocked Down, 1.500); + Apply Impulse(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Facing Direction Of(Event Player), 15, + To World, Cancel Contrary Motion); + Apply Impulse(Event Player, Vector(0, 8, 15), 15, To Player, Cancel Contrary Motion); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Closest Player To(Event Player, Opposite Team Of(Team Of( + Event Player))), 1); + Set Ability Cooldown(Event Player, Button(Melee), 0); + Press Button(Event Player, Button(Melee)); + Wait(1, Ignore Condition); + } +} + +rule("Torbjorn: Melting Point") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Event Player.Abilities[8] == True; + (Is Using Ability 2(Event Player) || Is Using Ultimate(Event Player)) == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Event Player, 8); + Play Effect(All Players(All Teams), Bad Explosion, Color(Yellow), Event Player, 8); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 16); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, + 25); + Set Status(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Off), Null, Burning, 3); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player, 100); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Torbjorn: Roots of Magma") +{ + event + { + Player Dealt Damage; + Team 1; + Torbjörn; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Set Status(Victim, Null, Rooted, 1); + Wait(1, Ignore Condition); + } +} + +rule("Tracer: Vortex") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, 0); + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 10); + Play Effect(All Players(All Teams), Ring Explosion, Color(Red), Position Of(Event Player), 24); + Play Effect(All Players(All Teams), Ring Explosion, Color(Yellow), Position Of(Event Player), 18); + Play Effect(All Players(All Teams), Ring Explosion, Color(Green), Position Of(Event Player), 12); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player), 6); + Set Environment Credit Player(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player); + } +} + +rule("Tracer: Vortex 2") +{ + event + { + Player Received Healing; + Team 2; + All; + } + + conditions + { + Healer.Abilities[8] == True; + Hero Of(Healer) == Hero(Tracer); + Is Using Ability 2(Healer) == True; + Event Ability == Null; + Event Damage <= 20; + } + + actions + { + Apply Impulse(Event Player, Up, 5, To World, Cancel Contrary Motion); + Wait(0.100, Ignore Condition); + Apply Impulse(Event Player, Direction Towards(Event Player, Healer), Distance Between(Event Player, Healer) * 3.500, To World, + Cancel Contrary Motion); + Set Status(Event Player, Null, Rooted, 1.300); + } +} + +rule("Tracer: Chain Reaction") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is True For Any(Filtered Array(All Players(Team Of(Event Player)), Current Array Element.Chain_Reaction_On), Distance Between( + Event Player, Current Array Element) <= 8 && True) == True; + Event Player.Chain_Reaction_Immune == False; + Event Player.Chain_Reaction_On == False; + Is Alive(Event Player) == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Event Player.Chain_Reaction_On = True; + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player, 3); + } +} + +rule("Tracer: Chain Reaction 2") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Event Player.Chain_Reaction_On == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Aqua), Event Player, 3); + Damage(Event Player, Players On Hero(Hero(Tracer), Opposite Team Of(Team Of(Event Player))), 200); + Wait(0.500, Ignore Condition); + Event Player.Chain_Reaction_Immune = True; + Event Player.Chain_Reaction_On = False; + Wait(2, Ignore Condition); + Event Player.Chain_Reaction_Immune = False; + } +} + +rule("Tracer: Chain Reaction 3") +{ + event + { + Player Dealt Damage; + Team 1; + Tracer; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Damage > 20; + Event Player.Abilities[12] == True; + } + + actions + { + Victim.Chain_Reaction_On = True; + } +} + +rule("[Winston] Electric Field") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 65); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Orb, Color(White), Event Player.Ability_Projectile1, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Stop Chasing Player Variable(Event Player, Ability_Resource); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Down * 1000, Null, + All Players(All Teams), False); + Wait(0.100, Ignore Condition); + Event Player.Ability_Resource = 5; + Wait(0.250, Ignore Condition); + Chase Player Variable At Rate(Event Player, Ability_Resource, 20, 7, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, Event Player.Ability_Resource, + Destination and Rate); + Wait(8.650, Restart When True); + Event Player.Ability_Active = False; + } +} + +rule("[Winston] Electric Field 2") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 33); + Play Effect(All Players(All Teams), Ring Explosion, Color(Blue), Event Player.Ability_Projectile1, 10); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 80); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Event Player.Ability_Projectile1, 12); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player.Ability_Projectile1, 125); + } +} + +rule("Winston: Next Generation") +{ + event + { + Player Earned Elimination; + Team 1; + Winston; + } + + conditions + { + Ultimate Charge Percent(Event Player) <= 80; + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 15); + } +} + +rule("Pharah: Head Trauma") +{ + event + { + Player Dealt Knockback; + Team 1; + Pharah; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Victim != Event Player; + } + + actions + { + Damage(Victim, Event Player, Max Health(Victim) * 0.300); + Set Status(Victim, Event Player, Knocked Down, 1); + Play Effect(All Players(All Teams), Good Explosion, Color(Team 1), Victim, 1); + } +} + +rule("Pharah: Thunderbird") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[12] == True; + Hero Of(Event Player) == Hero(Pharah); + } + + actions + { + Event Player.DamageDealt *= 4; + Start Damage Modification(All Players(All Teams), Event Player, 25, Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Add Health Pool To Player(Event Player, Shields, 150, True, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(!Event Player.Abilities[12] || Hero Of(Event Player) != Hero(Pharah), 99999); + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Stop Damage Modification(Event Player.Modification_Damage[1]); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + } +} + +rule("Orisa: Unstoppable Force") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Direction = Facing Direction Of(Event Player); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Sphere, Color(Green), Event Player.Ability_Projectile1, 4, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player) + Facing Direction Of(Event Player) * 0.500; + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 100, Null, All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 25, Destination and Rate); + Wait(0.250, Ignore Condition); + Wait Until((!Event Player.Gen_Available && Is Button Held(Event Player, Button(Secondary Fire))) || ( + Event Player.Ability_Projectile1 == Event Player.Ability_End), 99999); + Stop Chasing Player Variable(Event Player, Ability_Projectile1); + Wait(0.500, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, + 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Orisa: Availability for Halt!") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Available = True; + Wait Until(!Is Button Held(Event Player, Button(Secondary Fire)), 99999); + Event Player.Gen_Available = False; + } +} + +rule("Orisa: Drag effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Player.Ability_Active == True; + } + + actions + { + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Is Alive(Event Player) ? Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of( + Event Player)), Surfaces) : Empty Array, Event Player.Ability_Projectile1), 8, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Event Player.Ability_Projectile1, Event Player.Ability_End), 20, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Up, 5, + To Player, Cancel Contrary Motion); + Wait(0.200, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Orisa: Immoveable Object - Reduce dmg") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Damage Received(Event Player, 100 * 0.003); + Wait Until(!Is Using Ability 1(Event Player), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Orisa: Immovable Object - Healing") +{ + event + { + Player Took Damage; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Event Player, Null, Event Damage * 3); + } +} + +rule("[Reaper] Shadow Streak (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Event Player.Ability_Position = Position Of(Event Player) + Vector(0, 1, 0); + Wait(2, Abort When False); + Event Player.Ability_End = Position Of(Event Player) + Vector(0, 1, 0); + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Ability_End, Event Player.Ability_Position, Color(Black), + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player) || Is Using Ability 2(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage start to end (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players(Opposite Team Of(Team Of( + Event Player))), Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_Position, + Event Player.Ability_End, All Living Players(All Teams), Event Player, True), 1); + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage end to start (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Players(Opposite Team Of(Team Of(Event Player))), + Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_End, + Event Player.Ability_Position, All Living Players(All Teams), Event Player, True), 1); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Reaper: Loom") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Hacked, 1.500); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Rooted, 1.500); + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Event Player, 45); + } +} + +rule("Sigma: Gravity Well") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, 25); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Null, Rooted, 2); + Set Status(Event Player, Null, Invincible, 1); + Play Effect(Event Player, Ring Explosion, Color(Blue), Eye Position(Event Player), 50); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Sigma: Gravity Channels") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ultimate(Event Player)), Event Player, 150, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[12], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Echo: Focusing Optics") +{ + event + { + Player Dealt Damage; + Team 1; + Echo; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Normalized Health(Victim) > 0.500; + Normalized Health(Victim) <= 0.900; + Is Duplicating(Event Player) == False; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 3); + Play Effect(All Players(All Teams), Bad Explosion, Color(Violet), Victim, 0.500); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Wait(0.700, Abort When False); + Cancel Primary Action(Event Player); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Set Projectile Speed(Event Player, 100); + Wait(0.150, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Bomblets") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Is In Alternate Form(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Orange), Null + Ray Cast Hit Position(Eye Position(Event Player), + Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, All Living Players(Opposite Team Of(Team Of( + Event Player))), All Players(Team Of(Event Player)), True), 2); + Damage(Players Within Radius(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 2, + Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 12); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Taser - Loop damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is True For Any(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive(Current Array Element) + && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status(Current Array Element, + Phased Out) && Distance Between(Event Player, Current Array Element) <= 25) == True; + Is Alive(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Explosion Sound, Color(White), Event Player.Ability_Player, 80); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Event Player.Ability_Player, 1); + Event Player.Ability_Player = Filtered Array(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive( + Current Array Element) && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status( + Current Array Element, Phased Out) && Distance Between(Event Player, Current Array Element) <= 25); + Damage(Players Within Radius(Event Player.Ability_Player, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 30); + Wait(0.450, Ignore Condition); + Loop If Condition Is True; + Event Player.Ability_Player = Null; + } +} + +rule("Bastion: Taser - Visual beam") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player + Vector(False, 1, False), + Event Player.Ability_Player != Null ? Event Player.Ability_Player : Event Player, Color(Aqua), + Visible To Position Radius and Color); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[12], 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Sombra: Malware") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, + Hacked) || Current Array Element.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 200, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Sombra: Glitch") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Ability_Active = True; + Event Player.Ability_Position = Position Of(Event Player); + Create Effect(All Players(All Teams), Sphere, Color(Purple), Event Player.Ability_Position, 15, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait(8, Ignore Condition); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Sombra: Glitch - Loop") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Ability_Active == True; + } + + actions + { + Set Status(Players Within Radius(Event Player.Ability_Position, 15, Opposite Team Of(Team Of(Event Player)), Off), Null, Hacked, + 0.750); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Mei: Cold Snap") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Event Player, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Is Using Ability 1(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Damage(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Frozen, 2); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Rooted, 2); + Play Effect(All Players(All Teams), Ring Explosion, Color(White), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Sky Blue), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player) + Vector(0, 1, 0), 20); + } +} + +rule("Mei: Icebound") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Aqua), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Set Projectile Speed(Event Player, 200); + Wait Until(!Is Firing Secondary(Event Player), 99999); + Destroy Effect(Event Player.Effects_[2]); + Set Projectile Speed(Event Player, 100); + } +} + +rule("Mei: Icebound - Icicles hit") +{ + event + { + Player Dealt Damage; + Team 1; + Mei; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 1.250); + Set Status(Victim, Null, Frozen, 1); + Set Status(Victim, Null, Rooted, 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Victim, 1); + } +} + +rule("Wrecking Ball: Mirror Ball") +{ + event + { + Player Took Damage; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 4.500, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage); + Wait(0.100, Ignore Condition); + } +} + +rule("Wrecking Ball: Distort") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Set Status(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Hacked, Count Of( + Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces)) * 1.500); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Violet), Position Of(Event Player), 125); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Sound, Color(Purple), Position Of(Event Player), 16); + Play Effect(All Players(All Teams), Explosion Sound, Color(Violet), Position Of(Event Player), 80); + } +} + +rule("Symmetra: High voltage") +{ + event + { + Player Dealt Final Blow; + Team 1; + Symmetra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Victim, 10); + Play Effect(All Players(All Teams), Bad Explosion, Color(Aqua), Victim, 8); + Damage(Players Within Radius(Victim, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 150); + } +} + +rule("Symmetra: Energy Source") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is True For Any(Players On Hero(Hero(Symmetra), Team Of(Event Player)), Is Using Ultimate(Current Array Element) + && Current Array Element.Abilities[12]) == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 1, 40); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Event Player, 0.100); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Junkrat: Pyromania") +{ + event + { + Player Dealt Knockback; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability != Button(Melee); + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 2, 30); + Set Status(Victim, Null, Burning, 2); + } +} + +rule("Junkrat: Short Fused") +{ + event + { + Player Dealt Damage; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + } + + actions + { + Event Player.Ability_Countdown = 4; + While(Event Player.Ability_Countdown > 0); + Event Player.Ability_Countdown -= 1; + Event Player.Ability_Position = Position Of(Victim) + Vector(Random Real(-2, 2), Random Real(-2, 2), Random Real(-2, 2)); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 4); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Position, 4); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 35); + Set Status(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player, Stunned, 0.800); + Wait(0.200, Ignore Condition); + End; + } +} + +rule("Zenyatta: Vigor") +{ + event + { + Player Dealt Healing; + Team 1; + Zenyatta; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Healee, Null, Invincible, 1); + Wait(0.800, Ignore Condition); + } +} + +rule("Zenyatta: Perfect Balance") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Over Time(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 0.750, 200); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player, 24); + Wait(0.600, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Stench") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Violet), Event Player, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Roadhog: Stench effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 8; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 9); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Rusted Anchor") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ability 1(Event Player)), Event Player, 400, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Roadhog: Rusted Anchor - Reset cooldown") +{ + event + { + Player Earned Elimination; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ability 1(Event Player), 3); + Set Ability Cooldown(Event Player, Button(Ability 1), False); + } +} + +rule("Zarya: Augment") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Scaling Barriers(Event Player, 2, True); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5 + 50; + Set Max Health(Event Player, Event Player.PlayerHealth); + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Zarya), 99999); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Stop Scaling Barriers(Event Player); + } +} + +rule("Zarya: Perpetual Energy") +{ + event + { + Player Dealt Knockback; + Team 1; + Zarya; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Event Player.Abilities[12] == True; + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 9999, 15); + Set Status(Victim, Null, Burning, 9999); + } +} + +rule("Doomfist: Phase Shifter") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + (Is Firing Secondary(Event Player) || Is Using Ability 1(Event Player) || Is Using Ability 2(Event Player)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Event Player, Null, Phased Out, 1); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ultimate(Event Player), 99999); + Event Player.Ability_Position = Position Of(Event Player); + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player), 8); + Event Player.Ability_Active = False; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player.Ability_Position, 16); + While(Event Player.Ability_Active == True); + Damage(Players Within Radius(Event Player.Ability_Position, 8, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 34); + Wait(0.235, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[1]); + Destroy Effect(Event Player.Effects_[2]); + } +} + +rule("Team 1 (Perk): Sharpshooter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Global.Perk[0] == True; + Event Ability != Null; + Distance Between(Event Player, Victim) >= 10; + } + + actions + { + Damage(Victim, Event Player, 50 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Perk): Bulletstorm") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.Perk[1] == True; + (Ammo(Event Player, 0) < Max Ammo(Event Player, 0) || Ammo(Event Player, 1) < Max Ammo(Event Player, 1)) == True; + } + + actions + { + Set Ammo(Event Player, 0, 1000); + Set Ammo(Event Player, 1, 1000); + } +} + +rule("Team 1 Challenges") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + If(Global.Perk[2] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[17] = Last Text ID; + End; + If(Global.Perk[0] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[18] = Last Text ID; + End; + If(Global.Perk[1] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[19] = Last Text ID; + End; + If(Global.MaxHealthDone == 50); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + End; + } +} + +rule("Remove Auto Repair when Player leaves") +{ + event + { + Player Left Match; + Team 1; + All; + } + + actions + { + Global.AutoRepair -= Event Player.Abilities[16]; + } +} + +rule("Refund") +{ + event + { + Subroutine; + Refund; + } + + actions + { + "Refund Money" + Event Player.Money[0] += Event Player.Money[1]; + Event Player.Money[1] = 0; + "Reset Headhunter" + Event Player.Abilities[1] = 0; + "Reset Ambush" + Event Player.Abilities[2] = 0; + "Reset QuickFix" + Event Player.Abilities[3] = 0; + "Reset HeavyWeight" + Event Player.Abilities[4] = 0; + "Reset Charged" + Event Player.Abilities[5] = 0; + "Reset Haste" + Event Player.Abilities[6] = 0; + "Reset HeavyImpact" + Event Player.Abilities[7] = 0; + "Reset HeroTalent1" + Event Player.Abilities[8] = 0; + "Reset SecondWind" + Event Player.Abilities[9] = 0; + "Reset BindingHeal" + Event Player.Abilities[10] = 0; + "Reset Resilience" + Event Player.Abilities[11] = 0; + "Reset HeroTalent2" + Event Player.Abilities[12] = 0; + "Reset Damage" + Event Player.Abilities[13] = 0; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + "Reset Health" + Event Player.Abilities[14] = 0; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + If(Global.MaxHealthDone == 0); + End; + "Reset Healing" + Event Player.Abilities[15] = 0; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + "Reset AutoRepair" + Global.AutoRepair -= Event Player.Abilities[16]; + Event Player.Abilities[16] = 0; + } +} + +rule("Lucio Dash HUD Creation") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + } + + actions + { + If(Event Player.Lucio_Dash_Active == False); + Event Player.Lucio_Dash_Active = True; + Create HUD Text(Event Player, Null, Null, Custom String("{0} Slam on ground - Press: {1}", Ability Icon String(Hero(Wrecking Ball), + Button(Crouch)), Input Binding String(Button(Crouch))), Left, 1000, Color(White), Color(White), Color(White), + Visible To and String, Default Visibility); + Event Player.Lucio_Dash_Icon = Last Text ID; + End; + } +} + +rule("Lucio Dash Remove HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) != Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + } + + actions + { + Destroy HUD Text(Event Player.Lucio_Dash_Icon); + Event Player.Lucio_Dash_Active = False; + } +} + +rule("Lucio Dash") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + Is On Ground(Event Player) == False; + Is Button Held(Event Player, Button(Crouch)) == True; + } + + actions + { + Apply Impulse(Event Player, Down, 20, To World, Cancel Contrary Motion); + } +} + +rule("Ana Self-Nano") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + Ultimate Charge Percent(Event Player) == 100; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Abort If(Global.SelfNanoWorkshopSetting == False && Number Of Players(Team 1) > 1); + Wait(0.100, Ignore Condition); + If(Is Using Ultimate(Event Player) == False); + Create Dummy Bot(Hero(Ana), Team Of(Event Player), -1, Position Of(Event Player) + Backward, Eye Position(Event Player)); + Event Player.AnaEntityID = Last Created Entity; + Wait(0.100, Ignore Condition); + Set Ultimate Charge(Event Player.AnaEntityID, 100); + Start Facing(Event Player.AnaEntityID, Direction Towards(Eye Position(Event Player.AnaEntityID), Position Of(Event Player) + Up), + 1000, To World, Direction and Turn Rate); + Set Invisible(Event Player.AnaEntityID, All); + Set Status(Event Player.AnaEntityID, Null, Phased Out, 9999); + Wait(0.150, Ignore Condition); + Press Button(Event Player.AnaEntityID, Button(Ultimate)); + Set Ultimate Charge(Event Player, 0); + Wait(0.150, Ignore Condition); + Teleport(Event Player.AnaEntityID, Position Of(First Of(Spawn Points(Team Of(Event Player))))); + Wait(10, Ignore Condition); + Destroy Dummy Bot(Team Of(Event Player), Slot Of(Event Player.AnaEntityID)); + End; + } +} + +rule("Reinhard Charge Cancel") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + } + + actions + { + Wait(0.600, Ignore Condition); + Wait Until(Is Button Held(Event Player, Button(Ability 1)), 5); + Set Status(Event Player, Null, Rooted, 0.001); + Wait Until(Event Player.ReinPin, 1); + If(Event Player.ReinPin != 0); + Apply Impulse(Event Player.ReinPin, Facing Direction Of(Event Player), 15, To World, Cancel Contrary Motion); + End; + } +} + +disabled rule("Map Editor Walls") +{ + event + { + Ongoing - Global; + } +} + +rule("Initial Global") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Empty Array; + Global.AllDir = Empty Array; + Global.firstpos = Empty Array; + Global.secondpos = Empty Array; + Global.firstpoint2 = Empty Array; + Global.secondpoint2 = Empty Array; + Global.second = Empty Array; + Global.z = Empty Array; + Global.Wall_ID = Empty Array; + Global.g_beamType = Empty Array; + } +} + +rule("Initial Player") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.filterpos = 0; + Event Player.lastsavedpos = 0; + Event Player.closestbodypos = 0; + Event Player.fullbodypos = 0; + Event Player.prevpos_intersection = 0; + Event Player.active_wall = Empty Array; + Event Player.closestwall = Empty Array; + } +} + +rule("Collision Logic") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Event Player.lastsavedpos = (Eye Position(Event Player) + Position Of(Event Player)) / 2; + Wait(0.016, Ignore Condition); + Event Player.closestwall = Filtered Array(Global.AllPos, Distance Between(Global.AllPos[Current Array Index], Event Player) + <= Distance Between(Global.AllPos[Current Array Index], Global.firstpos[Current Array Index]) + || Event Player.active_wall[Current Array Index] == 1 || (Dot Product(Direction Towards(Current Array Element, + Event Player.lastsavedpos), Global.AllDir[Current Array Index]) > 0) != (Dot Product(Direction Towards(Current Array Element, + Event Player), Global.AllDir[Current Array Index]) > 0)); + For Player Variable(Event Player, x, 0, Count Of(Event Player.closestwall), 1); + Global.z = Index Of Array Value(Global.AllPos, Event Player.closestwall[Event Player.x]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3 || Global.Wall_ID[Global.z] == 5); + If(Y Component Of(Global.firstpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.firstpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.firstpos[Global.z]; + Else If(Y Component Of(Global.secondpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.secondpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.secondpos[Global.z]; + Else; + Event Player.closestbodypos = Position Of(Event Player); + End; + Event Player.fullbodypos = Vector(X Component Of(Eye Position(Event Player)), Y Component Of(Event Player.closestbodypos), + Z Component Of(Eye Position(Event Player))); + Event Player.filterpos = Event Player.fullbodypos + Global.AllDir[Global.z] * Dot Product( + Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) / Dot Product(Global.AllDir[Global.z], + Global.AllDir[Global.z]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3); + If((Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.lastsavedpos), Global.AllDir[Global.z]) > 0) != ( + Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.fullbodypos), Global.AllDir[Global.z]) > 0)); + Event Player.intersection_length = Dot Product(Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) + / Dot Product(Direction Towards(Event Player.lastsavedpos, Event Player.fullbodypos), Global.AllDir[Global.z]); + Event Player.prevpos_intersection = Event Player.fullbodypos + Direction Towards(Event Player.lastsavedpos, + Event Player.fullbodypos) * Vector(1, Empty Array, 1) * Event Player.intersection_length; + If(Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of( + Global.firstpos[Global.z]), Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], + Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of( + Global.firstpos[Global.z]), Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), + Direction Towards(Global.firstpos[Global.z], Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards( + Global.secondpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.prevpos_intersection)) + >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.secondpos[Global.z], Event Player.prevpos_intersection)) >= 0); + Cancel Primary Action(Event Player); + Teleport(Event Player, Event Player.prevpos_intersection + Direction Towards(Event Player.prevpos_intersection, + Event Player.lastsavedpos) * Vector(1, Empty Array, 1) * 2); + End; + End; + End; + Event Player.thickness = 0; + If(Global.Wall_ID[Global.z] == 5); + Event Player.thickness = 4; + Else; + Event Player.thickness = 1; + End; + If(Distance Between(Event Player.fullbodypos, Event Player.filterpos) <= Event Player.thickness && Dot Product(Direction Towards( + Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], Event Player.filterpos)) + >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.firstpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector( + X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), Z Component Of( + Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product( + Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), Y Component Of( + Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], + Event Player.filterpos)) >= 0); + If(!Global.is_Grounded); + Set Gravity(Event Player, 100); + End; + If(Event Player.active_wall[Global.z] == False); + Event Player.active_wall[Global.z] = 1; + If((Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3) && Global.is_Grounded == False); + Set Gravity(Event Player, 100); + Else If(Global.Wall_ID[Global.z] == 5); + Disable Movement Collision With Environment(Event Player, False); + End; + End; + If(Global.Wall_ID[Global.z] == 1); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos) * Vector(1, Empty Array, 1), 0.001, + To World, Cancel Contrary Motion); + Set Move Speed(Event Player, 100 - Dot Product(Direction Towards(Eye Position(Event Player), Eye Position(Event Player) + + World Vector Of(Throttle Of(Event Player), Event Player, Rotation)), Direction Towards(Event Player.filterpos, + Event Player.fullbodypos) * -1) * 100); + Else If(Global.Wall_ID[Global.z] == 3); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos), Speed Of(Event Player), To World, + Cancel Contrary Motion); + End; + Else; + Event Player.active_wall[Global.z] = 0; + Set Move Speed(Event Player, 100); + End; + End; + End; + Loop; + } +} + +rule("Reset") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Count Of(Filtered Array(Event Player.active_wall, Current Array Element != 0)) == 0; + } + + actions + { + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("Effect Creation") +{ + event + { + Ongoing - Global; + } + + actions + { + Wait(5, Ignore Condition); + If(Global.showwalls); + For Global Variable(x, 0, Count Of(Global.AllPos), 1); + If(Global.Wall_ID[Global.x] == 5); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Else; + Skip(Array(14, 0, 5, 10)[Index Of Array Value(Array(1, 2, 3), Global.g_beamType[Global.x]) + 1]); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(9); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(4); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + End; + Wait(0.016, Ignore Condition); + End; + End; + } +} + +rule("Wall Data") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Array(Vector(155.968, 12.470, -30.507), Vector(155.962, 12.472, -62.500), Vector(81.153, 6.453, -103.851), Vector( + 69.148, 6.474, -104.548)); + Global.AllDir = Array(Vector(-1, 0, -0.002), Vector(1, 0, -0.001), Vector(0, 0, 1), Vector(0.001, 0, 1)); + Global.firstpos = Array(Vector(155.971, 11.047, -31.771), Vector(155.964, 11.050, -61.229), Vector(79.761, 5.030, -103.852), + Vector(67.738, 5.022, -104.547)); + Global.secondpos = Array(Vector(155.965, 13.894, -29.242), Vector(155.960, 13.894, -63.771), Vector(82.544, 7.876, -103.851), + Vector(70.558, 7.925, -104.550)); + Global.firstpoint2 = Array(Vector(155.971, 13.894, -31.771), Vector(155.964, 13.894, -61.229), Vector(79.761, 7.876, -103.852), + Vector(67.738, 7.925, -104.547)); + Global.secondpoint2 = Array(Vector(155.965, 11.047, -29.242), Vector(155.960, 11.050, -63.771), Vector(82.544, 5.030, -103.851), + Vector(70.558, 5.022, -104.550)); + Global.z = 3; + Global.g_beamType = Array(1, 1, 1, 1); + Global.showwalls = True; + Global.Wall_ID = Array(5, 5, 5, 5); + } +} + +disabled rule("NEW SHOP") +{ + event + { + Ongoing - Global; + } +} + +rule("Setting Shop Position") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.ShopCamPos = 900 * Up; + Global.ShopPosAngle[1] = Direction From Angles(Horizontal Angle From Direction(Forward), Vertical Angle From Direction(Forward) + - 90); + Global.ShopPosAngle[0] = Cross Product(Global.ShopPosAngle[1], Forward); + Global.ShopBasePos = Global.ShopCamPos - 9 * Global.ShopPosAngle[1] + 142 * Forward; + } +} + +rule("Create Shop Buttons") +{ + event + { + Ongoing - Global; + } + + actions + { + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] + 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] - 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Refund"), + Global.ShopBasePos + 45 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 3, Do Not Clip, Visible To, Color(Green), + Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("[{0}] Leave", + Input Binding String(Button(Reload))), Global.ShopBasePos + 45 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 3, + Do Not Clip, Visible To and String, Color(Green), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("{0}$\n", Local Player.Money[0]), + Global.ShopBasePos + 36.500 * Global.ShopPosAngle[1], 3, Do Not Clip, Visible To and String, Color(White), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("▲"), Update Every Frame( + Global.ShopBasePos - (4 + Vertical Facing Angle Of(Local Player)) * Global.ShopPosAngle[1] + Horizontal Facing Angle Of( + Local Player) * Global.ShopPosAngle[0]), 4, Do Not Clip, Visible To Position and Color, Custom Color( + 245 + 10 * Sine From Radians(4 * Total Time Elapsed), 205 + 50 * Sine From Radians(4 * Total Time Elapsed), + 200 * Sine From Radians(4 * Total Time Elapsed), 255), Default Visibility); + "Headhunter" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[1] ? Custom String("Headhunter II\n  800$") : Custom String("Headhunter I\n  800$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[1] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Ambush" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[2] ? Custom String("Ambush II\n 800$") : Custom String("Ambush I\n 800$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[2] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Quick Fix" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[3] ? Custom String("Quick Fix II\n  700$") : Custom String("Quick Fix I\n  700$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[3] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavyweight" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[4] ? Custom String("Heavyweight II\n  1000$") : Custom String("Heavyweight I\n  1000$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[4] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Charged" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[5] ? Custom String("Charged II\n  700$") : Custom String("Charged I\n  700$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[5] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Haste" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[6] ? Custom String("Haste II\n 700$") : Custom String("Haste I\n 700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[6] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavy Impact" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[7] ? Custom String("Heavy Impact II\n  1000$") : Custom String("Heavy Impact I\n  1000$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[7] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 1" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 1\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[8] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "Second Wind" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[9] ? Custom String("Second Wind II\n   900$") : Custom String("Second Wind I\n   900$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[9] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Binding Heal" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[10] ? Custom String("Binding Heal II\n   700$") : Custom String("Binding Heal I\n   700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[10] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Resilience" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[11] ? Custom String("Resilience II\n  800$") : Custom String("Resilience I\n  800$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[11] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 2" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 2\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[12] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "PlusDamage" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Damage\n  400$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealth" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Health\n 400$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Healing\n  400$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, Visible To and String, + Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "+{0} Auto-Repair\n    400$", Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Global.AutoRepair < 5 ? Color(Green) : Color(Gray), Default Visibility); + "Use Update Every Frame to avoid showing the String when the cursor is out of bounds, resulting in 0\r\n ROW 0" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -33.750 ? Array(Custom String("Leave Buy Menu\n"), Custom String( + ""), Custom String(""), Custom String("Refund your money\n"))[Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) + / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, + Color(White), Default Visibility); + "ROW 1" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 22.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -11.250 ? Array(Custom String("Increase your damage by 5%\n"), + Local Player.Abilities[9] ? Custom String( + "Second Wind II: 60% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds") + : Custom String( + "Second Wind I: 30% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds"), + Local Player.Abilities[5] ? Custom String("Charged II: Ultimates cost 40% less\n") : Custom String( + "Charged I: Ultimates cost 20% less\n"), Local Player.Abilities[1] ? Custom String( + "Headhunter II: Critical hits deal 80% more damage\n") : Custom String("Headhunter I: Critical hits deal 40% more damage\n")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 2" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 36.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 11.250 ? Array(Custom String("Increase your health by 5%\n"), + Local Player.Abilities[10] ? Custom String("Binding Heal II: Heal yourself for 50% the amount when healing allies\n") + : Custom String("Binding Heal I: Heal yourself for 25% the amount when healing allies\n"), + Local Player.Abilities[6] ? Custom String( + " Haste II: Ability cooldown is reduced by 50%\nDoes not affect abilities with multiple charges") : Custom String( + " Haste I: Ability cooldown is reduced by 25%\nDoes not affect abilities with multiple charges"), + Local Player.Abilities[2] ? Custom String("Ambush II: Deal 60% more damage when attacking enemies from behind or above\n") + : Custom String("Ambush I: Deal 30% more damage when attacking enemies from behind or above\n"))[Round To Integer(( + Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 3" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 83.750) < 72.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 33.750 ? Array(Custom String("Increase your healing by 5%\n"), + Local Player.Abilities[11] ? Custom String("Resilience II: Take 30% less damage while below 60% health\n") : Custom String( + "Resilience I: Take 30% less damage while below 30% health\n"), Local Player.Abilities[7] ? Custom String( + "Heavy Impact II: Every hit has a chance to stun the enemy for 2 seconds\n") : Custom String( + "Heavy Impact I: Every hit has a chance to stun the enemy for 1 second\n"), Local Player.Abilities[3] ? Custom String( + "Quick Fix II: Eliminations restore 100 HP and shortly increase speed by 40%\n") : Custom String( + "Quick Fix I: Eliminations restore 50 HP and shortly increase speed by 20%\n"))[Round To Integer((Horizontal Facing Angle Of( + Local Player) + 90) / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, + Visible To and String, Color(White), Default Visibility); + "ROW 4" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 133) < 99.250 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 56.250 ? Array(Custom String( + "Increase your auto-repair by {0}/5s\n", Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Custom String("{0}", Local Player.HeroTalentText[2][1]), Custom String("{0}", Local Player.HeroTalentText[1][1]), + Local Player.Abilities[4] ? Custom String( + "Heavyweight II: Your knock back attacks deal 50% more damage and knock back\n            You receive 33% less knock back") + : Custom String( + "Heavyweight I: Your knock back attacks deal 25% more damage and knock back\n            You receive 20% less knock back")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + } +} + +rule("Toggle Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + !Is Dummy Bot(Event Player) == True; + Is Button Held(Event Player, Button(Reload)) == True; + !Is Communicating Any Emote(Event Player) == True; + } + + actions + { + If(Event Player.isInMenu == False); + Wait Until(!Is Button Held(Event Player, Button(Reload)), 0.500); + If(!Is Button Held(Event Player, Button(Reload))); + Abort; + End; + End; + Event Player.isInMenu = !Event Player.isInMenu; + } +} + +rule("Open Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == True; + } + + actions + { + Event Player.PlayerFacing = Facing Direction Of(Event Player); + Start Camera(Event Player, Global.ShopCamPos, Global.ShopCamPos + Forward, 0); + Disable Hero HUD(Event Player); + Call Subroutine(DisablePlayer); + Set Aim Speed(Event Player, 200); + } +} + +rule("Close Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == False; + } + + actions + { + Stop Camera(Event Player); + Enable Hero HUD(Event Player); + Call Subroutine(EnablePlayer); + Set Aim Speed(Event Player, 100); + Set Facing(Event Player, Event Player.PlayerFacing, To World); + } +} + +rule("Subroutine: Disable Player") +{ + event + { + Subroutine; + DisablePlayer; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + Set Primary Fire Enabled(Event Player, False); + Set Secondary Fire Enabled(Event Player, False); + Set Ability 1 Enabled(Event Player, False); + Set Ability 2 Enabled(Event Player, False); + Set Melee Enabled(Event Player, False); + Set Jump Enabled(Event Player, False); + Set Crouch Enabled(Event Player, False); + Disallow Button(Event Player, Button(Ultimate)); + } +} + +rule("Subroutine: Enable Player") +{ + event + { + Subroutine; + EnablePlayer; + } + + actions + { + Stop Forcing Throttle(Event Player); + Set Primary Fire Enabled(Event Player, True); + Set Secondary Fire Enabled(Event Player, True); + Set Ability 1 Enabled(Event Player, True); + Set Ability 2 Enabled(Event Player, True); + Set Melee Enabled(Event Player, True); + Set Jump Enabled(Event Player, True); + Set Crouch Enabled(Event Player, True); + Allow Button(Event Player, Button(Ultimate)); + } +} + +rule("Buy Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Primary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + Event Player.isInMenu = !Event Player.isInMenu; + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Money[1] != 0); + Call Subroutine(Refund); + Else; + Small Message(Local Player, Custom String("You don't have anything to refund!")); + End; + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[13] += 1; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 2); + If(Event Player.Money[0] >= 900); + Event Player.Money[0] -= 900; + Event Player.Money[1] += 900; + Event Player.Abilities[9] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[5] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[1] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[14] += 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[10] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[6] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[2] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[15] += 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[11] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[7] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[3] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Global.AutoRepair != 5); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Global.AutoRepair += 1; + Event Player.Abilities[16] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[12] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[8] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[4] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + End; + } +} + +rule("Refund Single Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Secondary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[13] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[13] -= 1; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 0); + Event Player.Money[0] += 900; + Event Player.Money[1] -= 900; + Event Player.Abilities[9] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[5] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[1] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[14] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[14] -= 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[10] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[6] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[2] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[15] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[15] -= 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[11] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[7] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[3] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[16] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Global.AutoRepair -= 1; + Event Player.Abilities[16] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[12] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[8] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[4] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + End; + } +} + +rule("Create Player HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Custom String("{0}{1}", + Event Player, Event Player.isInMenu ? Custom String("(In Shop)") : Custom String("")), Custom String("{0}{1}", Is Alive( + Event Player) ? Custom String("{0} HP", Round To Integer(Health(Event Player), Up)) : Custom String("Dead"), Custom String( + ", {0}$", Event Player.Money)), Left, Local Player == Event Player ? -1 : Slot Of(Event Player), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), + Visible To Sort Order String and Color, Default Visibility); + Create HUD Text(Event Player.Abilities[13] || Global.DamageDone ? Event Player : Null, Null, Null, Custom String("+{0}% Damage", + Global.DamageDone + Event Player.Abilities[13] * 5), Left, 913, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[9] ? Event Player : Null, Null, Null, Custom String("Second Wind {0}", + Event Player.Abilities[9] == 1 ? Custom String("I") : Custom String("II")), Left, 908, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[5] ? Event Player : Null, Null, Null, Custom String("Charged {0}", + Event Player.Abilities[5] == 1 ? Custom String("I") : Custom String("II")), Left, 905, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[1] ? Event Player : Null, Null, Null, Custom String("Headhunter {0}", + Event Player.Abilities[1] == 1 ? Custom String("I") : Custom String("II")), Left, 901, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[14] || Global.MaxHealthDone ? Event Player : Null, Null, Null, Custom String("+{0}% Health", + Global.MaxHealthDone + Event Player.Abilities[14] * 5), Left, 914, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[10] ? Event Player : Null, Null, Null, Custom String("Binding Heal {0}", + Event Player.Abilities[10] == 1 ? Custom String("I") : Custom String("II")), Left, 909, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[6] ? Event Player : Null, Null, Null, Custom String("Haste {0}", + Event Player.Abilities[6] == 1 ? Custom String("I") : Custom String("II")), Left, 906, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[2] ? Event Player : Null, Null, Null, Custom String("Ambush {0}", + Event Player.Abilities[2] == 1 ? Custom String("I") : Custom String("II")), Left, 902, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[15] ? Event Player : Null, Null, Null, Custom String("+{0}% Healing", + Event Player.Abilities[15] * 5), Left, 915, Color(White), Color(White), Color(Turquoise), Visible To and String, + Default Visibility); + Create HUD Text(Event Player.Abilities[11] ? Event Player : Null, Null, Null, Custom String("Resilience {0}", + Event Player.Abilities[11] == 1 ? Custom String("I") : Custom String("II")), Left, 910, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[7] ? Event Player : Null, Null, Null, Custom String("Heavy Impact {0}", + Event Player.Abilities[7] == 1 ? Custom String("I") : Custom String("II")), Left, 907, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[3] ? Event Player : Null, Null, Null, Custom String("Quick Fix {0}", + Event Player.Abilities[3] == 1 ? Custom String("I") : Custom String("II")), Left, 903, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Global.AutoRepair ? Event Player : Null, Null, Null, Custom String("{0} total Auto-Repair/5s", + Global.AutoRepair * (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5)), Left, 916, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[2][0], Event Player.HeroTalentText[2][1]), Top, 902, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("Hero Talent 2"), Left, 912, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[1][0], Event Player.HeroTalentText[1][1]), Top, 901, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("Hero Talent 1"), Left, 911, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[4] ? Event Player : Null, Null, Null, Custom String("Heavyweight {0}", + Event Player.Abilities[4] == 1 ? Custom String("I") : Custom String("II")), Left, 904, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + } +} + +rule("Rein Pin detect") +{ + event + { + Player Dealt Knockback; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 1); + Has Status(Victim, Stunned) == True; + } + + actions + { + Event Player.ReinPin = Victim; + Wait(1, Ignore Condition); + Event Player.ReinPin = Null; + } +} + +rule("Boss Rotation") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.activeBoss == True; + } + + actions + { + If(Global.bossRotation == 0 || Global.bossRotation == 3); + Global.bossRotation = 1; + Global.lastBoss[1] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 1); + Global.bossRotation = 2; + Global.lastBoss[2] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 2); + Global.bossRotation = 3; + Global.lastBoss[3] = Hero Of(Global.activeBoss); + End; + } +} + +rule("15 minutes hud") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 10; + } + + actions + { + Create HUD Text(All Players(Team 1), Global.activeBoss ? Custom String("Boss: {0}, HP: {1}/{2}", Hero Of(Global.activeBoss), + Health(Global.activeBoss), Max Health(Global.activeBoss)) : Custom String(""), Null, Null, Top, 900, Color(Red), Color(White), + Color(White), Visible To and String, Default Visibility); + } +} + +rule("debug") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + (Is Button Held(Event Player, Button(Primary Fire)) && Is Button Held(Event Player, Button(Crouch))) == True; + } + + actions + { + Global.TimeSec = 59; + } +} + +disabled rule("debug") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + } + + actions + { + Create HUD Text(Local Player, Custom String("{0}", Position Of(Local Player)), Null, Null, Left, 0, Color(Yellow), Color(White), + Color(White), Visible To and String, Default Visibility); + Set Status(Event Player, Null, Invincible, 9999); + Set Status(Event Player, Null, Phased Out, 9999); + } +} + +rule("ending 1 part 1") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + } + + actions + { + Big Message(All Players(Team 1), Custom String("Exfiltration available! (optional - ends the mode)")); + Create In-World Text(All Players(Team 1), Custom String( + "Exfiltration available! Gather here!\n{0}/{1} Players ready to exfiltrate!", Count Of(Filtered Array(All Players(Team 1), + Distance Between(Vector(186, 11, -46.500), Current Array Element) <= 9)), Count Of(All Players(Team 1))), Vector(186, 15, + -46.500), 1.200, Do Not Clip, Visible To and String, Color(Green), Default Visibility); + } +} + +rule("ending 1 part 2") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + Distance Between(Vector(186, 11, -46.500), All Players(Team 1)) <= 9; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GG! YOU DID IT!")); + Destroy All Dummy Bots; + Disable Movement Collision With Environment(All Players(Team 1), True); + Start Accelerating(All Players(Team 1), Up, 100, 5, To World, Direction Rate and Max Speed); + Wait(5, Ignore Condition); + Declare Team Victory(Team 1); + } +} + +rule("Team 1 (Ability): Second Wind save life") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[9] == True; + Event Player.secondWindActive == True; + Health(Event Player) == 1; + } + + actions + { + Small Message(All Players(All Teams), Custom String("{0} received a second wind!", Event Player)); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Green), Event Player, 1); + Clear Status(Event Player, Unkillable); + Set Player Health(Event Player, Max Health(Event Player)); + Event Player.lastSecondWind = 30; + Event Player.secondWindActive = 0; + } +} + +rule("Team 1 (Ability): Second Wind after buying") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[9] == True; + Event Player.secondWindActive == False; + Event Player.lastSecondWind == 0; + } + + actions + { + If(Random Integer(1, 100) > Event Player.Abilities[9] * 30); + Wait(30, Ignore Condition); + Loop; + End; + Set Status(Event Player, Null, Unkillable, 9999); + Event Player.secondWindActive = 1; + } +} + +rule("Team 1 (Ability): Second Wind counter") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Player.lastSecondWind > 0; + } + + actions + { + Wait(1, Ignore Condition); + Event Player.lastSecondWind -= 1; + Loop If Condition Is True; + } +} \ No newline at end of file diff --git a/defendTheCastleExtended/old_versions/c123.ow b/defendTheCastleExtended/old_versions/c123.ow new file mode 100644 index 0000000..d5f2e17 --- /dev/null +++ b/defendTheCastleExtended/old_versions/c123.ow @@ -0,0 +1,9317 @@ +settings +{ + main + { + Description: "Defend The Castle Extended v0.6.c123\nby ShuriZma#2349\nJ1K6F (Code Version: c123)\nOriginal mode by HuKuTa94#2589\n\nDefend the gate, kill enemies and don't allow them to damage the gate!\n\nSpecial Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents\n& Josbird for teaching me about Menus!\n\nFind this mode on: workshop.codes/defend-the-castle\nFind the Original Mode on: workshop.codes/BQEGS\nTell me what you think on Discord: discord.shurizma.de\n\nPS: SHINGEN PLS COME BACK" + Mode Name: "Defend The Castle Extended" + } + + lobby + { + Max Spectators: 0 + Max Team 1 Players: 4 + Max Team 2 Players: 0 + Return To Lobby: Never + Swap Teams After Match: No + } + + modes + { + Escort + { + enabled maps + { + Havana + } + } + + Team Deathmatch + { + enabled maps + { + } + } + + General + { + Game Mode Start: Immediately + Spawn Health Packs: Disabled + } + } + + workshop + { + Ana can nano herself even if there are other players only if no player targeted: On + Story Heroes: Off + } + + extensions + { + Beam Effects + Kinetic Explosion Effects + Explosion Sounds + Play More Effects + Spawn More Dummy Bots + } +} + +variables +{ + global: + 0: GatePosition + 1: ZenSpawnPositions + 2: SpawnPositionMaxId + 3: LoopIterator1 + 4: BigBossSpawnPositions + 5: PlayerSpawnPositions + 6: GateHealthChase + 7: GateHealth + 8: GateMaxHealth + 9: GateProgressBarColorCurrent + 10: GateProgressBarColorComponent + 11: GateHealthEvent + 12: BastionTargetPositions + 13: SniperPositions + 14: BallSpawnPositions + 15: ZenRespawnTime + 16: TimeMin + 17: TimeSec + 18: DefaultCurrentBot + 19: DefaultHeroBotsPool + 20: DefaultHeroBotsPoolCurrentId + 21: IsDebug + 22: BotOrisaParent + 23: IsStoryHeroes + 24: BotOrisaChild + 25: GateRepairPosition + 26: BotOrisaTargetPosition + 27: BotEchoRespawnPosition + 28: BotEchoTeleportPositions + 29: UpgradeGateMaxHealthValue + 30: UpgradeGateMaxHealthHudId + 31: UpgradePlayerMaxHealthValue + 32: UpgradePlayerMaxHealthHudId + 33: UpgradeCriticalDamageValue + 34: UpgradeCriticalDamageHudId + 35: UpgradeMaxAmmoValue + 36: UpgradeMaxAmmoHudId + 37: UpgradeMaxAmmoMaxValue + 38: UpgradePlayerMaxHealthMaxValue + 39: UpgradeCriticalDamageMaxValue + 40: UpgradeGateMaxHealthMaxValue + 41: DamageDone + 42: IsDebugAINavigation + 43: GameLogicCountOfUniqueHeroes + 44: IsNewWaveGameLogicProcessing + 45: AutoRepair + 46: UpgradePerkSharpshooterValue + 47: Perk + 48: MaxHealthDone + 49: StartMoney + 50: Time5Min + 51: SelfNanoWorkshopSetting + 52: ShopCamPos + 53: ShopBasePos + 54: ShopPosAngle + 55: activeBoss + 56: bossTrigger + 57: bossRotation + 58: lastBoss + 59: Time10Min + 60: MoneyMult + 61: challengeCount + 62: UpgradeBossHealthValue + 112: AllPos + 113: AllDir + 114: firstpos + 115: secondpos + 116: firstpoint2 + 117: secondpoint2 + 118: second + 119: z + 120: Wall_ID + 121: showwalls + 122: is_Grounded + 123: g_beamType + 124: x + 125: NodePositions + 126: NodeConnections + 127: DistanceMatrix + + player: + 0: BotSeePlayer + 1: BotDoesUniqueBehaviour + 2: BotEffects + 3: BotRayCastHitPosition + 4: BotEventPosition + 5: CurrentHero + 6: IsDead + 7: IsRespawning + 8: BotBastionArtilleryDidShotsCount + 9: BotCounter + 10: HasBadStatus + 11: EventHealth + 12: HealOverTimeId + 13: BotIsOrisaChild + 14: BotEchoCapturedPlayer + 15: BotPlayersInRadius + 16: BotLoopIterator2 + 17: BotWidowShotTime + 18: BotWidowTeleportTime + 19: IsNanoed + 20: AbilityHUD + 21: Lucio_Dash_Active + 22: Lucio_Dash_Icon + 23: AnaEntityID + 24: Abilities + 25: Money + 26: HeroTalentText + 27: DamageDealt + 28: PlayerHealth + 29: AbilityCountdown + 30: HP_Pool + 31: Effects_ + 32: Ability_Projectile1 + 33: Ability_End + 34: Storm_Projectile + 35: Storm_EndPoint + 36: Storm_Effects + 37: Feared_until + 38: Modification_Damage + 39: Ability_Projectile2 + 40: Ability_Position + 41: Chain_Reaction_On + 42: Chain_Reaction_Immune + 43: Ability_Active + 44: Ability_Resource + 45: secondWindActive + 46: isInMenu + 47: ReinPin + 48: PlayerFacing + 49: isBoss + 50: Gen_Direction + 51: Gen_Available + 52: Ability_Player + 53: Ability_Countdown + 54: lastSecondWind + 55: deathPosition + 105: filterpos + 106: lastsavedpos + 107: closestbodypos + 108: fullbodypos + 109: prevpos_intersection + 110: active_wall + 111: closestwall + 112: x + 113: intersection_length + 114: thickness + 115: BotCancelPathFinding + 116: BotLoopIterator1 + 117: BotTempArray + 118: BotTargetPlayer + 119: BotTargetPosition + 120: BotClosestNodeIdToTarget + 121: BotClosestNodeIdToBot + 122: BotPrevNodeId + 123: BotNextNodeId + 124: BotNextNodePosition + 125: BotCurrentDistanceToTarget + 126: BotShortestDistanceToTarget + 127: BotIsPathFinding +} + +subroutines +{ + 0: BotBastionArtilleryDamage + 1: BotBastionFlameGunDamage + 2: BotBastionRespawn + 3: GateProgressBarColor + 4: BotZenyattaRespawn + 5: BotWidowRespawn + 6: BotBallRespawn + 7: GameLogicAddNextHeroInGame + 8: BotOrisaRespawn + 9: BotLandingFromSky + 10: BotEchoRespawn + 11: BotEchoDetachPlayer + 12: BotEchoFlyToPlayer + 13: BotEchoFlyToPortal + 14: GameLogicSetBotProperties + 15: DisablePlayer + 16: BotApearFromUnderground + 17: BotReinRespawn + 18: PlayerInit + 19: BotInit + 20: PlayerRespawn + 21: BotRespawn + 22: BotWidowBadStatus + 23: GameLogicWave0 + 24: Refund + 25: EnablePlayer + 26: GateRepair + 124: BotStartPathFinding + 125: BotGetClosestNodeIdToTarget + 126: BotGetNextNodeIdAndPosition + 127: BotResetPathFinding +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("MAP: HAVANA") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Havana); + } + + actions + { + Global.NodePositions = Array(Vector(147.588, 6.425, -46.749), Vector(136.181, 6.425, -57.159), Vector(130.189, 6.425, -63.781), + Vector(123.305, 6.425, -57.983), Vector(125.678, 6.504, -46.633), Vector(114.485, 7.471, -46.699), Vector(138.743, 6.425, + -32.974), Vector(126.498, 6.425, -39.920), Vector(124.572, 10.434, -34.300), Vector(138.605, 5.359, -18.647), Vector(119.009, + 2.331, -31.024), Vector(121.138, 5.228, -19.933), Vector(126.722, 6.425, -29.505), Vector(102.762, 3.157, -33.609), Vector( + 76.030, 7.418, -74.087), Vector(83.720, 9.425, -33.744), Vector(97.439, 7.238, -42.379), Vector(86.252, 12.416, -47.261), + Vector(65.178, 11.425, -73.187), Vector(97.466, 7.269, -50.596), Vector(113.039, 7.424, -37.337), Vector(106.179, 7.450, + -46.143), Vector(90.086, 7.411, -44.653), Vector(78.752, 7.418, -62.140), Vector(82.124, 7.428, -44.229), Vector(90.675, 7.231, + -51.234), Vector(85.717, 4.692, -63.446), Vector(90.830, 4.330, -70.697), Vector(102.425, 2.387, -72.817), Vector(81.443, + 4.425, -81.648), Vector(70.743, 6.418, -81.495), Vector(69.738, 6.419, -96.344), Vector(127.586, 12.643, -63.344), Vector( + 118.911, 13.468, -58.008), Vector(102.885, 1.092, -56.579), Vector(100.009, 2.967, -67.139), Vector(106.703, 0.465, -44.628), + Vector(81.695, 7.418, -52.140), Vector(126.979, 12.393, -55.079), Vector(153.720, 18.578, -21.745), Vector(155.301, 18.619, + -17.595), Vector(133.043, 10.425, -26.625), Vector(114.646, 7.278, -57.336), Vector(95.160, 3.688, -81.194), Vector(78.456, + 5.418, -93.581), Vector(75.455, 5.418, -101.492), Vector(148.071, 9.432, -32.123), Vector(146.706, 9.425, -27.858), Vector( + 144.273, 9.445, -63.119), Vector(144.278, 9.454, -58.447)); + Global.NodeConnections = Array(Array(1, 6, 4, 7), Array(2, 1, 4, 6, 7, 0, 49), Array(1, 3), Array(2, 4, 42), Array(3, 1, 5, 7, 6, + 1, 0), Array(4, 7, 20, 21, 19, 16, 42), Array(7, 1, 4, 1, 9, 12, 0, 46), Array(4, 5, 6, 1, 1, 12, 0), Array(7, 41), Array(6, + 11), Array(11, 13), Array(9, 10, 13), Array(6, 7, 10), Array(10, 16, 36), Array(18, 23, 30), Array(17, 24), Array(13, 19, 22, + 21, 25, 5), Array(15, 22, 25, 23), Array(14), Array(16, 21, 22, 26, 27, 35, 25, 5), Array(5, 13, 10), Array(19, 16, 5, 13, 22, + 34), Array(16, 19, 21, 24, 25), Array(14, 25, 26, 37), Array(22, 15, 37), Array(23, 22, 19, 16, 26, 27, 35, 37), Array(25, 19, + 27, 35, 29), Array(19, 26, 25, 29, 35, 43), Array(35, 34, 43), Array(27, 26, 30, 43, 44), Array(29, 14, 31), Array(30, 29, 45), + Array(33, 38, 1, 48), Array(32, 38, 42), Array(35, 36, 28), Array(28, 19, 25, 27, 26, 34), Array(13, 34), Array(25, 23, 24), + Array(5, 4, 1, 6, 1, 32, 33, 0), Array(40), Array(39), Array(6, 8, 47, 46), Array(3, 5, 34), Array(28, 27, 29, 44), Array(29, + 43, 45), Array(44, 31), Array(6, 47), Array(46, 41), Array(49, 32), Array(1, 0, 6, 48)); + Global.DistanceMatrix = Array(Array(0, 1, 2, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, + 4, 5, 4, 4, 5, 5, 5, 0, 0, 4, 3, 5, 6, 7, 2, 3, 3, 2), Array(1, 0, 1, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, + 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 3, 4, 4, 4, 5, 5, 4, 0, 0, 4, 3, 5, 6, 7, 2, 3, 2, 1), Array(2, 1, 0, 1, 2, 3, 2, 2, 6, 3, 4, 4, + 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 4, 6, 7, 8, 4, 5, 3, 4, 4, 6, 5, 0, 0, 5, 2, 5, 6, 7, 3, 4, 3, 2), Array(2, 2, + 1, 0, 1, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, 5, 6, 2, 3, 3, 5, 6, 0, 0, 5, 1, 4, + 5, 6, 3, 4, 4, 3), Array(1, 1, 2, 1, 0, 1, 1, 1, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, + 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, 2, 3, 3, 2), Array(2, 2, 3, 2, 1, 0, 2, 1, 6, 3, 2, 3, 2, 2, 4, 4, 1, 5, 5, 1, 1, 1, 2, 3, + 3, 2, 2, 2, 3, 3, 4, 5, 5, 6, 2, 2, 3, 3, 6, 0, 0, 5, 1, 3, 4, 5, 3, 4, 4, 3), Array(1, 1, 2, 2, 1, 2, 0, 1, 4, 1, 2, 2, 1, 3, + 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 4, 5, 4, 4, 4, 5, 5, 0, 0, 3, 3, 5, 6, 7, 1, 2, 3, 2), Array(1, 1, 2, 2, + 1, 1, 1, 0, 5, 2, 2, 3, 1, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, + 2, 3, 3, 2), Array(2, 2, 3, 3, 2, 2, 2, 1, 0, 3, 3, 4, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, + 5, 5, 6, 0, 0, 1, 3, 5, 6, 7, 2, 2, 4, 3), Array(2, 2, 3, 3, 2, 3, 1, 2, 5, 0, 2, 1, 2, 2, 6, 6, 3, 7, 7, 4, 4, 4, 4, 5, 5, 4, + 5, 5, 5, 6, 7, 8, 5, 6, 4, 5, 3, 5, 6, 0, 0, 4, 4, 6, 7, 8, 2, 3, 4, 3), Array(4, 4, 5, 5, 4, 3, 3, 4, 7, 2, 0, 1, 4, 1, 5, 5, + 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 7, 8, 3, 4, 2, 4, 8, 0, 0, 6, 4, 5, 6, 7, 4, 5, 6, 5), Array(3, 3, 4, 4, 3, 3, + 2, 3, 6, 1, 1, 0, 3, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 6, 7, 3, 4, 2, 4, 7, 0, 0, 5, 4, 5, 6, 7, 3, 4, + 5, 4), Array(2, 2, 3, 3, 2, 2, 1, 1, 5, 2, 1, 2, 0, 2, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, 3, 5, + 6, 0, 0, 4, 3, 5, 6, 7, 2, 3, 4, 3), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 3, 1, 2, 4, 0, 4, 4, 1, 5, 5, 2, 3, 2, 2, 3, 3, 2, 3, 3, + 3, 4, 5, 6, 7, 8, 2, 3, 1, 3, 8, 0, 0, 7, 3, 4, 5, 6, 5, 6, 6, 5), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 5, 6, 6, 4, 0, 4, 3, 5, + 1, 3, 5, 4, 3, 1, 3, 2, 2, 3, 4, 2, 1, 2, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 3, 3, 3, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, + 5, 10, 7, 5, 6, 6, 4, 3, 0, 3, 1, 4, 3, 5, 3, 2, 2, 1, 2, 3, 3, 4, 4, 4, 5, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 4, 5, 6, 7, 8, + 8, 7), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 3, 3, 0, 4, 4, 1, 2, 1, 1, 2, 2, 1, 2, 2, 3, 3, 4, 5, 6, 7, 2, 2, 2, 2, + 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 1, 2, 0, 3, 2, 4, 2, 1, 1, 2, 1, 2, 2, + 3, 3, 3, 4, 8, 9, 3, 2, 4, 2, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 6, 7, 7, 5, 1, 5, 4, 6, + 0, 4, 6, 5, 4, 2, 4, 3, 3, 4, 5, 3, 2, 3, 10, 11, 5, 4, 6, 3, 11, 0, 0, 10, 6, 4, 4, 4, 8, 9, 9, 8), Array(3, 3, 4, 3, 2, 1, 3, + 2, 7, 4, 3, 4, 3, 2, 3, 3, 1, 4, 4, 0, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 3, 4, 6, 7, 2, 1, 3, 2, 7, 0, 0, 6, 2, 2, 3, 4, 4, 5, 5, + 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 3, 1, 2, 3, 1, 5, 5, 2, 6, 6, 2, 0, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 6, 7, 3, 3, 2, 4, 7, + 0, 0, 6, 2, 4, 5, 6, 4, 5, 5, 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 4, 3, 1, 4, 5, 1, 2, 0, 1, 3, 2, 2, 2, 2, 2, + 3, 4, 5, 6, 7, 1, 2, 2, 3, 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 3, 2, 1, 3, 4, + 1, 3, 1, 0, 2, 1, 1, 2, 2, 3, 3, 4, 5, 7, 8, 2, 2, 3, 2, 8, 0, 0, 7, 3, 3, 4, 5, 5, 6, 6, 5), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, + 6, 4, 5, 5, 3, 1, 3, 2, 4, 2, 2, 4, 3, 2, 0, 2, 1, 1, 2, 3, 2, 2, 3, 8, 9, 3, 2, 4, 1, 9, 0, 0, 8, 4, 3, 3, 4, 6, 7, 7, 6), + Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 3, 1, 2, 2, 4, 2, 4, 2, 1, 2, 0, 2, 3, 3, 4, 4, 4, 5, 8, 9, 3, 3, 4, 1, 9, 0, + 0, 8, 4, 4, 5, 6, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 2, 3, 1, 4, 3, 1, 3, 2, 1, 1, 2, 0, 1, 1, 2, 2, + 3, 4, 7, 8, 2, 1, 3, 1, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, + 3, 2, 2, 2, 3, 1, 0, 1, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 2, 2, 3, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, + 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 0, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 1, 2, 3, 5, 6, 6, 5), Array( + 5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 4, 5, 3, 6, 5, 2, 4, 3, 3, 3, 4, 2, 2, 2, 0, 2, 3, 4, 8, 9, 1, 1, 2, 3, 9, 0, 0, 8, + 4, 1, 2, 3, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 2, 5, 3, 6, 3, 2, 4, 3, 3, 3, 4, 2, 1, 1, 2, 0, 1, 2, + 8, 9, 3, 2, 4, 3, 9, 0, 0, 8, 4, 1, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 1, 5, 4, 6, 2, 3, 5, 4, + 4, 2, 4, 3, 2, 2, 3, 1, 0, 1, 9, 10, 4, 3, 5, 3, 10, 0, 0, 9, 5, 2, 2, 2, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, + 7, 6, 5, 2, 6, 4, 7, 3, 3, 5, 4, 4, 3, 5, 3, 2, 2, 3, 1, 1, 0, 9, 10, 4, 3, 5, 4, 10, 0, 0, 9, 5, 2, 2, 1, 7, 8, 8, 7), Array( + 2, 1, 2, 3, 2, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 4, 5, 6, 7, 0, 1, 3, 4, 4, 5, 1, 0, 0, 5, + 2, 5, 6, 7, 3, 4, 1, 2), Array(2, 2, 3, 2, 2, 2, 2, 3, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, + 1, 0, 2, 3, 3, 5, 1, 0, 0, 5, 1, 4, 5, 6, 3, 4, 2, 3), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 5, 3, 4, 5, 2, 4, 5, 3, 6, 5, 2, 4, 3, + 3, 3, 4, 2, 2, 2, 1, 3, 4, 5, 8, 9, 0, 1, 1, 3, 9, 0, 0, 8, 4, 2, 3, 4, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, + 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 1, 1, 2, 3, 4, 7, 8, 1, 0, 2, 2, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(5, 5, + 6, 5, 4, 3, 5, 4, 9, 4, 2, 3, 5, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 8, 9, 1, 2, 0, 4, 9, 0, 0, 8, 4, 3, + 4, 5, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 2, 2, 3, 3, 2, 4, 3, 2, 1, 1, 1, 2, 2, 3, 3, 3, 4, 8, 9, + 3, 2, 4, 0, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(1, 1, 2, 2, 1, 1, 1, 2, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, + 4, 3, 3, 3, 4, 4, 5, 6, 1, 1, 3, 3, 4, 4, 0, 0, 0, 4, 2, 4, 5, 6, 2, 3, 2, 2), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(2, 2, 3, 3, 2, 3, 1, 2, 1, 2, 3, 3, 2, + 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 0, 4, 6, 7, 8, 1, 1, 4, 3), Array(3, 3, 2, + 1, 2, 1, 3, 2, 7, 4, 3, 4, 3, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 6, 7, 1, 2, 2, 4, 7, 0, 0, 6, 0, 3, 4, + 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 3, 5, 3, 6, 4, 2, 4, 3, 3, 3, 4, 2, 2, 1, 1, 1, 2, 3, 8, 9, 2, + 2, 3, 3, 9, 0, 0, 8, 4, 0, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 3, 6, 4, 7, 4, 3, 5, 4, 4, 4, 5, + 3, 2, 2, 2, 1, 2, 2, 9, 10, 3, 3, 4, 4, 10, 0, 0, 9, 5, 1, 0, 1, 7, 8, 8, 7), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 7, 8, 7, 6, + 3, 7, 5, 8, 4, 4, 6, 5, 5, 4, 6, 4, 3, 3, 3, 2, 2, 1, 10, 11, 4, 4, 5, 5, 11, 0, 0, 10, 6, 2, 1, 0, 8, 9, 9, 8), Array(2, 2, 3, + 3, 2, 3, 1, 2, 3, 2, 3, 3, 2, 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 2, 4, 6, 7, + 8, 0, 1, 4, 3), Array(3, 3, 4, 4, 3, 4, 2, 3, 2, 3, 4, 4, 3, 5, 8, 8, 5, 9, 9, 5, 5, 5, 6, 7, 7, 6, 6, 6, 7, 7, 8, 9, 6, 7, 6, + 6, 6, 7, 7, 0, 0, 1, 5, 7, 8, 9, 1, 0, 5, 4), Array(2, 2, 3, 4, 3, 3, 2, 3, 6, 3, 4, 4, 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, + 5, 5, 5, 5, 6, 7, 8, 1, 2, 4, 5, 5, 6, 2, 0, 0, 5, 3, 6, 7, 8, 3, 4, 0, 1), Array(1, 1, 2, 3, 2, 3, 1, 2, 5, 2, 3, 3, 2, 4, 7, + 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 2, 3, 5, 5, 5, 6, 3, 0, 0, 4, 4, 6, 7, 8, 2, 3, 1)); + } +} + +rule("SUBROUTINE: BOT - RESET PATH FINDING") +{ + event + { + Subroutine; + BotResetPathFinding; + } + + actions + { + Event Player.BotTargetPlayer = -1; + Event Player.BotTargetPosition = -1; + Event Player.BotPrevNodeId = -1; + Event Player.BotClosestNodeIdToTarget = -1; + Event Player.BotNextNodeId = -1; + Event Player.BotNextNodePosition = -1; + Event Player.BotIsPathFinding = False; + Event Player.BotCancelPathFinding = False; + Stop Throttle In Direction(Event Player); + disabled Stop Facing(Event Player); + } +} + +rule("SUBROUTINE: BOT - START PATH FINDING") +{ + event + { + Subroutine; + BotStartPathFinding; + } + + actions + { + disabled Abort If(Event Player.BotIsPathFinding == True); + Call Subroutine(BotGetNextNodeIdAndPosition); + disabled Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Event Player.BotIsPathFinding = True; + } +} + +rule("SUBROUTINE: BOT - GET NEXT NODE ID AND POSITION") +{ + event + { + Subroutine; + BotGetNextNodeIdAndPosition; + } + + actions + { + "BOT JUST START FOLLOW PATH OR LOST NEXT NODE" + If(Event Player.BotPrevNodeId == -1); + Event Player.BotClosestNodeIdToBot = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array(Global.NodePositions, + Is In Line of Sight(Position Of(Event Player) + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS) == True), + Distance Between(Position Of(Event Player), Current Array Element))[0]); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + "NEXT NODE IS TARGET (DISTANCE TO TARGET NODE = 1)" + If(Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1); + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToTarget; + "CHECK CONNECTIONS OF REACHED NODE" + Else; + Event Player.BotShortestDistanceToTarget = 999; + Event Player.BotCurrentDistanceToTarget = Event Player.BotShortestDistanceToTarget; + Event Player.BotTempArray = Global.NodeConnections[Event Player.BotClosestNodeIdToBot]; + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotTempArray), 1); + Event Player.BotCurrentDistanceToTarget = Global.DistanceMatrix[Event Player.BotTempArray[Event Player.BotLoopIterator1]][Event Player.BotClosestNodeIdToTarget]; + If(Event Player.BotCurrentDistanceToTarget < Event Player.BotShortestDistanceToTarget); + Event Player.BotShortestDistanceToTarget = Event Player.BotCurrentDistanceToTarget; + Event Player.BotNextNodeId = Event Player.BotTempArray[Event Player.BotLoopIterator1]; + End; + End; + End; + "NEXT NODE IS HIGHER THAN BOT AND BOT DIDN'T REACH CLOSEST NODE" + If(Y Component Of(Position Of(Event Player)) - Y Component Of(Global.NodePositions[Event Player.BotNextNodeId]) + < -3 && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + "BOT CAN SEE TARGET POSITION AND NEXT NODE IS TARGET" + Else If( + Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1 && Is In Line of Sight( + Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotTargetPosition + Vector(0, 2, 0), Barriers Do Not Block LOS)); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Abort; + "BOT CAN'T SEE NEXT NODE AND PREV NODE != REACHED NODE" + Else If(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), + Global.NodePositions[Event Player.BotNextNodeId] + Vector(0, 2, 0), Barriers Do Not Block LOS) + == False && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + End; + Event Player.BotNextNodePosition = Global.NodePositions[Event Player.BotNextNodeId]; + } +} + +rule("SUBROUTINE: BOT - GET CLOSEST NODE ID AND POSITION TO TARGET") +{ + event + { + Subroutine; + BotGetClosestNodeIdToTarget; + } + + actions + { + Event Player.BotTargetPosition = Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Event Player.BotTargetPosition; + Event Player.BotClosestNodeIdToTarget = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array( + Global.NodePositions, Is In Line of Sight(Event Player.BotTargetPosition + Vector(0, 2, 0), Current Array Element, + Barriers Do Not Block LOS) == True), Distance Between(Event Player.BotTargetPosition, Current Array Element))[0]); + } +} + +rule("BOT: PATH FINDING - START") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + (Event Player.BotTargetPosition != -1 || Event Player.BotTargetPlayer != -1) == True; + } + + actions + { + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - CANCEL") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotCancelPathFinding == True; + } + + actions + { + Start Rule(BotResetPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - LOST THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + (Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotNextNodePosition + Vector(0, 2.500, 0), + Barriers Do Not Block LOS) == False && Speed Of In Direction(Event Player, Throttle Of(Event Player)) < 2) == True; + } + + actions + { + Wait(0.500, Abort When False); + "RESET PREV NODE ID TO INFORM BOT THAT IT LOST NEXT NODE" + Event Player.BotPrevNodeId = -1; + "TRY FIND NEW NEXT NODE" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodeId), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +rule("BOT: PATH FINDING - REACHED THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotClosestNodeIdToTarget >= 0; + (Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotNextNodePosition), 0, Z Component Of(Event Player.BotNextNodePosition))) < 0.850) == True; + } + + actions + { + Event Player.BotPrevNodeId = Event Player.BotNextNodeId; + Event Player.BotClosestNodeIdToBot = Event Player.BotNextNodeId; + "BOT'S TARGET IS PLAYER" + If(Event Player.BotTargetPlayer != -1); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + Event Player.BotCurrentDistanceToTarget = Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of( + Position Of(Event Player))), Vector(X Component Of(Event Player.BotTargetPosition), 0, Z Component Of( + Event Player.BotTargetPosition))); + "BOT REACHED THE TARGET NODE OR TARGET POSITION" + If(Event Player.BotNextNodeId == Event Player.BotClosestNodeIdToTarget || Event Player.BotCurrentDistanceToTarget <= 0.850); + "BOT DIDN'T REACH TARGET POSITION" + If(Event Player.BotCurrentDistanceToTarget > 0.850); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Skip(6); + "BOT REACHED TARGET" + Else; + Call Subroutine(BotResetPathFinding); + Abort; + End; + End; + "CONTINUE FOLLOW PATH" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: GAME MODE INIT - WORKSHOP SETTINGS") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.IsDebug = False; + Global.IsDebugAINavigation = False; + Global.GateMaxHealth = Workshop Setting Integer(Custom String("Defend The Castle Extended"), Custom String("GATE MAX HEALTH"), 500, 100, 1000, + 0); + Global.MoneyMult = Workshop Setting Real(Custom String("Defend The Castle Extended"), Custom String("Money Multiplicator"), 1, 0.500, 2, 0); + Global.IsStoryHeroes = Workshop Setting Toggle(Custom String("Defend The Castle Extended"), Custom String("Story Heroes"), True, 0); + Global.SelfNanoWorkshopSetting = Workshop Setting Toggle(Custom String("Ana Self Nano"), Custom String( + "Ana can nano herself even if there are other players (only if no player targeted)"), False, 0); + } +} + +rule("GLOBAL: GAME MODE INIT - COMMON PROPERTIES") +{ + event + { + Ongoing - Global; + } + + actions + { + Create HUD Text(All Players(All Teams), Null, Null, Custom String( + "Defend The Castle Extended v0.6.c123 BY ShuriZma#2349\r\nOriginal mode by HUKUTA94#2589\r\nDiscord: discord.shurizma.de\r\n{0}", Custom String( + "Special Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents &\nJosbird for teaching me about Menus{0}", + Custom String(" \nPS: SHINGEN PLS COME BACK"))), Right, -1000, Null, Null, Color(White), Visible To, + Default Visibility); + Global.GateRepairPosition = Vector(153, 8, -46.500); + Global.GatePosition = Vector(148.800, 6, -46.400); + Global.BallSpawnPositions = Array(Vector(104, 7, -46), Vector(106, 2, -31)); + Global.SniperPositions = Array(Vector(154, 18, -22.600), Vector(86, 12, -46.600), Vector(80.880, 11.300, -71.600), Vector(98, 9, + -19)); + Global.ZenSpawnPositions = Array(Vector(79.500, 5, -100), Vector(90, 4, -88), Vector(65, 11, -70), Vector(85, 4, -68), Vector(96, + 2, -73), Vector(84, 7, -47), Vector(95, 9, -34), Vector(108, 1.700, -28), Vector(113, 7, -37), Vector(123, 5, -19), Vector(144, + 5, -19), Vector(123, 6, -39), Vector(123, 6, -61), Vector(129, 6, -30.500), Vector(135, 6, -63)); + Global.PlayerSpawnPositions = Array(Vector(153.300, 10, -63.800), Vector(153.300, 10, -61.700), Vector(153.300, 10, -31.700), + Vector(153.300, 10, -29.600)); + Global.BigBossSpawnPositions = Array(Vector(78, 4, -84), Vector(95, 4, -82)); + Global.BastionTargetPositions = Array(Vector(131, 12, -62), Vector(115, 7, -46), Objective Position(2), Vector(136, 10, -27)); + Global.SpawnPositionMaxId = 2; + Global.BotOrisaTargetPosition = Vector(104, 7, -46); + Global.BotEchoRespawnPosition = Vector(130, 23, -44); + Global.BotEchoTeleportPositions = Array(Vector(88, 23, -79), Vector(108, 18, -27)); + Global.DefaultHeroBotsPool = Array(Hero(Zenyatta), Hero(Widowmaker), Null, Hero(Bastion), Hero(Echo), Hero(Bastion)); + Global.ZenRespawnTime = 10; + Global.GameLogicCountOfUniqueHeroes = 5; + Global.lastBoss = Array(Null, Null, Null, Null); + Create Effect(All Players(Team 1), Ring, Color(Sky Blue), Vector(186, 11, -46.500), 9, Visible To Position and Radius); + } +} + +disabled rule("PLAYER: DEBUG - PRESS INTERACT") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Host Player == True; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + disabled Modify Player Score(Event Player, 10); + disabled Global.GateHealth -= 5; + disabled Start Rule(GateProgressBarColor, Restart Rule); + Global.TimeSec = 59; + Set Status(Event Player, Null, Phased Out, 9999); + disabled Set Ultimate Charge(Event Player, 100); + disabled Kill(Event Player, Null); + disabled Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: DEBUG - AI NAVIGATION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.IsDebugAINavigation == True; + } + + actions + { + For Global Variable(LoopIterator1, 0, Count Of(Global.NodePositions), 1); + Create Effect(All Players(All Teams), Sphere, Color(Red), Global.NodePositions[Global.LoopIterator1], 0.850, Visible To); + Create In-World Text(All Players(All Teams), Custom String("NODE {0}", Global.LoopIterator1), + Global.NodePositions[Global.LoopIterator1], 1.200, Clip Against Surfaces, Visible To, Color(White), Default Visibility); + End; + } +} + +disabled rule("GLOBAL: DEBUG - CREATE BOTS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + Create Dummy Bot(Hero(Bastion), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + Create Dummy Bot(Hero(Orisa), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +disabled rule("PLAYER: DEBUG - INFOS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + Host Player == Event Player; + Has Spawned(Event Player) == True; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Create HUD Text(Event Player, Custom String("POS {0}\r\nFACING {1}", Position Of(Event Player), Facing Direction Of(Event Player)), + Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + Create HUD Text(Event Player, Custom String("SERVER PERFORMANCE\r\nLOAD {0}%\r\nPEAK {1}%\r\nAVG {2}%", Server Load, + Server Load Peak, Server Load Average), Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create Progress Bar HUD Text(Event Player, 45, Custom String("45 / 100 KILLS"), Left, -99, Color(Blue), Color(White), + Visible To Values and Color, Default Visibility); + disabled Create HUD Text(Event Player, Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Null, Custom String( + "LEVEL 1 - 50 AMMO CLIP"), Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + "ЭФФЕКТ С ОФФСЕТОМ ОТ ПОЗИЦИИ ГЛАЗ" + disabled Create Beam Effect(All Players(All Teams), Bad Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + Facing Direction Of( + Event Player) * 3, Eye Position(Event Player) + Facing Direction Of(Event Player) * 50, Color(Purple), + Visible To Position and Radius); + } +} + +disabled rule("=== TEAM UPGRADES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: TEAM UPGRADES - INIT") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.UpgradeMaxAmmoMaxValue[0] = 250; + Global.UpgradeMaxAmmoMaxValue[1] = 500; + Global.UpgradeMaxAmmoMaxValue[2] = 1000; + Global.UpgradeCriticalDamageMaxValue[0] = 10; + Global.UpgradeCriticalDamageMaxValue[1] = 5; + Global.UpgradeCriticalDamageMaxValue[2] = 5; + Global.UpgradePlayerMaxHealthMaxValue[0] = 2500; + Global.UpgradePlayerMaxHealthMaxValue[1] = 5000; + Global.UpgradePlayerMaxHealthMaxValue[2] = 10000; + Global.UpgradeGateMaxHealthMaxValue[0] = Round To Integer(Global.GateMaxHealth + Global.GateMaxHealth * 0.500, Up); + Global.UpgradeGateMaxHealthMaxValue[1] = Global.UpgradeGateMaxHealthMaxValue[0] + Global.UpgradeGateMaxHealthMaxValue[0]; + Global.UpgradeGateMaxHealthMaxValue[2] = Global.UpgradeGateMaxHealthMaxValue[1] + Global.UpgradeGateMaxHealthMaxValue[1]; + Abort If(Global.IsDebug == False); + Global.UpgradeMaxAmmoMaxValue[0] = 1; + Global.UpgradeCriticalDamageMaxValue[0] = 1; + Global.UpgradePlayerMaxHealthMaxValue[0] = 1; + Global.UpgradeGateMaxHealthMaxValue[0] = 1; + Global.UpgradeMaxAmmoMaxValue[1] = 1; + Global.UpgradeCriticalDamageMaxValue[1] = 1; + Global.UpgradePlayerMaxHealthMaxValue[1] = 1; + Global.UpgradeGateMaxHealthMaxValue[1] = 1; + Global.UpgradeMaxAmmoMaxValue[2] = 1; + Global.UpgradeCriticalDamageMaxValue[2] = 1; + Global.UpgradePlayerMaxHealthMaxValue[2] = 1; + Global.UpgradeGateMaxHealthMaxValue[2] = 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GATE'S MAX HEALTH UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Global.GateMaxHealth = Global.UpgradeGateMaxHealthMaxValue[0]; + Global.GateHealth = Global.GateMaxHealth; + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Right, 1, Color( + Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X GATE REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[1]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X GATE REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X GATE REPAIR"), Right, 2, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X AUTO-REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[2]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[2] = Last Text ID; + Global.GateHealth = Global.GateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 3 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X AUTO-REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X AUTO-REPAIR"), Right, 3, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.UpgradeGateMaxHealthHudId[2] = Last Text ID; + Global.GateHealth = Global.GateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - PLAYER'S MAX HEALTH - DEALT HEALING") +{ + event + { + Player Received Healing; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + disabled Healer != Event Player; + Global.UpgradePlayerMaxHealthValue < Global.UpgradePlayerMaxHealthMaxValue[2]; + } + + actions + { + Global.UpgradePlayerMaxHealthValue += Event Healing; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +50%"), Right, 4, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("Up You Go: You respawn twice as fast"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[1]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.MaxHealthDone = 50; + All Players(Team 1).PlayerHealth = 100 + Global.MaxHealthDone + All Players(Team 1).Abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).PlayerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK UP YOU GO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("UP YOU GO UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String("Up You Go"), + Right, 5, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +100%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[2]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[2] = Last Text ID; + Set Respawn Max Time(All Players(Team 1), 5); + Heal(All Players(Team 1), Null, 9999); + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.Perk[2] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[17] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH 2 UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +100%"), Right, 6, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[2] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.MaxHealthDone = 150; + All Players(Team 1).PlayerHealth = 100 + Global.MaxHealthDone + All Players(Team 1).Abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).PlayerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Hero Of(Victim) == Hero(Widowmaker); + Global.UpgradeCriticalDamageValue < Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradeCriticalDamageValue += 1; + Small Message(All Players(Team 1), Custom String("CRITICAL DAMAGE CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - CRITICAL DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("CRITICAL DAMAGE 150% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "CRITICAL DAMAGE 150%"), Right, 7, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String( + "Sharpshooter: Deal 40% more damage to enemies that are further than 15 meters away"), Custom String("KILL ECHO {0}/{1}", + Global.UpgradePerkSharpshooterValue, Global.UpgradeCriticalDamageMaxValue[1]), Left, 14, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - UNLOCKED") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.500); + } +} + +rule("PLAYER: UPGRADE - PERK SHARPSHOOTER - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Echo); + Global.UpgradePerkSharpshooterValue < Global.UpgradeCriticalDamageMaxValue[1]; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradePerkSharpshooterValue += 1; + Small Message(All Players(Team 1), Custom String("SHARPSHOOTER CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - PERK SHARPSHOOTER - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("SHARPSHOOTER UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Sharpshooter"), Right, 8, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("-10% BOSS HEALTH"), Custom String("KILL Bosses {0}/{1}", + Global.UpgradeBossHealthValue, Global.UpgradeCriticalDamageMaxValue[2]), Left, 14, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[2] = Last Text ID; + Global.Perk[0] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[18] = Last Text ID; + Global.challengeCount += 1; + } +} + +disabled rule("PLAYER: UPGRADE - -10% BOSS HEALTH - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]; + Global.UpgradeBossHealthValue < Global.UpgradeCriticalDamageMaxValue[2]; + Victim.isBoss == 1; + } + + actions + { + Global.UpgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - -10% BOSS HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("-10% BOSS HEALTH UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "-10% BOSS HEALTH"), Right, 9, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[2] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - MAX AMMO - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Zenyatta); + Global.UpgradeMaxAmmoValue < Global.UpgradeMaxAmmoMaxValue[2]; + } + + actions + { + If(Event Player.isBoss == 1); + Global.UpgradeMaxAmmoValue += 10; + Else; + Global.UpgradeMaxAmmoValue += 1; + End; + } +} + +rule("GLOBAL: UPGRADE - MAX AMMO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("MAX AMMO 200% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "MAX AMMO 200%"), Right, 10, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("Bulletstorm: Your weapon can hold unlimited ammo"), + Custom String("KILL {2}: {0}/{1}", Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[1], Hero(Zenyatta)), Left, 15, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0) * 2); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1) * 2); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0)); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1)); + End; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK BULLETSTORM - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("BULLETSTORM UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Bulletstorm"), Right, 11, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("+50% DAMAGE"), Custom String("KILL {2}: {0}/{1}", + Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[2], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[2] = Last Text ID; + Global.Perk[1] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[19] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - +50% DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("+50% DAMAGE UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "+50% DAMAGE"), Right, 12, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[2] = Last Text ID; + Global.DamageDone = 50; + All Players(Team 1).DamageDealt = 100 + Global.DamageDone + All Players(Team 1).Abilities[13] * 5; + Set Damage Dealt(All Players(Team 1), All Players(Team 1).DamageDealt); + Global.challengeCount += 1; + } +} + +disabled rule("=== GAME PHASES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: ASEMBLING PHASE - MAKE CHALLENGES HUDS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Assembling Heroes == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Disable Inspector Recording; + Set Match Time(20); + End; + Create In-World Text(All Players(Team 1), Custom String(" {0}\r\nREPAIR\r\n {1}", Hero Icon String(Hero(Torbjörn)), + Ability Icon String(Hero(Bastion), Button(Secondary Fire))), Global.GatePosition + Vector(0, 1.400, 0), 1.200, Do Not Clip, + Visible To, Color(White), Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("TEAM CHALLENGES"), Left, 11, Color(White), Color(Blue), Color( + White), Visible To, Default Visibility); + "UPGRADE - GATE'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String( + "GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Custom String("REPAIR GATE {0}/{1} HP", + Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[0]), Left, 12, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 2, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - PLAYER'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +50%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[0]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 4, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - CRITICAL DAMAGE" + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("CRITICAL DAMAGE 150%"), Custom String( + "KILL WIDOW WITH HEADSHOT: {0}/{1}", Global.UpgradeCriticalDamageValue, Global.UpgradeCriticalDamageMaxValue[0]), Left, 14, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 6, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - MAX AMMO" + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("MAX AMMO 200%"), Custom String("KILL {2}: {0}/{1}", + Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[0], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Custom String("HOLD {0} - Reload to open the shop", Input Binding String(Button(Reload))), + Null, Null, Top, 1000, Color(Yellow), Color(White), Color(White), Visible To and String, Default Visibility); + } +} + +rule("GLOBAL: SETUP PHASE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Set Match Time(20); + End; + Set Objective Description(All Players(All Teams), Custom String("DEFEND GATE"), Visible To and String); + } +} + +rule("GLOBAL: GAME IN PROGRESS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + } + + actions + { + Set Match Time(3599); + Pause Match Time; + Disable Built-In Game Mode Scoring; + Disable Built-In Game Mode Announcer; + Disable Built-In Game Mode Completion; + Disable Game Mode HUD(All Players(All Teams)); + Disable Game Mode In-World UI(All Players(All Teams)); + Global.GateHealth = Global.GateMaxHealth; + Global.GateHealthChase = Global.GateHealth; + Global.GateProgressBarColorComponent = 255; + Global.GateProgressBarColorCurrent = Color(White); + Create Progress Bar HUD Text(All Players(Team 1), Global.GateHealthChase * 100 / Global.GateMaxHealth, Custom String( + "GATE {0}/{1}", Global.GateHealth, Global.GateMaxHealth), Top, 1, Global.GateProgressBarColorCurrent, Color(White), + Visible To Values and Color, Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("SURVIVED TIME: {0}:{1}", Global.TimeMin, + Global.TimeSec < 10 ? Custom String("0{0}", Global.TimeSec) : Global.TimeSec), Top, 2, Color(White), Color(White), Color( + White), Visible To and String, Default Visibility); + Start Rule(GameLogicWave0, Do Nothing); + } +} + +disabled rule("=== GAME - MAIN LOGIC ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: DEFEAT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.IsDebug == False; + Global.GateHealth <= 0; + } + + actions + { + Declare Team Victory(Team 2); + } +} + +rule("GLOBAL: TIMER - MAIN GAME LOOP") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + disabled Global.GateHealth > 0; + } + + actions + { + Wait(1, Ignore Condition); + Global.TimeSec += 1; + If(Global.TimeSec == 60); + Global.TimeSec = 0; + Global.TimeMin += 1; + Global.Time5Min = Round To Integer(Global.TimeMin / 5, Down); + Global.Time10Min = Round To Integer(Global.TimeMin / 10, Down); + Global.SpawnPositionMaxId += 1; + disabled Start Rule(GameLogicAddNextHeroInGame, Restart Rule); + Else If(Global.TimeSec == 30); + Global.SpawnPositionMaxId += 1; + End; + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GAME LOGIC - ADD NEXT HERO IN GAME") +{ + event + { + Subroutine; + GameLogicAddNextHeroInGame; + } + + actions + { + "REDUCE RESPAWN TIME FOR ZENS" + disabled Global.ZenRespawnTime -= 1.500; + disabled Global.ZenRespawnTime = Max(1, Global.ZenRespawnTime); + disabled Set Respawn Max Time(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Global.DefaultHeroBotsPool[0]), + Global.ZenRespawnTime); + "ALL HEROES WAS ADDED IN GAME" + Abort If(Global.DefaultHeroBotsPoolCurrentId == Count Of(Global.DefaultHeroBotsPool) - 1); + Global.DefaultHeroBotsPoolCurrentId += 1; + "ВРЕМЕННЫЙ КОСТЫЛЬ ЧТОБЫ ЭХО ЗАМЕНИЛА ХАМСТЕРА" + If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Hero(Echo)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Abort; + End; + "ABORT IF NEXT HERO IN ARRAY ORDER IS NULL" + Abort If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Null); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId], Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("SUBROUTINE: GAME LOGIC - SET BOT PROPERTIES") +{ + event + { + Subroutine; + GameLogicSetBotProperties; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + If(Global.TimeMin >= 10); + If(Filtered Array(Global.lastBoss, Current Array Element == Hero Of(Event Player)) == False); + If(Global.activeBoss == False); + If(Global.bossTrigger < Global.TimeMin); + Global.bossTrigger = Global.TimeMin; + Global.activeBoss = Event Player; + Event Player.isBoss = 1; + Big Message(All Players(Team 1), Custom String("BOSS SPAWNED - {0}", Hero Of(Event Player))); + End; + End; + End; + End; + "PROPERTIES BY DEFAULT" + Set Gravity(Event Player, 100); + Set Damage Dealt(Event Player, 100); + Set Respawn Max Time(Event Player, 10); + Start Scaling Player(Event Player, 1, False); + "INDIVIDUAL HERO'S PROPERTIES" + If(Hero Of(Event Player) == Hero(Zenyatta)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 30); + Set Max Health(Event Player, 5 * (100 + Global.TimeMin * 10) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 1.500, False); + Else; + If(20 + 3 * Number Of Players(Team 1) + 3 * Global.TimeMin > 75); + Set Move Speed(Event Player, 75); + Else; + Set Move Speed(Event Player, 20 + 3 * Count Of(All Players(Team 1)) + 3 * Global.TimeMin); + End; + Set Max Health(Event Player, 100 + Global.TimeMin * 10); + End; + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 20); + Set Max Health(Event Player, 5 * (70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + If(30 + Global.TimeMin + 2.500 * Global.Time5Min > 40); + Set Move Speed(Event Player, 40); + Else; + Set Move Speed(Event Player, 30 + Global.TimeMin + 2.500 * Global.Time5Min); + End; + Set Ultimate Charge(Event Player, 0); + Set Max Health(Event Player, 70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + If(Event Player.isBoss == 1); + Set Damage Dealt(Event Player, 2 * (85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min)); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 5 * (100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Event Player.BotCounter = 0; + Set Damage Dealt(Event Player, 85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Bastion)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 50); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Start Scaling Player(Event Player, 3, False); + Set Max Health(Event Player, 5 * (155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Else; + Set Move Speed(Event Player, 80); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Start Scaling Player(Event Player, 2, False); + Set Max Health(Event Player, 155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Orisa)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 5 * (220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Set Move Speed(Event Player, 30 + 5 * Global.Time5Min); + Else; + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min); + Set Move Speed(Event Player, 90 + 5 * Global.Time5Min); + End; + Else If(Hero Of(Event Player) == Hero(Echo)); + If(Event Player.isBoss == 1); + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 70 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 5 * (90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 130 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.500, False); + Set Move Speed(Event Player, 70); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 5 * (55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Else; + disabled Start Scaling Player(Event Player, 0.850, False); + Set Move Speed(Event Player, 110); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin); + End; + End; + Wait(0.250, Ignore Condition); + "FILL HEALTH" + Heal(Event Player, Null, 100000); + } +} + +disabled rule("=== GATE ===") +{ + event + { + Ongoing - Global; + } +} + +rule("Subroutine: GATE REPAIR") +{ + event + { + Subroutine; + GateRepair; + } + + actions + { + Small Message(Event Player, Custom String("REPAIR +2% ULTIMATE")); + "UPGRADE - GATE'S MAX HEALTH" + If(Global.UpgradeGateMaxHealthValue < Global.UpgradeGateMaxHealthMaxValue[2]); + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.UpgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.UpgradeGateMaxHealthValue += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + End; + End; + "HEAL GATE" + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.GateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.GateHealth += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + "CHARGE ULTIMATE" + Else; + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + End; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + } +} + +rule("TORB: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Has Spawned(Event Player) == True; + Weapon(Event Player) == 2; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(Is Using Ability 2(Event Player) == True ? 0.350 : 0.700, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Brig: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 5; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Rein: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + Is Game In Progress == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Call Subroutine(GateRepair); + Wait(0.850, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GATE PROGRESS BAR COLOR") +{ + event + { + Subroutine; + GateProgressBarColor; + } + + actions + { + Stop Chasing Global Variable(GateHealthChase); + Chase Global Variable Over Time(GateHealthChase, Global.GateHealth, 0.100, Destination and Duration); + "GATE WAS DAMAGED" + If(Global.GateHealth < Global.GateHealthEvent); + For Global Variable(LoopIterator1, 0, 3, 1); + Global.GateProgressBarColorCurrent = Color(Red); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(White); + Wait(0.030, Ignore Condition); + End; + "GATE WAS REPAIRED" + Else; + Global.GateProgressBarColorCurrent = Color(Green); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(Yellow); + Wait(0.030, Ignore Condition); + End; + Global.GateHealthEvent = Global.GateHealth; + Global.GateProgressBarColorComponent = Global.GateHealth * 255 / Global.GateMaxHealth; + Global.GateProgressBarColorCurrent = Custom Color(255, Global.GateProgressBarColorComponent, Global.GateProgressBarColorComponent, + 255); + } +} + +disabled rule("=== COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("ALL: INIT") +{ + event + { + Player Joined Match; + All; + All; + } + + actions + { + "ALL (COMMON) INIT" + Event Player.IsDead = True; + Disable Kill Feed(Event Player); + Disable Game Mode In-World UI(Event Player); + Disable Death Spectate Target HUD(Event Player); + "BOT INIT" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotInit); + "PLAYER INIT" + Else; + Call Subroutine(PlayerInit); + End; + } +} + +rule("SUBROUTINE: BOT - INIT") +{ + event + { + Subroutine; + BotInit; + } + + actions + { + "INIT VARS" + Event Player.HasBadStatus = False; + Event Player.IsRespawning = False; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEventPosition = Vector(9999, 999, 9999); + "DISABLE ALL FOR BOT" + Disable Hero HUD(Event Player); + Disable Messages(Event Player); + Disable Text Chat(Event Player); + Disable Scoreboard(Event Player); + Disable Game Mode HUD(Event Player); + Disable Death Spectate All Players(Event Player); + Disable Voice Chat(Event Player, True, True, True); + "INIT AI NAVIGATION VARS" + Call Subroutine(BotResetPathFinding); + } +} + +rule("SUBROUTINE: PLAYER - INIT") +{ + event + { + Subroutine; + PlayerInit; + } + + actions + { + "STORY HEROES" + If(Global.IsStoryHeroes); + Reset Player Hero Availability(Event Player); + Set Player Allowed Heroes(Event Player, Array(Hero(Ana), Hero(Brigitte), Hero(Mercy), Hero(Lúcio), Hero(Moira), Hero(Baptiste), + Hero(Ashe), Hero(D.Va), Hero(Genji), Hero(Hanzo), Hero(Widowmaker), Hero(Cassidy), Hero(Reinhardt), Hero(Soldier: 76), Hero( + Torbjörn), Hero(Tracer), Hero(Winston), Hero(Pharah))); + End; + "TEAM CHALLENGE - PLAYER'S MAX HEALTH" + If(Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0]); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + End; + If(Is Game In Progress); + Disable Game Mode HUD(Event Player); + End; + } +} + +rule("ALL: RESPAWN") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + (Hero Of(Event Player) != Event Player.CurrentHero || Event Player.IsDead == True) == True; + } + + actions + { + Event Player.IsDead = False; + "BOT RESPAWN" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotRespawn); + If(Global.IsDebugAINavigation); + Create Beam Effect(All Players(All Teams), Good Beam, Eye Position(Event Player), Event Player.BotNextNodePosition, Color(Green), + Visible To Position and Radius); + End; + "PLAYER RESPAWN" + Else; + Call Subroutine(PlayerRespawn); + End; + "MUST BE AFTER ALL RESPAWN SUBROUTINES!" + Event Player.CurrentHero = Hero Of(Event Player); + } +} + +rule("SUBROUTINE: BOT - RESPAWN") +{ + event + { + Subroutine; + BotRespawn; + } + + actions + { + "RESET COMMON PROPERTIES" + Event Player.IsRespawning = True; + Enable Nameplates(Event Player, All Players(Team 1)); + Call Subroutine(BotResetPathFinding); + disabled If(Hero Of(Event Player) != Event Player.CurrentHero); + Call Subroutine(GameLogicSetBotProperties); + disabled End; + "INDIVIDUAL HERO'S RESPAWN SCRIPTS" + If(Hero Of(Event Player) == Hero(Bastion)); + Call Subroutine(BotBastionRespawn); + Else If(Hero Of(Event Player) == Hero(Zenyatta)); + Call Subroutine(BotZenyattaRespawn); + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + Call Subroutine(BotWidowRespawn); + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Call Subroutine(BotBallRespawn); + Else If(Hero Of(Event Player) == Hero(Orisa)); + Call Subroutine(BotOrisaRespawn); + Else If(Hero Of(Event Player) == Hero(Echo)); + Call Subroutine(BotEchoRespawn); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Call Subroutine(BotReinRespawn); + End; + Event Player.IsRespawning = False; + } +} + +rule("SUBROUTINE: PLAYER - RESPAWN") +{ + event + { + Subroutine; + PlayerRespawn; + } + + actions + { + "TEAM CHALLENGE - MAX AMMO" + If(Hero Of(Event Player) != Event Player.CurrentHero && Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]); + Set Max Ammo(Event Player, 0, Ammo(Event Player, 0) * 2); + Set Max Ammo(Event Player, 1, Ammo(Event Player, 1) * 2); + Set Ammo(Event Player, 0, Max Ammo(Event Player, 0)); + Set Ammo(Event Player, 1, Max Ammo(Event Player, 1)); + End; + "MUST BE AFTER TEAM CHALLENGE MAX AMMO!" + disabled Event Player.CurrentHero = Hero Of(Event Player); + "PLAYER RESPAWN" + Set Status(Event Player, Null, Phased Out, 3); + Set Facing(Event Player, Vector(-1, 0, 0), To World); + If(Ability Cooldown(Players On Hero(Hero(Mercy), Team 1), Button(Ability 2)) >= 29); + Teleport(Event Player, Event Player.deathPosition); + Else; + Teleport(Event Player, Global.PlayerSpawnPositions[Slot Of(Event Player) == Count Of(Global.PlayerSpawnPositions) ? Random Integer( + 0, Count Of(Global.PlayerSpawnPositions) - 1) : Slot Of(Event Player)]); + End; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + } +} + +rule("PLAYER: DEATH") +{ + event + { + Player Died; + Team 1; + All; + } + + actions + { + If(Hero Of(Event Player) == Hero(Roadhog)); + Event Player.Abilities[8] -= 1; + Wait(Global.Perk[2] ? 5 : 10, Ignore Condition); + Event Player.Abilities[8] += 1; + End; + Event Player.deathPosition = Position Of(Event Player); + disabled If(Event Player.lastSecondWind > 0); + disabled Event Player.lastSecondWind = 0; + disabled End; + Event Player.IsDead = True; + } +} + +rule("BOT: DEATH") +{ + event + { + Player Died; + Team 2; + All; + } + + actions + { + If(Event Player.isBoss == 1); + If(Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]); + If(Global.UpgradeBossHealthValue < Global.UpgradeCriticalDamageMaxValue[2]); + Global.UpgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + End; + End; + Event Player.isBoss = 0; + Global.activeBoss = Null; + Big Message(All Players(Team 1), Custom String("BOSS DIED - {0}", Hero Of(Event Player))); + End; + Event Player.IsDead = True; + Event Player.HasBadStatus = False; + Event Player.BotDoesUniqueBehaviour = False; + Disable Nameplates(Event Player, All Players(Team 1)); + disabled Stop Holding Button(Event Player, Button(Ability 1)); + disabled Stop Holding Button(Event Player, Button(Primary Fire)); + disabled Stop Holding Button(Event Player, Button(Secondary Fire)); + "BOT HAS 1 EFFECT IN VAR (NOT ARRAY)" + Skip If(!Entity Exists(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects); + "BOT HAS MORE THEN 1 EFFECT IN VAR (ARRAY)" + Skip If(Count Of(Event Player.BotEffects) == 0, 3); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects[Event Player.BotLoopIterator1]); + End; + } +} + +disabled rule("=== BOT COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BAD STATUS") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + Event Player.HasBadStatus = True; + "PROCESS BAD STATUS" + If(Hero Of(Event Player) == Hero(Widowmaker)); + Start Rule(BotWidowBadStatus, Do Nothing); + End; + Wait Until(!Has Status(Event Player, Knocked Down) && !Has Status(Event Player, Asleep) && !Has Status(Event Player, Frozen) + && !Has Status(Event Player, Stunned), 15); + Event Player.HasBadStatus = False; + } +} + +rule("SUBROUTINE: BOT - LANDING FROM SKY") +{ + event + { + Subroutine; + BotLandingFromSky; + } + + actions + { + Stop Throttle In Direction(Event Player); + "SET RESPAWN POSITION" + Event Player.BotEventPosition = Random Value In Array(Global.BigBossSpawnPositions); + "CREATE EFFECTS" + disabled Create Effect(All Players(All Teams), Light Shaft, Color(Red), Event Player.BotEventPosition, 3, Visible To); + disabled Event Player.BotEffects = Last Created Entity; + "RESPAWN IN LIGHT SHAFT EFFECT" + Teleport(Event Player, Event Player.BotEventPosition + Vector(0, 25, 0)); + Wait(0.020, Ignore Condition); + "SLOW LANDING" + Set Gravity(Event Player, 50); + While(Is In Air(Event Player) == True); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Position Of(Event Player) + Vector(0, -2.700, 0), 2); + Wait(0.250, Ignore Condition); + End; + Set Gravity(Event Player, 100); + disabled Destroy Effect(Event Player.BotEffects); + "LANDING EFFECTS" + Play Effect(All Players(All Teams), Wrecking Ball Piledriver Impact Effect, Custom Color(105, 87, 46, 255), Position Of( + Event Player), 8); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Sound, Color(White), Position Of(Event Player), 150); + } +} + +rule("SUBROUTINE: BOT - APPEAR FROM UNDERGROUND") +{ + event + { + Subroutine; + BotApearFromUnderground; + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1); + Wait(0.200, Ignore Condition); + Set Gravity(Event Player, 20); + Disable Movement Collision With Environment(Event Player, True); + Teleport(Event Player, Global.ZenSpawnPositions[Random Integer(Min(Global.TimeMin, Count Of(Global.ZenSpawnPositions) - 10), Min( + Global.SpawnPositionMaxId, Count Of(Global.ZenSpawnPositions) - 4))] + Vector(0, -1.500, 0)); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Sigma Accretion Impact Effect, Custom Color(220, 175, 100, 255), Eye Position(Event Player), + 3); + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(Gray), Eye Position(Event Player), 50); + Apply Impulse(Event Player, Up, 3.500, To World, Cancel Contrary Motion); + Wait(0.400, Ignore Condition); + Clear Status(Event Player, Knocked Down); + Set Gravity(Event Player, 100); + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("=== PLAYER MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("PLAYER: DARKNESS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + !Entity Exists(Event Player.BotEffects) == True; + } + + actions + { + Disable Nameplates(Event Player, All Players(All Teams)); + Start Forcing Player Outlines(Event Player, All Players(All Teams), False, Color(White), Default); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 14), 25, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(-5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + } +} + +rule("PLAYER: HEALTH REGEN") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + actions + { + Stop Heal Over Time(Event Player.HealOverTimeId); + Event Player.EventHealth = Health(Event Player); + Wait(4, Ignore Condition); + "TOOK DAMAGE, RESET REGENERATION TIMER" + Loop If(Is Alive(Event Player) && Event Player.EventHealth > Health(Event Player)); + Start Heal Over Time(Event Player, Null, 3, Max Health(Event Player) / 3); + Event Player.HealOverTimeId = Last Heal Over Time ID; + } +} + +disabled rule("=== NERFS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("REINHARDT: ANTI-CHARGE FOR BASTION & ORISA") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Using Ability 1(Event Player) == True; + Hero Of(Ray Cast Hit Player(Eye Position(Event Player) + Vector(0, 2, 0), Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 2, All Living Players(Team 2), Event Player, True)) == (Hero(Bastion) == True || Hero( + Orisa) == True); + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1.500); + } +} + +rule("HOG: ANTI-HOOK FOR BASTION & ORISA") +{ + event + { + Player Dealt Damage; + Team 1; + Roadhog; + } + + conditions + { + Event Ability == Button(Ability 1); + (Hero Of(Victim) == Hero(Bastion) || Hero Of(Victim) == Hero(Orisa)) == True; + } + + actions + { + Set Status(Event Player, Null, Stunned, 0.005); + } +} + +disabled rule("=== ZENYATTA ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ZEN - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Zenyatta; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + } + + actions + { + Set Ammo(Event Player, 0, 0); + Communicate(Event Player, Hello); + disabled Call Subroutine(BotResetPathFinding); + Wait(1.500, Ignore Condition); + Abort If(Is Dead(Event Player) == True); + Kill(Event Player, Null); + } +} + +rule("BOT: ZEN - DEATH") +{ + event + { + Player Died; + Team 2; + Zenyatta; + } + + actions + { + "EFFECT" + Play Effect(All Players(All Teams), Junkrat Frag Launcher Explosion Effect, Color(Red), Eye Position(Event Player), 2.500); + Play Effect(All Players(All Teams), Ashe Dynamite Explosion Sound, Color(Red), Eye Position(Event Player), 70); + "DAMAGE AND APPLY IMPULSE TO PLAYERS" + Event Player.BotPlayersInRadius = Players Within Radius(Position Of(Event Player), 2.500, All Teams, Surfaces And Enemy Barriers); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotPlayersInRadius), 1); + Apply Impulse(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Direction Towards(Position Of(Event Player), + Eye Position(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1])), 5, To World, Incorporate Contrary Motion); + If(Team Of(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1]) == Team 1); + Damage(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Event Player, 50); + End; + End; + "DAMAGE GATE" + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 125; + Else; + Global.GateHealth -= 25; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Respawn(Event Player); + Abort; + End; + "KILLED BY PLAYER" + Teleport(Event Player, Vector(0, -999, 0)); + Wait(2, Ignore Condition); + Respawn(Event Player); + Wait(2, Ignore Condition); + } +} + +rule("SUBROUTINE: ZEN - RESPAWN") +{ + event + { + Subroutine; + BotZenyattaRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WRECKING BALL ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BALL - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + disabled Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Set Ammo(Event Player, 0, 0); + Wait(1, Ignore Condition); + Set Ultimate Charge(Event Player, 100); + Start Holding Button(Event Player, Button(Ultimate)); + Wait Until(Is Using Ultimate(Event Player), 0.600); + Abort If(Is Dead(Event Player)); + Kill(Event Player, Null); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Effect, Color(Orange), Eye Position(Event Player), 6); + Play Effect(All Players(All Teams), DVa Self Destruct Explosion Sound, Color(White), Eye Position(Event Player), 250); + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 300; + Else; + Global.GateHealth -= 150; + End; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Damage(Players Within Radius(Eye Position(Event Player), 7, Team 1, Surfaces And All Barriers), Event Player, 200); + } +} + +rule("BOT: BALL - ALTERNATIVE FORM") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is In Alternate Form(Event Player) == False; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is In Alternate Form(Event Player), 10); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: BALL - DEATH") +{ + event + { + Player Died; + Team 2; + Wrecking Ball; + } + + actions + { + Stop Holding Button(Event Player, Button(Ability 1)); + Stop Holding Button(Event Player, Button(Ultimate)); + } +} + +rule("SUBROUTINE: BALL - RESPAWN") +{ + event + { + Subroutine; + BotBallRespawn; + } + + actions + { + "RESPAWN IN AIR" + Teleport(Event Player, Random Value In Array(Global.BallSpawnPositions) + Vector(0, 20, 0)); + Stop Holding Button(Event Player, Button(Ultimate)); + Wait(0.250, Ignore Condition); + "LANDING" + Start Holding Button(Event Player, Button(Crouch)); + Wait Until(Is On Ground(Event Player), 9999); + Stop Holding Button(Event Player, Button(Crouch)); + "LANDING IMPACT EFFECT" + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(White), Event Player, 150); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Effect, Color(Gray), Position Of(Event Player), 10); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Eye Position(Event Player), 1.500, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + "PATH FINDING TO GATE" + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +disabled rule("=== ECHO ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ECHO - FLY ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is Using Ability 1(Event Player) == False; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), 0); + Press Button(Event Player, Button(Ability 1)); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - BEAM ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Using Ability 1(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == True; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - BAD STATUS - RESET BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.HasBadStatus == True; + disabled (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + Wait Until(Event Player.HasBadStatus, 7); + } +} + +rule("BOT: ECHO - CAN'T SEE PORTAL - APPLY IMPULSE") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == True; + Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Wait(0.300, Abort When False); + Apply Impulse(Event Player, Vector(Random Integer(-1, 1), 1, Random Integer(-1, 1)), 20, To World, Incorporate Contrary Motion); + Wait(1, Ignore Condition); + If(!Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + Event Player.BotTargetPosition = Global.BotEchoRespawnPosition; + Start Rule(BotStartPathFinding, Restart Rule); + Else; + Call Subroutine(BotResetPathFinding); + End; + Loop If Condition Is True; + } +} + +disabled rule("BOT: ECHO - MAIN LOGIC - BACKUP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(!Event Player.BotIsPathFinding); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Is In Line of Sight(Eye Position(Event Player), + Eye Position(Current Array Element), Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), + Position Of(Current Array Element)))[0]; + End; + "NO PLAYERS IN VIEW RANGE" + disabled If(Event Player.BotSeePlayer == Null); + disabled Stop Throttle In Direction(Event Player); + disabled End; + "FLY TO PLAYER" + If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + > 4 && Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + "ACTIVATE FOCUS BEAM" + Else If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + < 4 && Event Player.BotDoesUniqueBehaviour == False && Event Player.HasBadStatus == False); + Event Player.BotDoesUniqueBehaviour = True; + Set Status(Event Player.BotSeePlayer, Event Player, Stunned, 1); + Set Status(Event Player.BotSeePlayer, Event Player, Hacked, 99999); + Attach Players(Event Player.BotSeePlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + "TELEPORT PLAYER TO AWAY" + Else If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotSeePlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotSeePlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotSeePlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + "BEGIN TO FLY TO THE PORTAL" + Else If(Event Player.BotDoesUniqueBehaviour == True); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + End; + "TELEPORT PLAYER SO FAR" + If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotEchoCapturedPlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotEchoCapturedPlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + End; + "BEGIN TO FLY TO THE PORTAL WITH A PLAYER" + If(Event Player.BotDoesUniqueBehaviour); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotEchoCapturedPlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - DEFEND PORTAL") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + } + + actions + { + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPlayer); + } +} + +rule("BOT: ECHO - PATH FINDING TO PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Call Subroutine(BotStartPathFinding); + } +} + +rule("BOT: ECHO - ATTACH PLAYER BY BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotEchoCapturedPlayer == Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 3; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Event Player.BotEchoCapturedPlayer = Event Player.BotSeePlayer; + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Stunned, 0.700); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Hacked, 10); + Attach Players(Event Player.BotEchoCapturedPlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - PLAYER DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Dead(Event Player.BotEchoCapturedPlayer) != Null; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - DEATH") +{ + event + { + Player Died; + Team 2; + Echo; + } + + actions + { + Call Subroutine(BotEchoDetachPlayer); + Stop Holding Button(Event Player, Button(Jump)); + Wait(5, Ignore Condition); + Teleport(Event Player, Vector(0, 999, 0)); + Start Forcing Player To Be Hero(Event Player, Hero(Orisa)); + } +} + +rule("SUBROUTINE: ECHO - RESPAWN") +{ + event + { + Subroutine; + BotEchoRespawn; + } + + actions + { + Event Player.BotCounter = 0; + Event Player.BotEffects = Empty Array; + Create Effect(All Players(All Teams), Good Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Energy Sound, Color(White), Global.BotEchoRespawnPosition, 200, Visible To); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Chase Player Variable Over Time(Event Player, BotCounter, 3, 0.800, Destination and Duration); + Play Effect(All Players(All Teams), Sombra EMP Explosion Effect, Color(Sky Blue), Global.BotEchoRespawnPosition, 12); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Null, Global.BotEchoRespawnPosition, 100); + Wait(3, Ignore Condition); + Teleport(Event Player, Global.BotEchoRespawnPosition); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Global.BotEchoRespawnPosition, 2.500); + Play Effect(All Players(All Teams), Debuff Impact Sound, Null, Global.BotEchoRespawnPosition, 100); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PLAYER") +{ + event + { + Subroutine; + BotEchoFlyToPlayer; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Stop Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PORTAL") +{ + event + { + Subroutine; + BotEchoFlyToPortal; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - DETACH PLAYER") +{ + event + { + Subroutine; + BotEchoDetachPlayer; + } + + actions + { + Detach Players(Event Player.BotEchoCapturedPlayer); + Clear Status(Event Player.BotEchoCapturedPlayer, Hacked); + "IF PLAYER INSIDE THE WALL" + If(Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotEchoCapturedPlayer), Barriers Do Not Block LOS)); + Teleport(Event Player.BotEchoCapturedPlayer, Position Of(Event Player)); + End; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEchoCapturedPlayer = Null; + } +} + +disabled rule("=== REINHARDT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: REIN - SET PLAYER AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + disabled Event Player.BotIsPathFinding == False; + "BOT IS FAR FROM GATES" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Global.GatePosition), 0, Z Component Of(Global.GatePosition))) > 20; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET CLOSEST PLAYER TO BOT AS TARGET AND FOLLOW HIM" + Event Player.BotTargetPlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - SET GATE AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "BOT DOESN'T FOLLOW PLAYER" + Event Player.BotTargetPlayer == -1; + "CAN'T SEE ANY PLAYER" + disabled Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), !Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET GATE AS TARGET" + Event Player.BotTargetPosition = Global.GatePosition; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - TARGET DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer != -1; + Is Dead(Event Player.BotTargetPlayer) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + } +} + +rule("BOT: REIN - ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) < 4; + "CAN ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) < 4; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + "TARGET IS PLAYER" + Abort If(Event Player.BotTargetPlayer != -1); + If(Event Player.isBoss == 1); + "TARGET IS GATE" + Global.GateHealth -= 25; + Else; + Global.GateHealth -= 5; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: REIN - STOP ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) > 4; + "CAN'T ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) > 4; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + } +} + +rule("BOT: REIN - USE SHIELD") +{ + event + { + Player Took Damage; + Team 2; + Reinhardt; + } + + conditions + { + Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) > 3; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Attacker)), 200, To World, + Direction and Turn Rate); + Start Holding Button(Event Player, Button(Secondary Fire)); + Wait Until(Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) < 3, 3); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("BOT: REIN - CHARGE IN GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer == -1; + Is Using Ability 1(Event Player) == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == True; + Is In View Angle(Event Player, Global.GatePosition, 7.500) == True; + } + + actions + { + disabled Wait(0.800, Abort When False); + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is Using Ability 1(Event Player), 1); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: REIN - DEATH") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("SUBROUTINE: REIN - RESPAWN") +{ + event + { + Subroutine; + BotReinRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WIDOW ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: WIDOW - SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer == Null; + Event Player.HasBadStatus == False; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Event Player.BotWidowShotTime = Total Time Elapsed + (Global.TimeMin >= 9 ? Random Real(2, 5) : Random Real(5, 10)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 9999, To World, + Direction and Turn Rate); + } +} + +rule("BOT: WIDOW - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer != Null; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowShotTime; + } + + actions + { + Press Button(Event Player, Button(Primary Fire)); + Stop Facing(Event Player); + Event Player.BotSeePlayer = Null; + } +} + +rule("BOT: WIDOW - Aim Sound") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Alive(Event Player) == True; + Is In Line of Sight(Eye Position(Players On Hero(Hero(Widowmaker), Team 2)), Eye Position(Event Player), Barriers Do Not Block LOS) + == True; + Is Alive(Players On Hero(Hero(Widowmaker), Team 2)) == True; + Players On Hero(Hero(Widowmaker), Team 2).BotSeePlayer == True; + } + + actions + { + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 100); + Wait(1, Abort When False); + Loop If Condition Is True; + } +} + +rule("BOT: WIDOW - TELEPORT TO NEW POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowTeleportTime; + } + + actions + { + Event Player.BotWidowTeleportTime = Total Time Elapsed + 28; + Event Player.BotWidowShotTime = Total Time Elapsed + Random Real(1, 1.600); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Event Player, 1); + Wait(0.016, Ignore Condition); + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + Event Player.BotWidowShotTime = Total Time Elapsed + (Global.TimeMin >= 9 ? Random Real(2, 5) : Random Real(5, 10)); + } +} + +rule("BOT: WIDOW - DEATH") +{ + event + { + Player Died; + Team 2; + Widowmaker; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + Wait(0.250, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - RESPAWN") +{ + event + { + Subroutine; + BotWidowRespawn; + } + + actions + { + "RESPAWN ON RANDOM SNIPER POSITION" + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Wait(0.700, Ignore Condition); + Start Holding Button(Event Player, Button(Secondary Fire)); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait Until(Is Dead(Event Player), 99999); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - BAD STATUS") +{ + event + { + Subroutine; + BotWidowBadStatus; + } + + actions + { + Stop Facing(Event Player); + Destroy Effect(Event Player.BotEffects); + Wait Until(!Event Player.HasBadStatus, 15); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + } +} + +disabled rule("=== BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("BOT: BASTION - FLAME GUN") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 50) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 8; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Stop Holding Button(Event Player, Button(Primary Fire)); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Update Every Frame(Eye Position(Event Player) + World Vector Of( + Vector(-1, -1.200, 1.800), Event Player, Rotation)), 1, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Start Rule(BotBastionFlameGunDamage, Do Nothing); + Wait(1.100, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(4, Ignore Condition); + Loop If Condition Is True; + } +} + +disabled rule("BOT: BASTION - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + disabled Event Player.BotSeePlayer == Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - CAN'T SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == False; + } + + actions + { + Event Player.BotSeePlayer = Null; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - MOVE TO BASTION'S TARGET (POSITION)") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotTargetPosition = Random Value In Array(Filtered Array(Global.BastionTargetPositions, Distance Between(Position Of( + Event Player), Current Array Element) > 3.500)); + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("BOT: BASTION - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + "SEE THE PLAYER" + If(Event Player.BotSeePlayer != Null); + Stop Holding Button(Event Player, Button(Secondary Fire)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer) - Vector(0, 0.500, + 0)), 100, To World, Direction and Turn Rate); + "SELF REPAIRING" + Else If(!Is Firing Secondary(Event Player) && Health(Event Player) < Max Health(Event Player)); + Start Holding Button(Event Player, Button(Secondary Fire)); + End; + "START FOLLOW PATH" + disabled If(!Event Player.BotIsPathFinding && !Event Player.BotDoesUniqueBehaviour); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled Wait(0.050, Ignore Condition); + disabled Event Player.BotTargetPosition = Random Value In Array(Global.BastionTargetPositions); + disabled Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Event Player.BotTargetPosition + Vector(0, 2, 0)), 100, + To World, Direction and Turn Rate); + disabled Start Rule(BotStartPathFinding, Do Nothing); + "REACHED PATH TARGET" + disabled Else If(Distance Between(Position Of(Event Player), Event Player.BotTargetPosition) <= 3); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled End; + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - ARTILLERY") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 30) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) > 18; + Distance Between(Eye Position(Event Player), Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Up * 99, Null, Event Player, False)) >= 35; + } + + actions + { + "TRYING TO CAPTURE TARGET" + Wait(0.800, Abort When False); + "CAPTURE TARGET" + Event Player.BotDoesUniqueBehaviour = True; + Stop Throttle In Direction(Event Player); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Update Every Frame(Eye Position(Event Player)), + Update Every Frame(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 1000, All Living Players(Team 1), Event Player, True)), Color(Sky Blue), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait(1.400, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Event Player.BotEventPosition = Position Of(Event Player.BotSeePlayer); + "SHOOT FROM ARTILLERY" + Event Player.BotBastionArtilleryDidShotsCount = 0; + For Player Variable(Event Player, BotLoopIterator1, 0, 4, 1); + Event Player.BotBastionArtilleryDidShotsCount += 1; + Play Effect(All Players(All Teams), Wrecking Ball Minefield Explosion Sound, Color(White), Eye Position(Event Player), 250); + Play Effect(All Players(All Teams), Pharah Barrage Explosion Effect, Color(Orange), Eye Position(Event Player) + World Vector Of( + Vector(0, 1.400, -0.700), Event Player, Rotation), 2); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) + World Vector Of(Vector(0, 1.400, + -0.700), Event Player, Rotation), Eye Position(Event Player) + World Vector Of(Vector(Random Real(-1, 1), Random Integer(40, + 80), Random Real(0.500, 1.500)), Event Player, Rotation), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + If(Is Dead(Event Player)); + Break; + End; + End; + disabled Call Subroutine(BotResetPathFinding); + disabled Start Rule(BotStartPathFinding, Do Nothing); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Wait(1.500, Ignore Condition); + Start Rule(BotBastionArtilleryDamage, Do Nothing); + Wait(4, Ignore Condition); + } +} + +rule("BOT: BASTION - PRIMARY FIRE") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 40) == True; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Stop Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Bastion; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + For Player Variable(Event Player, BotLoopIterator1, 0, 3, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Effect, Color(White), Event Player, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player, 100); + Wait(0.250, Ignore Condition); + End; + } +} + +rule("SUBROUTINE: BASTION - RESPAWN") +{ + event + { + Subroutine; + BotBastionRespawn; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + Call Subroutine(BotLandingFromSky); + Set Ammo(Event Player, 0, 0); + Wait Until(!Is Reloading(Event Player), 99999); + Event Player.BotTargetPosition = Objective Position(2); + } +} + +rule("SUBROUTINE: BASTION - ARTILLERY DAMAGE") +{ + event + { + Subroutine; + BotBastionArtilleryDamage; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = False; + "EXPLOSIONS OF ARTILLERY" + For Player Variable(Event Player, BotLoopIterator2, 0, Event Player.BotBastionArtilleryDidShotsCount, 1); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotEventPosition + Vector(0, 50, 0), + Event Player.BotEventPosition + Vector(Random Integer(-4, 4), -15, Random Integer(-4, 4)), Null, Event Player, True); + Damage(Players Within Radius(Event Player.BotEventPosition, 8, Team 1, Surfaces And Enemy Barriers), Event Player, 50); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Pharah Rocket Launcher Explosion Effect, Color(Orange), Event Player.BotEventPosition, 5); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Event Player.BotEventPosition, + Event Player.BotEventPosition + Vector(0, 60, 0), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + End; + } +} + +disabled rule("SUBROUTINE: BASTION - FLAME GUN DAMAGE") +{ + event + { + Subroutine; + BotBastionFlameGunDamage; + } + + actions + { + Event Player.BotRayCastHitPosition = Eye Position(Event Player) + World Vector Of(Vector(-1, -1.200, 1.800), Event Player, + Rotation); + "FIRE PARTICLES OF FLAME GUN" + For Player Variable(Event Player, BotLoopIterator1, 1, 13, 3); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotRayCastHitPosition, + Event Player.BotRayCastHitPosition + Facing Direction Of(Event Player) * Event Player.BotLoopIterator1, Null, Event Player, + True); + Damage(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Surfaces And Enemy Barriers), Event Player, 20); + Set Status(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Off), Event Player, Burning, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.BotEventPosition, 2.500); + Wait(0.200, Ignore Condition); + End; + Event Player.BotDoesUniqueBehaviour = False; + } +} + +disabled rule("=== ORISA + BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ORISA-BASTION - REACHED TARGET POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotIsPathFinding == True; + Distance Between(Position Of(Event Player), Global.BotOrisaTargetPosition) < 1.500; + } + + actions + { + Call Subroutine(BotResetPathFinding); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Vector(X Component Of(Global.GatePosition), -999, + Z Component Of(Global.GatePosition))), 80, To World, Direction and Turn Rate); + Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + disabled Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element) && Is In Line of Sight(Eye Position(Event Player), Position Of(Current Array Element), + Barriers Do Not Block LOS)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + Press Button(Event Player, Button(Ability 1)); + Wait Until(Y Component Of(Facing Direction Of(Event Player)) < -0.300, 99999); + Press Button(Event Player, Button(Ability 2)); + Wait(0.800, Ignore Condition); + Global.BotOrisaChild.BotDoesUniqueBehaviour = False; + Disallow Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ORISA-BASTION - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + While(Is Alive(Event Player)); + disabled Create Effect(All Players(All Teams), Bad Aura, Color(Purple), Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3.200, 1, Visible To Position and Radius); + disabled Event Player.BotEffects = Last Created Entity; + Wait(1.500, Ignore Condition); + disabled Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Press Button(Event Player, Button(Primary Fire)); + Press Button(Event Player, Button(Reload)); + Event Player.BotRayCastHitPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Facing Direction Of(Event Player) * 999, All Players(Team 1), All Players(Team 2), True); + "ANTI-SHIELD BUG" + Event Player.BotRayCastHitPosition = Event Player.BotRayCastHitPosition + Direction Towards(Event Player.BotRayCastHitPosition, + Eye Position(Event Player)) * 0.200; + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3, Event Player.BotRayCastHitPosition, Color(Purple), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Damage(Players Within Radius(Event Player.BotRayCastHitPosition, 4, Team 1, Surfaces And All Barriers), Event Player, 0.040); + Play Effect(All Players(All Teams), Pharah Concussive Blast Effect, Color(Purple), Event Player.BotRayCastHitPosition, 4); + Play Effect(All Players(All Teams), Pharah Concussive Blast Sound, Color(Purple), Event Player.BotRayCastHitPosition, 250); + Play Effect(All Players(All Teams), Bad Explosion, Color(Purple), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 3.300, 2); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Color(Purple), Eye Position(Event Player), 170); + If(Distance Between(Event Player.BotRayCastHitPosition, Global.GatePosition) < 4 && Is In Line of Sight( + Event Player.BotRayCastHitPosition, Global.GatePosition, Enemy Barriers Block LOS)); + Global.GateHealth -= 80; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Wait(0.150, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.060, Ignore Condition); + Wait Until(!Is Reloading(Event Player), 2.500); + End; + } +} + +rule("BOT: ORISA-BASTION - CAN'T SEE THE TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: ORISA-BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Orisa; + } + + actions + { + Allow Button(Event Player, Button(Ability 2)); + Kill(Global.BotOrisaChild, Null); + Detach Players(Global.BotOrisaChild); + Clear Status(Global.BotOrisaChild, Phased Out); + Set Damage Dealt(Global.BotOrisaChild, 100); + Global.BotOrisaChild.BotIsOrisaChild = False; + Global.BotOrisaChild = Null; + Global.BotOrisaParent = Null; + Start Forcing Player To Be Hero(Event Player, Hero(Widowmaker)); + } +} + +rule("SUBROUTINE: ORISA - RESPAWN") +{ + event + { + Subroutine; + BotOrisaRespawn; + } + + actions + { + Global.BotOrisaParent = Event Player; + "WAITING FOR ANY BASTION TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero(Bastion)), + 99999); + "SETUP BASTION AS CHILD" + Global.BotOrisaChild = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Bastion))[0]; + Global.BotOrisaChild.BotIsOrisaChild = True; + Global.BotOrisaChild.BotDoesUniqueBehaviour = True; + Wait(2, Ignore Condition); + Respawn(Global.BotOrisaChild); + Start Scaling Player(Global.BotOrisaChild, 1.800, False); + Set Damage Dealt(Global.BotOrisaChild, 2000); + Set Status(Global.BotOrisaChild, Null, Phased Out, 9999); + Disable Nameplates(Global.BotOrisaChild, All Players(All Teams)); + Set Facing(Global.BotOrisaChild, Vector(X Component Of(Facing Direction Of(Event Player)), 9999, Z Component Of( + Facing Direction Of(Event Player))), To World); + Start Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Wait Until(Is In Alternate Form(Global.BotOrisaChild), 5); + Stop Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Teleport(Global.BotOrisaChild, Position Of(Event Player)); + Attach Players(Global.BotOrisaChild, Global.BotOrisaParent, Vector(0, 1.800, 0.230)); + disabled Wait(1, Ignore Condition); + disabled Stop Holding Button(Global.BotOrisaChild, Button(Primary Fire)); + disabled Wait(0.250, Ignore Condition); + Call Subroutine(BotLandingFromSky); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 0 - ZENS, REINS, BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 0; + } + + actions + { + "CREATE BOTS - ZEN" + While(Count Of(All Players(Team 2)) < 13); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "BALL" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "REPLACE DEAD ZEN TO REIN" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) != 3); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 1 - WIDOW") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 1; + } + + actions + { + Global.IsNewWaveGameLogicProcessing = True; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Global.IsNewWaveGameLogicProcessing = False; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 3 - BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 3; + } + + actions + { + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 5 - REINS WAVE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 5; + } + + actions + { + "PREPARE WAVE - DESTROY WIDOW AND BALLS" + Destroy Dummy Bot(Team 2, Slot Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))[0])); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))[0]; + Kill(Global.DefaultCurrentBot, Null); + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + "BOSS WAVE" + Big Message(All Players(All Teams), Custom String("BOSS WAVE - {1} {0}", Hero Icon String(Hero(Reinhardt)), Hero(Reinhardt))); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) < 6); + Wait Until(Is True For Any(All Players(Team 2), Distance Between(Position Of(Current Array Element), Global.GatePosition) + > 13 && Hero Of(Current Array Element) == Hero(Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + disabled Wait(0.200, Ignore Condition); + disabled Set Max Health(Global.DefaultCurrentBot, 50); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) > 3); + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Reinhardt)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Reinhardt))[0]; + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(All Players(Team 2)) < 13); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Big Message(All Players(All Teams), Custom String("BOSS WAVE FINISHED!")); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 7 - BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 7; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 9 - ECHO, +1 BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 9; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Echo))) == 0); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + "FILL EMPTY SLOTS BY ZENS" + While(Count Of(All Players(Team 2)) < 12); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("Ana Nano Variable") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + } + + actions + { + Player Closest To Reticle(Event Player, Team 1).IsNanoed = 1; + } +} + +rule("IsNanoed") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.IsNanoed == True; + } + + actions + { + If(Is Dead(Event Player)); + Event Player.IsNanoed = 0; + End; + Wait(8, Ignore Condition); + Event Player.IsNanoed = 0; + } +} + +rule("money on kill") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + actions + { + If(Hero Of(Victim) == Hero(Zenyatta)); + All Players(Team 1).Money[0] += 10 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 10 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Reinhardt)); + All Players(Team 1).Money[0] += 20 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 20 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Wrecking Ball)); + All Players(Team 1).Money[0] += 25 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 25 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Widowmaker)); + All Players(Team 1).Money[0] += 30 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 30 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Bastion)); + All Players(Team 1).Money[0] += 50 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 50 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Echo)); + All Players(Team 1).Money[0] += 75 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 75 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Orisa)); + All Players(Team 1).Money[0] += 100 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 100 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + } +} + +rule("Abilities and Hero Talents by Shingen and LemonAid") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.DamageDealt = 100; + Event Player.PlayerHealth = 100; + Event Player.Money[0] = 2400 + Global.StartMoney; + If(Custom String("{0}", Event Player) == Custom String("ShuriZma")); + Create HUD Text(Event Player, Custom String("Serverload: {0}, AVG {1}, Peak {2}", Server Load, Server Load Average, + Server Load Peak), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create HUD Text(Event Player, Custom String("Last SW: {0}, SW Active {1}", Event Player.lastSecondWind, + Event Player.secondWindActive), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + End; + } +} + +rule("Team 1 (Ability): Headhunter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[1] == True; + Event Was Critical Hit == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[1] * 40 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Ambush") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[2] == True; + Event Ability != Null; + (Y Component Of(Position Of(Event Player)) - Y Component Of(Position Of(Victim)) >= 3 || Absolute Value(Horizontal Angle Towards( + Victim, Event Player)) >= 90) == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[2] * 30 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Quick Fix") +{ + event + { + Player Earned Elimination; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[3] == True; + } + + actions + { + Heal(Event Player, Null, Event Player.Abilities[3] * 50); + Set Move Speed(Event Player, 100 + Event Player.Abilities[3] * 20); + Wait(5, Restart When True); + Set Move Speed(Event Player, 100); + } +} + +rule("Team 1 (Ability): Heavyweight") +{ + event + { + Player Dealt Knockback; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[4] == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[4] * 25 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Charged") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[5] == True; + Ultimate Charge Percent(Event Player) < Event Player.Abilities[5] * 20; + } + + actions + { + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + If(Is Duplicating(Event Player)); + Wait(0.016, Ignore Condition); + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + End; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Team 1 (Ability): Haste Primary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Primary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Primary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Primary Fire))); + } +} + +rule("Team 1 (Ability): Haste Secondary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Secondary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Secondary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Secondary Fire))); + } +} + +rule("Team 1 (Ability): Haste Ability 1") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 1)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 1))); + } +} + +rule("Team 1 (Ability): Haste Ability 2") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 2)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 2))); + } +} + +rule("Team 1 (Ability): Haste Jump") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Jump)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Jump), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Jump))); + } +} + +rule("Team 1 (Ability): Haste Crouch") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Crouch)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Crouch), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Crouch))); + } +} + +rule("Team 1 (Ability): Heavy Impact") +{ + event + { + Player Took Damage; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[7] == True; + } + + actions + { + Abort If(Random Real(-0.020, 1) > Event Damage / Max Health(Event Player)); + Set Status(Event Player, Attacker, Stunned, 1 * Attacker.Abilities[7]); + Wait(5, Ignore Condition); + } +} + +rule("Team 1 (Ability): Binding Heal") +{ + event + { + Player Dealt Healing; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[10] == True; + Healee != Event Player; + } + + actions + { + Set Player Health(Event Player, Health(Event Player) + Event Player.Abilities[10] * 0.250 * Event Healing); + } +} + +rule("Team 1 (Ability): Resilience") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[11] == True; + Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300; + } + + actions + { + Set Damage Received(Event Player, 70); + Wait Until(!(Event Player.Abilities[11] && Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Auto Repair") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.AutoRepair == True; + Global.GateHealth < Global.GateMaxHealth; + } + + actions + { + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2]); + Global.GateHealth += 10 * Global.AutoRepair; + Global.UpgradeGateMaxHealthValue += 10 * Global.AutoRepair; + Else; + Global.GateHealth += 5 * Global.AutoRepair; + Global.UpgradeGateMaxHealthValue += 5 * Global.AutoRepair; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(5, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ana Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ana), Button(Ability 1)), Custom String( + "Sleep Paralysis: Slept enemies cannot be woken up by damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Ana), Button(Ability 2)), Custom String( + "Multinade: Ana throws multiple Biotic Grenades")); + } +} + +rule("Brigitte Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Brigitte), Button(Ability 1)), Custom String( + "Heavy Iron: Hitting enemies with Whip Flail will root them in pace")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Brigitte), Button(Ultimate)), Custom String( + "Endeavor: Gain a health, damage and speed boost when your barrier breaks")); + } +} + +rule("Mercy Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mercy), Button(Ability 2)), Custom String( + "Angelic blessing: Healing an ally slowly charges their ultimate")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mercy), Button(Ultimate)), Custom String( + "Holy light missiles: Unleash blasts of holy light missiles during valkyrie")); + } +} + +rule("Lúcio Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Lúcio), Button(Secondary Fire)), Custom String( + "Healing Wave: Soundwave heals allies for 30% of their max HP")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Lúcio), Button(Ability 1)), Custom String( + "Reverse Amp: Amp It Up inflicts the opposite effect of the currently played song to enemies")); + } +} + +rule("Moira Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Moira), Button(Secondary Fire)), Custom String( + "Hose: Biotic Grasp primary will damage and push enemies back")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Moira), Button(Ability 2)), Custom String( + "Flourish: Biotic Orbs are 3x more effective")); + } +} + +rule("Baptiste Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String( + "Corrode: Regenerative Burst will damage and poison enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Breakthrough: Immortality Field HP threshold increased to 100%; allies inside gain ultimate")); + } +} + +rule("Ashe Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ashe), Button(Ability 2)), Custom String( + "Wildfire: Shooting a burning enemy ignites other nearby enemies")); + Event Player.HeroTalentText[2] = Array(Icon String(Fire), Custom String( + "Flare trigger: Coach gun instantly damages all burning enemies")); + } +} + +rule("D.Va Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(D.Va), Button(Secondary Fire)), Custom String( + "Voltage Grid: Defense Matrix will damage and root enemies it's casted over")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(D.Va), Button(Ability 1)), Custom String( + "Shooting Star: Boosters set enemies on fire")); + } +} + +rule("Genji Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Genji), Button(Ability 1)), Custom String( + "Venomous Strike: Swift Strike poisons enemies; heal for poison damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Genji), Button(Ultimate)), Custom String( + "Dragon's Breath: Dragonblade fires large explosive energy charges")); + } +} + +rule("Hanzo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Hanzo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "Stormbreak: Enemies eliminated by hanzo unleash a thundercloud")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Hanzo), Button(Ability 2)), Custom String( + "Punch II: Storm Arrows deal more damage and stun and knockback enemies")); + } +} + +rule("Widowmaker Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Widowmaker; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Widowmaker), Button(Ultimate)), Custom String( + "Kiss Of Death: Scoped critical hits against enemies below 30% health explode and instantly die")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Widowmaker), Button(Ability 2)), Custom String( + "Epidemic: Enemies hurt by Venom Mine unleash toxic pulses; heal for dealt damage")); + } +} + +rule("McCree Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Cassidy), Button(Ability 2)), Custom String( + "Panic: Flashbang puts enemies in fear; deal +120% more damage to enemies in fear")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Cassidy), Button(Ultimate)), Custom String( + "Clocked: Deadeye deals more damage and knocks enemies down")); + } +} + +rule("Reinhardt Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reinhardt), Button(Ability 2)), Custom String( + "Fire Blast: Fire Strike explodes as it deals damage, setting enemies on fire")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reinhardt), Button(Ultimate)), Custom String( + "Epicenter: Earthshatter travels in all directions")); + } +} + +rule("Soldier: 76 Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ultimate)), Custom String( + "Triple Threat: 2 more rockets are fired alongside Helix Rockets")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Soldier: 76), Button(Ability 1)), Custom String( + "Shoulder Check: Sprinting into enemies will damage and tackle them to the ground")); + } +} + +rule("Torbjörn Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Torbjörn), Button(Ability 2)), Custom String( + "Melting point: Unleash heatwaves during overload and molten core")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Torbjörn), Button(Ultimate)), Custom String( + "Roots Of Magma: Enemies trapped in Molten Core blots cannot move")); + } +} + +rule("Tracer Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Tracer), Button(Ability 2)), Custom String( + "Vortex: Recall pulls and roots enemies towards the activation point")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Tracer), Button(Ultimate)), Custom String( + "Chain Reaction: Pulse Bomb creates chain explosions on enemies damaged by it")); + } +} + +rule("Winston Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Winston), Button(Ability 2)), Custom String( + "Blast Barrier: Barrier Projector damages enemies inside the area")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Winston), Button(Ultimate)), Custom String( + "Next Generation: Eliminations during Primal Rage add +15% ultimate charge towards the next")); + } +} + +rule("Pharah Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Pharah; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ability 2)), Custom String( + "Head Trauma: Concussive Blast stuns and damages enemies for 25% of their max health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Pharah), Button(Ability 1)), Custom String( + "Thunderbird: Gain 150 shields and deal 4x the damage to barriers and objects")); + } +} + +rule("Bastion Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Bomblets: Bullets shot during sentry configuration are explosive")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ability 1)), Custom String( + "Tesla: A powerful mounted laser will autmotically attack one enemy at a time")); + } +} + +rule("Doomfist Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Jump)), Custom String( + "Phase Shifter: Immune to damage while any ability is active")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Doomfist), Button(Ultimate)), Custom String( + "Fissure: Meteor Strike leaves a large fissure behind that burns enemies over it")); + } +} + +rule("Echo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Focusing Optics: Focusing Beam damage ramp starts at 90% health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Streamline: Fire many more sticky bombs per burst")); + } +} + +rule("Junkrat Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Junkrat; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Fire), Custom String("Pyromania: All explosive attacks inflict fire damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Junkrat), Button(Ability 2)), Custom String( + "Short Fused: Steel Trap sets off violent explosions once triggered")); + } +} + +rule("Mei Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mei), Button(Ultimate)), Custom String( + "Cold Snap: Instantly freeze neaerby enemies once Cryo-Freeze expires")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mei), Button(Ability 2)), Custom String( + "Icebound: While Ice Wall is up, Icicles freeze and deal much more damage")); + } +} + +rule("Orisa Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Orisa), Button(Ability 1)), Custom String( + "Immovable Object: During Fortify, become immune and convert 50% of taken damage to healing")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Orisa), Button(Secondary Fire)), Custom String( + "Unstoppable Force: Halt! is much larger and pushes enemies. When triggered, it explodes violently")); + } +} + +rule("Reaper Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reaper), Button(Ability 1)), Custom String( + "shadow streak: shadow step creates a beam that damages enemies who cross")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reaper), Button(Ultimate)), Custom String( + "Loom: Traumatize enemies in front of you when using Wraith Form")); + } +} + +rule("Roadhog Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String("Stench: Roadhog constantly damages enemies nearby")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Roadhog), Button(Ability 1)), Custom String( + "Rusted Anchor: Hook deals more damage; Eliminations will reset hook cooldown")); + } +} + +rule("Sigma Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sigma), Button(Ability 1)), Custom String( + "Gravity Well: Kinetic Grasp gives invincibility")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sigma), Button(Ultimate)), Custom String( + "Gravity Channels: Gravitic Flux damages enemies for 75% of max hp instead of 50%")); + } +} + +rule("Sombra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sombra), Button(Secondary Fire)), Custom String( + "Malware: Enemies hacked or in fear take +100% more damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sombra), Button(Ultimate)), Custom String( + "Glitch: EMP leaves behind a large hack zone ")); + } +} + +rule("Symmetra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Symmetra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "High Voltage: Enemies eliminated by Symmetra explode and damage other enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ultimate)), Custom String( + "Energy Source: While Photon Barrier is active, all players regenerate health and gain ultimate")); + } +} + +rule("Wrecking Ball Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ultimate)), Custom String( + "Mirror Ball: Reflect 100% of taken damage to nearby enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ability 2)), Custom String( + "Distort: Adaptive Shields damages and hacks nearby enemies")); + } +} + +rule("Zarya Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zarya; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Zarya), Button(Ability 1)), Custom String( + "Augment: Health and barrier hp increased by 50%; barrier sized doubled")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Perpetual Energy: secondary inflicts burn damage that continues to last until the enemy dies")); + } +} + +rule("Zenyatta Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Vigor: The ally under the effect of Harmony Orb is immune to damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Zenyatta), Button(Ultimate)), Custom String( + "Perfect Balance: Transcendence damages enemies in a large proximity")); + } +} + +rule("Ana: Sleep Paralysis") +{ + event + { + Player Dealt Damage; + Team 1; + Ana; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Black), Victim, 1); + Wait(0.250, Ignore Condition); + Set Status(Victim, Null, Knocked Down, 5); + } +} + +rule("Ana: Multinade") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.AbilityCountdown = 4; + While(Event Player.AbilityCountdown > 0); + Wait(0.030, Ignore Condition); + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Cancel Primary Action(Event Player); + Wait(0.050, Ignore Condition); + Press Button(Event Player, Button(Ability 2)); + Event Player.AbilityCountdown -= 1; + End; + Wait(2, Ignore Condition); + } +} + +rule("Brigitte: Heavy Iron") +{ + event + { + Player Dealt Damage; + Team 1; + Brigitte; + } + + conditions + { + (Event Ability == Button(Primary Fire) || Event Ability == Button(Ability 1)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Victim, 1.500); + Set Status(Victim, Null, Rooted, 0.500); + Set Environment Credit Player(Victim, Event Player); + } +} + +rule("Brigitte: Endeavor") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Ability Cooldown(Event Player, Button(Secondary Fire)) >= 0.100; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Eye Position(Event Player), 15); + Heal(Players Within Radius(Event Player, 15, Team Of(Event Player), Off), Event Player, 200); + Event Player.DamageDealt *= 2.500; + Set Move Speed(Event Player, 100 * 1.750); + Add Health Pool To Player(Event Player, Armor, Max Health(Event Player) / 2, False, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(Is Dead(Event Player), 6); + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Move Speed(Event Player, 100); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Mercy: Angelic Blessing") +{ + event + { + Player Dealt Healing; + All; + Mercy; + } + + conditions + { + Event Player.Abilities[8] == True; + Healee != Event Player; + Normalized Health(Healee) < True; + } + + actions + { + Set Ultimate Charge(Healee, Ultimate Charge Percent(Healee) + 1); + Wait(0.400, Ignore Condition); + } +} + +rule("Mercy: Aurora") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ultimate(Event Player) == True; + } + + actions + { + Wait(1.500, Ignore Condition); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(All Teams), Event Player, True); + Create Beam Effect(All Players(All Teams), Mercy Heal Beam, Event Player, Event Player.Ability_Projectile1, Color(White), + Visible To Position and Radius); + Event Player.Effects_[3] = Last Created Entity; + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 70, Destination and Rate); + While(Event Player.Ability_End != Event Player.Ability_Projectile1); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Event Player.Ability_Projectile1, 1); + Wait(0.032, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[3]); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 120); + Loop If Condition Is True; + } +} + +rule("Lucio: Healing Wave") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4); + Heal(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 4, 4, Team Of(Event Player), Surfaces), + Event Player, Max Health(Filtered Array(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4, Team Of(Event Player), Surfaces), Is Alive(Current Array Element))) * 0.300); + } +} + +rule("Lucio: Reverse Amp") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + If(Is Using Ability 1(Event Player)); + Set Status(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Rooted, 4); + Else; + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 16.250); + End; + Play Effect(All Players(All Teams), Ring Explosion, Is Using Ability 1(Event Player) ? Color(Green) : Color(Yellow), Event Player, + 1); + Wait(0.400, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Hose") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Event Player.Abilities[8] == True; + Ability Resource(Event Player, Button(Primary Fire)) > False; + } + + actions + { + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Facing Direction Of(Event Player), 15, To World, + Cancel Contrary Motion); + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && !Is In Line of Sight(Current Array Element, Event Player, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Up, 8, To World, Cancel Contrary Motion); + Start Damage Over Time(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), + Distance Between(Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS)), Event Player, 1, 15); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Flourish - Damage") +{ + event + { + Player Dealt Damage; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("[Moira] Flourish - Healing") +{ + event + { + Player Dealt Healing; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Heal(Healee, Event Player, Event Healing * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Healee, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("Baptiste: Corrode") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 20); + Wait(0.200, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 12); + } +} + +rule("Baptiste: Breakthrough") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Status(Event Player, Unkillable) == True; + (Event Player.Abilities[12] ? Players On Hero(Hero(Baptiste), Team Of(Event Player)) : Empty Array).Abilities[12] == True; + } + + actions + { + Heal(Event Player, Event Player, 10000); + Set Status(Event Player, Null, Invincible, 0.800); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ashe: Firebourne") +{ + event + { + Player Dealt Damage; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability == Button(Primary Fire); + Has Status(Victim, Burning) == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Null, Burning, 10); + Start Damage Over Time(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Event Player, 10, 15); + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 5); + Wait(0.250, Ignore Condition); + } +} + +rule("Ashe: Taunt") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Damage(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, Burning)), + Event Player, 125); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Frozen, + 0.016); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Stunned, + 2); + } +} + +rule("D.Va: Voltage Grid") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 2, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 5, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 8, 0.500); + Wait(0.300, Ignore Condition); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Wait(0.016, Ignore Condition); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Loop If Condition Is True; + } +} + +rule("D.Va: Shooting Star") +{ + event + { + Player Dealt Knockback; + Team 1; + D.Va; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, 40); + Set Status(Victim, Null, Burning, 3); + Start Damage Over Time(Victim, Event Player, 3, 35); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 1); + } +} + +rule("Genji: Venomous Strike") +{ + event + { + Player Dealt Damage; + Team 1; + Genji; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 3, 25); + Start Damage Over Time(Victim, Event Player, 3, 25); + Damage(Victim, Event Player, 25); + Heal(Event Player, Event Player, 25); + } +} + +rule("Genji: Dragon's Breath") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is Firing Primary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Good Aura, Color(Lime Green), Event Player.Ability_Projectile1, 1, + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 80, Destination and Rate); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True); + Wait Until(Event Player.Ability_End == Event Player.Ability_Projectile1, 1); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Green), Event Player.Ability_Projectile1, 100); + Play Effect(All Players(All Teams), Bad Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Green), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 100); + } +} + +rule("[Hanzo] Stormbreak (Storm_Effects6)") +{ + event + { + Player Died; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[8] == True; + Hero Of(Attacker) == Hero(Hanzo); + } + + actions + { + Event Player.Storm_Projectile = Eye Position(Event Player); + Event Player.Storm_EndPoint = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Up * 12, Null, + All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Storm_Projectile, Event Player.Storm_EndPoint, 4, Destination and Rate); + Create Effect(All Players(All Teams), Cloud, Color(White), Vector(False, -0.500, False) + Event Player.Storm_Projectile, 4, + Visible To Position and Radius); + Event Player.Storm_Effects[3] = Last Created Entity; + Create Effect(All Players(All Teams), Bad Aura, Color(White), Event Player.Storm_Projectile, 3, Visible To Position and Radius); + Event Player.Storm_Effects[4] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(White), Event Player.Storm_Projectile, 3.500, Visible To Position and Radius); + Event Player.Storm_Effects[5] = Last Created Entity; + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Storm_Projectile, Ray Cast Hit Position( + Event Player.Storm_Projectile, Vector(0.100, 0, 0) + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), + False), Color(Aqua), Visible To Position and Radius); + Event Player.Storm_Effects[6] = Last Created Entity; + While(Distance Between(Event Player.Storm_Projectile, Event Player.Storm_EndPoint) > 1); + Wait(0.600, Ignore Condition); + Damage(Players Within Radius(Ray Cast Hit Position(Event Player.Storm_Projectile, Event Player.Storm_Projectile + Down * 1000, + Null, All Players(All Teams), False), 3, Team Of(Event Player), Surfaces), Attacker, 50); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + End; + Destroy Effect(Event Player.Storm_Effects[3]); + Destroy Effect(Event Player.Storm_Effects[4]); + Destroy Effect(Event Player.Storm_Effects[5]); + Destroy Effect(Event Player.Storm_Effects[6]); + } +} + +rule("Hanzo: Punch II") +{ + event + { + Player Dealt Damage; + Team 1; + Hanzo; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + Hero Of(Victim) != Hero(Torbjörn); + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.800); + Apply Impulse(Victim, Facing Direction Of(Event Player), 12, To World, Cancel Contrary Motion); + Apply Impulse(Victim, Up, 5, To World, Cancel Contrary Motion); + Set Environment Credit Player(Victim, Event Player); + Set Status(Victim, Null, Stunned, 1); + } +} + +rule("Widowmaker: Kiss Of Death") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + (Normalized Health(Victim) <= 0.300 || Event Damage >= Normalized Health(Victim) + Event Damage) == True; + Is Firing Secondary(Event Player) == True; + Event Ability == Button(Primary Fire); + Event Player.Abilities[8] == True; + Event Damage >= 40; + Event Was Critical Hit == True; + } + + actions + { + Kill(Victim, Event Player); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 2), Victim, 3); + Damage(Players Within Radius(Victim, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage * 1.500); + } +} + +rule("Widowmaker: Epidemic") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 8); + Play Effect(All Players(All Teams), Good Explosion, Color(Purple), Victim, 4); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Victim, 16); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Victim, 3); + Start Damage Over Time(Players Within Radius(Victim, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, 50); + Start Heal Over Time(Event Player, Event Player, 3, 50); + Wait(0.500, Ignore Condition); + } +} + +rule("McCree: Panic") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Victim.Feared_until = Total Time Elapsed + 3.500; + } +} + +rule("McCree: Panic - Damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), + Event Player.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 220, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("McCree: Clocked") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Damage(Victim, Event Player, Event Damage * 1.500); + Set Status(Victim, Null, Knocked Down, 3); + } +} + +rule("Reinhardt: Fire Blast") +{ + event + { + Player Dealt Damage; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Start Damage Over Time(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, 20); + Set Status(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Burning, 5); + } +} + +rule("Reinhardt: Epicenter") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is On Ground(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, Knocked Down, 2.500); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 10); + Damage(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, 50); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 20); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 30); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 40); + Wait(5, Ignore Condition); + } +} + +rule("[Soldier: 76] Rocket Assault Rifle") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile2 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(-2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Projectile1 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Position = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, + 0), Event Player, Rotation); + Event Player.Ability_End = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, 0), + Event Player, Rotation); + Chase Player Variable At Rate(Event Player, Ability_Position, Event Player.Ability_Projectile1, 60, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_End, Event Player.Ability_Projectile2, 60, Destination and Rate); + Wait Until(Event Player.Ability_Position == 0 && Event Player.Ability_End == 0, 2.500); + } +} + +rule("[Soldier: 76] First Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile1 != Event Player.Ability_Position; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_Position, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_Position, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_Position, 2.500); + Stop Chasing Player Variable(Event Player, Ability_Position); + Wait(0.016, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 80); + Stop Chasing Player Variable(Event Player, Ability_Position); + Event Player.Ability_Position = 0; + Event Player.Ability_Projectile1 = 0; + Wait(0.016, Ignore Condition); + } +} + +rule("[Soldier: 76] Second Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile2 != Event Player.Ability_End; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_End, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_End, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_End, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_End, 2.500); + Stop Chasing Player Variable(Event Player, Ability_End); + Damage(Players Within Radius(Event Player.Ability_End, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Event Player.Ability_End = 0; + Event Player.Ability_Projectile2 = 0; + } +} + +rule("Soldier: 76 - Init rockets") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile1 = Event Player.Ability_Position; + Event Player.Ability_Projectile2 = Event Player.Ability_End; + } +} + +rule("[Soldier: 76] Shoulder Check") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 3; + Is Alive(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) == True; + } + + actions + { + Damage(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Event Player, 55); + Set Status(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Null, Knocked Down, 1.500); + Apply Impulse(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Facing Direction Of(Event Player), 15, + To World, Cancel Contrary Motion); + Apply Impulse(Event Player, Vector(0, 8, 15), 15, To Player, Cancel Contrary Motion); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Closest Player To(Event Player, Opposite Team Of(Team Of( + Event Player))), 1); + Set Ability Cooldown(Event Player, Button(Melee), 0); + Press Button(Event Player, Button(Melee)); + Wait(1, Ignore Condition); + } +} + +rule("Torbjorn: Melting Point") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Event Player.Abilities[8] == True; + (Is Using Ability 2(Event Player) || Is Using Ultimate(Event Player)) == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Event Player, 8); + Play Effect(All Players(All Teams), Bad Explosion, Color(Yellow), Event Player, 8); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 16); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, + 25); + Set Status(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Off), Null, Burning, 3); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player, 100); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Torbjorn: Roots of Magma") +{ + event + { + Player Dealt Damage; + Team 1; + Torbjörn; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Set Status(Victim, Null, Rooted, 1); + Wait(1, Ignore Condition); + } +} + +rule("Tracer: Vortex") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, 0); + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 10); + Play Effect(All Players(All Teams), Ring Explosion, Color(Red), Position Of(Event Player), 24); + Play Effect(All Players(All Teams), Ring Explosion, Color(Yellow), Position Of(Event Player), 18); + Play Effect(All Players(All Teams), Ring Explosion, Color(Green), Position Of(Event Player), 12); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player), 6); + Set Environment Credit Player(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player); + } +} + +rule("Tracer: Vortex 2") +{ + event + { + Player Received Healing; + Team 2; + All; + } + + conditions + { + Healer.Abilities[8] == True; + Hero Of(Healer) == Hero(Tracer); + Is Using Ability 2(Healer) == True; + Event Ability == Null; + Event Damage <= 20; + } + + actions + { + Apply Impulse(Event Player, Up, 5, To World, Cancel Contrary Motion); + Wait(0.100, Ignore Condition); + Apply Impulse(Event Player, Direction Towards(Event Player, Healer), Distance Between(Event Player, Healer) * 3.500, To World, + Cancel Contrary Motion); + Set Status(Event Player, Null, Rooted, 1.300); + } +} + +rule("Tracer: Chain Reaction") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is True For Any(Filtered Array(All Players(Team Of(Event Player)), Current Array Element.Chain_Reaction_On), Distance Between( + Event Player, Current Array Element) <= 8 && True) == True; + Event Player.Chain_Reaction_Immune == False; + Event Player.Chain_Reaction_On == False; + Is Alive(Event Player) == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Event Player.Chain_Reaction_On = True; + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player, 3); + } +} + +rule("Tracer: Chain Reaction 2") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Event Player.Chain_Reaction_On == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Aqua), Event Player, 3); + Damage(Event Player, Players On Hero(Hero(Tracer), Opposite Team Of(Team Of(Event Player))), 200); + Wait(0.500, Ignore Condition); + Event Player.Chain_Reaction_Immune = True; + Event Player.Chain_Reaction_On = False; + Wait(2, Ignore Condition); + Event Player.Chain_Reaction_Immune = False; + } +} + +rule("Tracer: Chain Reaction 3") +{ + event + { + Player Dealt Damage; + Team 1; + Tracer; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Damage > 20; + Event Player.Abilities[12] == True; + } + + actions + { + Victim.Chain_Reaction_On = True; + } +} + +rule("[Winston] Electric Field") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 65); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Orb, Color(White), Event Player.Ability_Projectile1, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Stop Chasing Player Variable(Event Player, Ability_Resource); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Down * 1000, Null, + All Players(All Teams), False); + Wait(0.100, Ignore Condition); + Event Player.Ability_Resource = 5; + Wait(0.250, Ignore Condition); + Chase Player Variable At Rate(Event Player, Ability_Resource, 20, 7, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, Event Player.Ability_Resource, + Destination and Rate); + Wait(8.650, Restart When True); + Event Player.Ability_Active = False; + } +} + +rule("[Winston] Electric Field 2") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 33); + Play Effect(All Players(All Teams), Ring Explosion, Color(Blue), Event Player.Ability_Projectile1, 10); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 80); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Event Player.Ability_Projectile1, 12); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player.Ability_Projectile1, 125); + } +} + +rule("Winston: Next Generation") +{ + event + { + Player Earned Elimination; + Team 1; + Winston; + } + + conditions + { + Ultimate Charge Percent(Event Player) <= 80; + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 15); + } +} + +rule("Pharah: Head Trauma") +{ + event + { + Player Dealt Knockback; + Team 1; + Pharah; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Victim != Event Player; + } + + actions + { + Damage(Victim, Event Player, Max Health(Victim) * 0.300); + Set Status(Victim, Event Player, Knocked Down, 1); + Play Effect(All Players(All Teams), Good Explosion, Color(Team 1), Victim, 1); + } +} + +rule("Pharah: Thunderbird") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[12] == True; + Hero Of(Event Player) == Hero(Pharah); + } + + actions + { + Event Player.DamageDealt *= 4; + Start Damage Modification(All Players(All Teams), Event Player, 25, Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Add Health Pool To Player(Event Player, Shields, 150, True, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(!Event Player.Abilities[12] || Hero Of(Event Player) != Hero(Pharah), 99999); + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Stop Damage Modification(Event Player.Modification_Damage[1]); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + } +} + +rule("Orisa: Unstoppable Force") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Direction = Facing Direction Of(Event Player); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Sphere, Color(Green), Event Player.Ability_Projectile1, 4, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player) + Facing Direction Of(Event Player) * 0.500; + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 100, Null, All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 25, Destination and Rate); + Wait(0.250, Ignore Condition); + Wait Until((!Event Player.Gen_Available && Is Button Held(Event Player, Button(Secondary Fire))) || ( + Event Player.Ability_Projectile1 == Event Player.Ability_End), 99999); + Stop Chasing Player Variable(Event Player, Ability_Projectile1); + Wait(0.500, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, + 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Orisa: Availability for Halt!") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Available = True; + Wait Until(!Is Button Held(Event Player, Button(Secondary Fire)), 99999); + Event Player.Gen_Available = False; + } +} + +rule("Orisa: Drag effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Player.Ability_Active == True; + } + + actions + { + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Is Alive(Event Player) ? Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of( + Event Player)), Surfaces) : Empty Array, Event Player.Ability_Projectile1), 8, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Event Player.Ability_Projectile1, Event Player.Ability_End), 20, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Up, 5, + To Player, Cancel Contrary Motion); + Wait(0.200, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Orisa: Immoveable Object - Reduce dmg") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Damage Received(Event Player, 100 * 0.003); + Wait Until(!Is Using Ability 1(Event Player), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Orisa: Immovable Object - Healing") +{ + event + { + Player Took Damage; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Event Player, Null, Event Damage * 3); + } +} + +rule("[Reaper] Shadow Streak (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Event Player.Ability_Position = Position Of(Event Player) + Vector(0, 1, 0); + Wait(2, Abort When False); + Event Player.Ability_End = Position Of(Event Player) + Vector(0, 1, 0); + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Ability_End, Event Player.Ability_Position, Color(Black), + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player) || Is Using Ability 2(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage start to end (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players(Opposite Team Of(Team Of( + Event Player))), Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_Position, + Event Player.Ability_End, All Living Players(All Teams), Event Player, True), 1); + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage end to start (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Players(Opposite Team Of(Team Of(Event Player))), + Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_End, + Event Player.Ability_Position, All Living Players(All Teams), Event Player, True), 1); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Reaper: Loom") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Hacked, 1.500); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Rooted, 1.500); + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Event Player, 45); + } +} + +rule("Sigma: Gravity Well") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, 25); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Null, Rooted, 2); + Set Status(Event Player, Null, Invincible, 1); + Play Effect(Event Player, Ring Explosion, Color(Blue), Eye Position(Event Player), 50); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Sigma: Gravity Channels") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ultimate(Event Player)), Event Player, 150, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[12], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Echo: Focusing Optics") +{ + event + { + Player Dealt Damage; + Team 1; + Echo; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Normalized Health(Victim) > 0.500; + Normalized Health(Victim) <= 0.900; + Is Duplicating(Event Player) == False; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 3); + Play Effect(All Players(All Teams), Bad Explosion, Color(Violet), Victim, 0.500); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Wait(0.700, Abort When False); + Cancel Primary Action(Event Player); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Set Projectile Speed(Event Player, 100); + Wait(0.150, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Bomblets") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Is In Alternate Form(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Orange), Null + Ray Cast Hit Position(Eye Position(Event Player), + Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, All Living Players(Opposite Team Of(Team Of( + Event Player))), All Players(Team Of(Event Player)), True), 2); + Damage(Players Within Radius(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 2, + Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 12); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Taser - Loop damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is True For Any(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive(Current Array Element) + && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status(Current Array Element, + Phased Out) && Distance Between(Event Player, Current Array Element) <= 25) == True; + Is Alive(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Explosion Sound, Color(White), Event Player.Ability_Player, 80); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Event Player.Ability_Player, 1); + Event Player.Ability_Player = Filtered Array(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive( + Current Array Element) && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status( + Current Array Element, Phased Out) && Distance Between(Event Player, Current Array Element) <= 25); + Damage(Players Within Radius(Event Player.Ability_Player, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 30); + Wait(0.450, Ignore Condition); + Loop If Condition Is True; + Event Player.Ability_Player = Null; + } +} + +rule("Bastion: Taser - Visual beam") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player + Vector(False, 1, False), + Event Player.Ability_Player != Null ? Event Player.Ability_Player : Event Player, Color(Aqua), + Visible To Position Radius and Color); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[12], 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Sombra: Malware") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, + Hacked) || Current Array Element.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 200, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Sombra: Glitch") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Ability_Active = True; + Event Player.Ability_Position = Position Of(Event Player); + Create Effect(All Players(All Teams), Sphere, Color(Purple), Event Player.Ability_Position, 15, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait(8, Ignore Condition); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Sombra: Glitch - Loop") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Ability_Active == True; + } + + actions + { + Set Status(Players Within Radius(Event Player.Ability_Position, 15, Opposite Team Of(Team Of(Event Player)), Off), Null, Hacked, + 0.750); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Mei: Cold Snap") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Event Player, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Is Using Ability 1(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Damage(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Frozen, 2); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Rooted, 2); + Play Effect(All Players(All Teams), Ring Explosion, Color(White), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Sky Blue), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player) + Vector(0, 1, 0), 20); + } +} + +rule("Mei: Icebound") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Aqua), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Set Projectile Speed(Event Player, 200); + Wait Until(!Is Firing Secondary(Event Player), 99999); + Destroy Effect(Event Player.Effects_[2]); + Set Projectile Speed(Event Player, 100); + } +} + +rule("Mei: Icebound - Icicles hit") +{ + event + { + Player Dealt Damage; + Team 1; + Mei; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 1.250); + Set Status(Victim, Null, Frozen, 1); + Set Status(Victim, Null, Rooted, 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Victim, 1); + } +} + +rule("Wrecking Ball: Mirror Ball") +{ + event + { + Player Took Damage; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 4.500, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage); + Wait(0.100, Ignore Condition); + } +} + +rule("Wrecking Ball: Distort") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Set Status(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Hacked, Count Of( + Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces)) * 1.500); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Violet), Position Of(Event Player), 125); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Sound, Color(Purple), Position Of(Event Player), 16); + Play Effect(All Players(All Teams), Explosion Sound, Color(Violet), Position Of(Event Player), 80); + } +} + +rule("Symmetra: High voltage") +{ + event + { + Player Dealt Final Blow; + Team 1; + Symmetra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Victim, 10); + Play Effect(All Players(All Teams), Bad Explosion, Color(Aqua), Victim, 8); + Damage(Players Within Radius(Victim, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 150); + } +} + +rule("Symmetra: Energy Source") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is True For Any(Players On Hero(Hero(Symmetra), Team Of(Event Player)), Is Using Ultimate(Current Array Element) + && Current Array Element.Abilities[12]) == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 1, 40); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Event Player, 0.100); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Junkrat: Pyromania") +{ + event + { + Player Dealt Knockback; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability != Button(Melee); + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 2, 30); + Set Status(Victim, Null, Burning, 2); + } +} + +rule("Junkrat: Short Fused") +{ + event + { + Player Dealt Damage; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + } + + actions + { + Event Player.Ability_Countdown = 4; + While(Event Player.Ability_Countdown > 0); + Event Player.Ability_Countdown -= 1; + Event Player.Ability_Position = Position Of(Victim) + Vector(Random Real(-2, 2), Random Real(-2, 2), Random Real(-2, 2)); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 4); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Position, 4); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 35); + Set Status(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player, Stunned, 0.800); + Wait(0.200, Ignore Condition); + End; + } +} + +rule("Zenyatta: Vigor") +{ + event + { + Player Dealt Healing; + Team 1; + Zenyatta; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Healee, Null, Invincible, 1); + Wait(0.800, Ignore Condition); + } +} + +rule("Zenyatta: Perfect Balance") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Over Time(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 0.750, 200); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player, 24); + Wait(0.600, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Stench") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Violet), Event Player, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Roadhog: Stench effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 8; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 9); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Rusted Anchor") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ability 1(Event Player)), Event Player, 400, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Roadhog: Rusted Anchor - Reset cooldown") +{ + event + { + Player Earned Elimination; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ability 1(Event Player), 3); + Set Ability Cooldown(Event Player, Button(Ability 1), False); + } +} + +rule("Zarya: Augment") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Scaling Barriers(Event Player, 2, True); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5 + 50; + Set Max Health(Event Player, Event Player.PlayerHealth); + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Zarya), 99999); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Stop Scaling Barriers(Event Player); + } +} + +rule("Zarya: Perpetual Energy") +{ + event + { + Player Dealt Knockback; + Team 1; + Zarya; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Event Player.Abilities[12] == True; + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 9999, 15); + Set Status(Victim, Null, Burning, 9999); + } +} + +rule("Doomfist: Phase Shifter") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + (Is Firing Secondary(Event Player) || Is Using Ability 1(Event Player) || Is Using Ability 2(Event Player)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Event Player, Null, Phased Out, 1); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ultimate(Event Player), 99999); + Event Player.Ability_Position = Position Of(Event Player); + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player), 8); + Event Player.Ability_Active = False; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player.Ability_Position, 16); + While(Event Player.Ability_Active == True); + Damage(Players Within Radius(Event Player.Ability_Position, 8, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 34); + Wait(0.235, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[1]); + Destroy Effect(Event Player.Effects_[2]); + } +} + +rule("Team 1 (Perk): Sharpshooter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Global.Perk[0] == True; + Event Ability != Null; + Distance Between(Event Player, Victim) >= 10; + } + + actions + { + Damage(Victim, Event Player, 50 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Perk): Bulletstorm") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.Perk[1] == True; + (Ammo(Event Player, 0) < Max Ammo(Event Player, 0) || Ammo(Event Player, 1) < Max Ammo(Event Player, 1)) == True; + } + + actions + { + Set Ammo(Event Player, 0, 1000); + Set Ammo(Event Player, 1, 1000); + } +} + +rule("Team 1 Challenges") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + If(Global.Perk[2] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[17] = Last Text ID; + End; + If(Global.Perk[0] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[18] = Last Text ID; + End; + If(Global.Perk[1] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[19] = Last Text ID; + End; + If(Global.MaxHealthDone == 50); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + End; + } +} + +rule("Remove Auto Repair when Player leaves") +{ + event + { + Player Left Match; + Team 1; + All; + } + + actions + { + Global.AutoRepair -= Event Player.Abilities[16]; + } +} + +rule("Refund") +{ + event + { + Subroutine; + Refund; + } + + actions + { + "Refund Money" + Event Player.Money[0] += Event Player.Money[1]; + Event Player.Money[1] = 0; + "Reset Headhunter" + Event Player.Abilities[1] = 0; + "Reset Ambush" + Event Player.Abilities[2] = 0; + "Reset QuickFix" + Event Player.Abilities[3] = 0; + "Reset HeavyWeight" + Event Player.Abilities[4] = 0; + "Reset Charged" + Event Player.Abilities[5] = 0; + "Reset Haste" + Event Player.Abilities[6] = 0; + "Reset HeavyImpact" + Event Player.Abilities[7] = 0; + "Reset HeroTalent1" + Event Player.Abilities[8] = 0; + "Reset SecondWind" + Event Player.Abilities[9] = 0; + "Reset BindingHeal" + Event Player.Abilities[10] = 0; + "Reset Resilience" + Event Player.Abilities[11] = 0; + "Reset HeroTalent2" + Event Player.Abilities[12] = 0; + "Reset Damage" + Event Player.Abilities[13] = 0; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + "Reset Health" + Event Player.Abilities[14] = 0; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + If(Global.MaxHealthDone == 0); + End; + "Reset Healing" + Event Player.Abilities[15] = 0; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + "Reset AutoRepair" + Global.AutoRepair -= Event Player.Abilities[16]; + Event Player.Abilities[16] = 0; + } +} + +rule("Lucio Dash HUD Creation") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + } + + actions + { + If(Event Player.Lucio_Dash_Active == False); + Event Player.Lucio_Dash_Active = True; + Create HUD Text(Event Player, Null, Null, Custom String("{0} Slam on ground - Press: {1}", Ability Icon String(Hero(Wrecking Ball), + Button(Crouch)), Input Binding String(Button(Crouch))), Left, 1000, Color(White), Color(White), Color(White), + Visible To and String, Default Visibility); + Event Player.Lucio_Dash_Icon = Last Text ID; + End; + } +} + +rule("Lucio Dash Remove HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) != Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + } + + actions + { + Destroy HUD Text(Event Player.Lucio_Dash_Icon); + Event Player.Lucio_Dash_Active = False; + } +} + +rule("Lucio Dash") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + Is On Ground(Event Player) == False; + Is Button Held(Event Player, Button(Crouch)) == True; + } + + actions + { + Apply Impulse(Event Player, Down, 20, To World, Cancel Contrary Motion); + } +} + +rule("Ana Self-Nano") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + Ultimate Charge Percent(Event Player) == 100; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Abort If(Global.SelfNanoWorkshopSetting == False && Number Of Players(Team 1) > 1); + Wait(0.100, Ignore Condition); + If(Is Using Ultimate(Event Player) == False); + Create Dummy Bot(Hero(Ana), Team Of(Event Player), -1, Position Of(Event Player) + Backward, Eye Position(Event Player)); + Event Player.AnaEntityID = Last Created Entity; + Wait(0.100, Ignore Condition); + Set Ultimate Charge(Event Player.AnaEntityID, 100); + Start Facing(Event Player.AnaEntityID, Direction Towards(Eye Position(Event Player.AnaEntityID), Position Of(Event Player) + Up), + 1000, To World, Direction and Turn Rate); + Set Invisible(Event Player.AnaEntityID, All); + Set Status(Event Player.AnaEntityID, Null, Phased Out, 9999); + Wait(0.150, Ignore Condition); + Press Button(Event Player.AnaEntityID, Button(Ultimate)); + Set Ultimate Charge(Event Player, 0); + Wait(0.150, Ignore Condition); + Teleport(Event Player.AnaEntityID, Position Of(First Of(Spawn Points(Team Of(Event Player))))); + Wait(10, Ignore Condition); + Destroy Dummy Bot(Team Of(Event Player), Slot Of(Event Player.AnaEntityID)); + End; + } +} + +rule("Reinhard Charge Cancel") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + } + + actions + { + Wait(0.600, Ignore Condition); + Wait Until(Is Button Held(Event Player, Button(Ability 1)), 5); + Set Status(Event Player, Null, Rooted, 0.001); + Wait Until(Event Player.ReinPin, 1); + If(Event Player.ReinPin != 0); + Apply Impulse(Event Player.ReinPin, Facing Direction Of(Event Player), 15, To World, Cancel Contrary Motion); + End; + } +} + +disabled rule("Map Editor Walls") +{ + event + { + Ongoing - Global; + } +} + +rule("Initial Global") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Empty Array; + Global.AllDir = Empty Array; + Global.firstpos = Empty Array; + Global.secondpos = Empty Array; + Global.firstpoint2 = Empty Array; + Global.secondpoint2 = Empty Array; + Global.second = Empty Array; + Global.z = Empty Array; + Global.Wall_ID = Empty Array; + Global.g_beamType = Empty Array; + } +} + +rule("Initial Player") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.filterpos = 0; + Event Player.lastsavedpos = 0; + Event Player.closestbodypos = 0; + Event Player.fullbodypos = 0; + Event Player.prevpos_intersection = 0; + Event Player.active_wall = Empty Array; + Event Player.closestwall = Empty Array; + } +} + +rule("Collision Logic") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Event Player.lastsavedpos = (Eye Position(Event Player) + Position Of(Event Player)) / 2; + Wait(0.016, Ignore Condition); + Event Player.closestwall = Filtered Array(Global.AllPos, Distance Between(Global.AllPos[Current Array Index], Event Player) + <= Distance Between(Global.AllPos[Current Array Index], Global.firstpos[Current Array Index]) + || Event Player.active_wall[Current Array Index] == 1 || (Dot Product(Direction Towards(Current Array Element, + Event Player.lastsavedpos), Global.AllDir[Current Array Index]) > 0) != (Dot Product(Direction Towards(Current Array Element, + Event Player), Global.AllDir[Current Array Index]) > 0)); + For Player Variable(Event Player, x, 0, Count Of(Event Player.closestwall), 1); + Global.z = Index Of Array Value(Global.AllPos, Event Player.closestwall[Event Player.x]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3 || Global.Wall_ID[Global.z] == 5); + If(Y Component Of(Global.firstpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.firstpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.firstpos[Global.z]; + Else If(Y Component Of(Global.secondpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.secondpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.secondpos[Global.z]; + Else; + Event Player.closestbodypos = Position Of(Event Player); + End; + Event Player.fullbodypos = Vector(X Component Of(Eye Position(Event Player)), Y Component Of(Event Player.closestbodypos), + Z Component Of(Eye Position(Event Player))); + Event Player.filterpos = Event Player.fullbodypos + Global.AllDir[Global.z] * Dot Product( + Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) / Dot Product(Global.AllDir[Global.z], + Global.AllDir[Global.z]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3); + If((Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.lastsavedpos), Global.AllDir[Global.z]) > 0) != ( + Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.fullbodypos), Global.AllDir[Global.z]) > 0)); + Event Player.intersection_length = Dot Product(Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) + / Dot Product(Direction Towards(Event Player.lastsavedpos, Event Player.fullbodypos), Global.AllDir[Global.z]); + Event Player.prevpos_intersection = Event Player.fullbodypos + Direction Towards(Event Player.lastsavedpos, + Event Player.fullbodypos) * Vector(1, Empty Array, 1) * Event Player.intersection_length; + If(Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of( + Global.firstpos[Global.z]), Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], + Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of( + Global.firstpos[Global.z]), Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), + Direction Towards(Global.firstpos[Global.z], Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards( + Global.secondpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.prevpos_intersection)) + >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.secondpos[Global.z], Event Player.prevpos_intersection)) >= 0); + Cancel Primary Action(Event Player); + Teleport(Event Player, Event Player.prevpos_intersection + Direction Towards(Event Player.prevpos_intersection, + Event Player.lastsavedpos) * Vector(1, Empty Array, 1) * 2); + End; + End; + End; + Event Player.thickness = 0; + If(Global.Wall_ID[Global.z] == 5); + Event Player.thickness = 4; + Else; + Event Player.thickness = 1; + End; + If(Distance Between(Event Player.fullbodypos, Event Player.filterpos) <= Event Player.thickness && Dot Product(Direction Towards( + Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], Event Player.filterpos)) + >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.firstpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector( + X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), Z Component Of( + Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product( + Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), Y Component Of( + Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], + Event Player.filterpos)) >= 0); + If(!Global.is_Grounded); + Set Gravity(Event Player, 100); + End; + If(Event Player.active_wall[Global.z] == False); + Event Player.active_wall[Global.z] = 1; + If((Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3) && Global.is_Grounded == False); + Set Gravity(Event Player, 100); + Else If(Global.Wall_ID[Global.z] == 5); + Disable Movement Collision With Environment(Event Player, False); + End; + End; + If(Global.Wall_ID[Global.z] == 1); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos) * Vector(1, Empty Array, 1), 0.001, + To World, Cancel Contrary Motion); + Set Move Speed(Event Player, 100 - Dot Product(Direction Towards(Eye Position(Event Player), Eye Position(Event Player) + + World Vector Of(Throttle Of(Event Player), Event Player, Rotation)), Direction Towards(Event Player.filterpos, + Event Player.fullbodypos) * -1) * 100); + Else If(Global.Wall_ID[Global.z] == 3); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos), Speed Of(Event Player), To World, + Cancel Contrary Motion); + End; + Else; + Event Player.active_wall[Global.z] = 0; + Set Move Speed(Event Player, 100); + End; + End; + End; + Loop; + } +} + +rule("Reset") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Count Of(Filtered Array(Event Player.active_wall, Current Array Element != 0)) == 0; + } + + actions + { + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("Effect Creation") +{ + event + { + Ongoing - Global; + } + + actions + { + Wait(5, Ignore Condition); + If(Global.showwalls); + For Global Variable(x, 0, Count Of(Global.AllPos), 1); + If(Global.Wall_ID[Global.x] == 5); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Else; + Skip(Array(14, 0, 5, 10)[Index Of Array Value(Array(1, 2, 3), Global.g_beamType[Global.x]) + 1]); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(9); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(4); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + End; + Wait(0.016, Ignore Condition); + End; + End; + } +} + +rule("Wall Data") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Array(Vector(155.968, 12.470, -30.507), Vector(155.962, 12.472, -62.500), Vector(81.153, 6.453, -103.851), Vector( + 69.148, 6.474, -104.548)); + Global.AllDir = Array(Vector(-1, 0, -0.002), Vector(1, 0, -0.001), Vector(0, 0, 1), Vector(0.001, 0, 1)); + Global.firstpos = Array(Vector(155.971, 11.047, -31.771), Vector(155.964, 11.050, -61.229), Vector(79.761, 5.030, -103.852), + Vector(67.738, 5.022, -104.547)); + Global.secondpos = Array(Vector(155.965, 13.894, -29.242), Vector(155.960, 13.894, -63.771), Vector(82.544, 7.876, -103.851), + Vector(70.558, 7.925, -104.550)); + Global.firstpoint2 = Array(Vector(155.971, 13.894, -31.771), Vector(155.964, 13.894, -61.229), Vector(79.761, 7.876, -103.852), + Vector(67.738, 7.925, -104.547)); + Global.secondpoint2 = Array(Vector(155.965, 11.047, -29.242), Vector(155.960, 11.050, -63.771), Vector(82.544, 5.030, -103.851), + Vector(70.558, 5.022, -104.550)); + Global.z = 3; + Global.g_beamType = Array(1, 1, 1, 1); + Global.showwalls = True; + Global.Wall_ID = Array(5, 5, 5, 5); + } +} + +disabled rule("NEW SHOP") +{ + event + { + Ongoing - Global; + } +} + +rule("Setting Shop Position") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.ShopCamPos = 900 * Up; + Global.ShopPosAngle[1] = Direction From Angles(Horizontal Angle From Direction(Forward), Vertical Angle From Direction(Forward) + - 90); + Global.ShopPosAngle[0] = Cross Product(Global.ShopPosAngle[1], Forward); + Global.ShopBasePos = Global.ShopCamPos - 9 * Global.ShopPosAngle[1] + 142 * Forward; + } +} + +rule("Create Shop Buttons") +{ + event + { + Ongoing - Global; + } + + actions + { + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] + 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] - 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Refund"), + Global.ShopBasePos + 45 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 3, Do Not Clip, Visible To, Color(Green), + Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("[{0}] Leave", + Input Binding String(Button(Reload))), Global.ShopBasePos + 45 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 3, + Do Not Clip, Visible To and String, Color(Green), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("{0}$\n", Local Player.Money[0]), + Global.ShopBasePos + 36.500 * Global.ShopPosAngle[1], 3, Do Not Clip, Visible To and String, Color(White), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("▲"), Update Every Frame( + Global.ShopBasePos - (4 + Vertical Facing Angle Of(Local Player)) * Global.ShopPosAngle[1] + Horizontal Facing Angle Of( + Local Player) * Global.ShopPosAngle[0]), 4, Do Not Clip, Visible To Position and Color, Custom Color( + 245 + 10 * Sine From Radians(4 * Total Time Elapsed), 205 + 50 * Sine From Radians(4 * Total Time Elapsed), + 200 * Sine From Radians(4 * Total Time Elapsed), 255), Default Visibility); + "Headhunter" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[1] ? Custom String("Headhunter II\n  800$") : Custom String("Headhunter I\n  800$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[1] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Ambush" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[2] ? Custom String("Ambush II\n 800$") : Custom String("Ambush I\n 800$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[2] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Quick Fix" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[3] ? Custom String("Quick Fix II\n  700$") : Custom String("Quick Fix I\n  700$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[3] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavyweight" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[4] ? Custom String("Heavyweight II\n  1000$") : Custom String("Heavyweight I\n  1000$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[4] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Charged" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[5] ? Custom String("Charged II\n  700$") : Custom String("Charged I\n  700$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[5] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Haste" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[6] ? Custom String("Haste II\n 700$") : Custom String("Haste I\n 700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[6] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavy Impact" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[7] ? Custom String("Heavy Impact II\n  1000$") : Custom String("Heavy Impact I\n  1000$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[7] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 1" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 1\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[8] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "Second Wind" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[9] ? Custom String("Second Wind II\n   900$") : Custom String("Second Wind I\n   900$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[9] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Binding Heal" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[10] ? Custom String("Binding Heal II\n   700$") : Custom String("Binding Heal I\n   700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[10] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Resilience" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[11] ? Custom String("Resilience II\n  800$") : Custom String("Resilience I\n  800$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[11] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 2" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 2\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[12] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "PlusDamage" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Damage\n  400$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealth" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Health\n 400$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Healing\n  400$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, Visible To and String, + Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "+{0} Auto-Repair\n    400$", Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Global.AutoRepair < 5 ? Color(Green) : Color(Gray), Default Visibility); + "Use Update Every Frame to avoid showing the String when the cursor is out of bounds, resulting in 0\r\n ROW 0" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -33.750 ? Array(Custom String("Leave Buy Menu\n"), Custom String( + ""), Custom String(""), Custom String("Refund your money\n"))[Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) + / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, + Color(White), Default Visibility); + "ROW 1" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 22.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -11.250 ? Array(Custom String("Increase your damage by 5%\n"), + Local Player.Abilities[9] ? Custom String( + "Second Wind II: 60% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds") + : Custom String( + "Second Wind I: 30% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds"), + Local Player.Abilities[5] ? Custom String("Charged II: Ultimates cost 40% less\n") : Custom String( + "Charged I: Ultimates cost 20% less\n"), Local Player.Abilities[1] ? Custom String( + "Headhunter II: Critical hits deal 80% more damage\n") : Custom String("Headhunter I: Critical hits deal 40% more damage\n")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 2" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 36.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 11.250 ? Array(Custom String("Increase your health by 5%\n"), + Local Player.Abilities[10] ? Custom String("Binding Heal II: Heal yourself for 50% the amount when healing allies\n") + : Custom String("Binding Heal I: Heal yourself for 25% the amount when healing allies\n"), + Local Player.Abilities[6] ? Custom String( + " Haste II: Ability cooldown is reduced by 50%\nDoes not affect abilities with multiple charges") : Custom String( + " Haste I: Ability cooldown is reduced by 25%\nDoes not affect abilities with multiple charges"), + Local Player.Abilities[2] ? Custom String("Ambush II: Deal 60% more damage when attacking enemies from behind or above\n") + : Custom String("Ambush I: Deal 30% more damage when attacking enemies from behind or above\n"))[Round To Integer(( + Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 3" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 83.750) < 72.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 33.750 ? Array(Custom String("Increase your healing by 5%\n"), + Local Player.Abilities[11] ? Custom String("Resilience II: Take 30% less damage while below 60% health\n") : Custom String( + "Resilience I: Take 30% less damage while below 30% health\n"), Local Player.Abilities[7] ? Custom String( + "Heavy Impact II: Every hit has a chance to stun the enemy for 2 seconds\n") : Custom String( + "Heavy Impact I: Every hit has a chance to stun the enemy for 1 second\n"), Local Player.Abilities[3] ? Custom String( + "Quick Fix II: Eliminations restore 100 HP and shortly increase speed by 40%\n") : Custom String( + "Quick Fix I: Eliminations restore 50 HP and shortly increase speed by 20%\n"))[Round To Integer((Horizontal Facing Angle Of( + Local Player) + 90) / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, + Visible To and String, Color(White), Default Visibility); + "ROW 4" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 133) < 99.250 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 56.250 ? Array(Custom String( + "Increase your auto-repair by {0}/5s\n", Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Custom String("{0}", Local Player.HeroTalentText[2][1]), Custom String("{0}", Local Player.HeroTalentText[1][1]), + Local Player.Abilities[4] ? Custom String( + "Heavyweight II: Your knock back attacks deal 50% more damage and knock back\n            You receive 33% less knock back") + : Custom String( + "Heavyweight I: Your knock back attacks deal 25% more damage and knock back\n            You receive 20% less knock back")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + } +} + +rule("Toggle Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + !Is Dummy Bot(Event Player) == True; + Is Button Held(Event Player, Button(Reload)) == True; + !Is Communicating Any Emote(Event Player) == True; + } + + actions + { + If(Event Player.isInMenu == False); + Wait Until(!Is Button Held(Event Player, Button(Reload)), 0.500); + If(!Is Button Held(Event Player, Button(Reload))); + Abort; + End; + End; + Event Player.isInMenu = !Event Player.isInMenu; + } +} + +rule("Open Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == True; + } + + actions + { + Event Player.PlayerFacing = Facing Direction Of(Event Player); + Start Camera(Event Player, Global.ShopCamPos, Global.ShopCamPos + Forward, 0); + Disable Hero HUD(Event Player); + Call Subroutine(DisablePlayer); + Set Aim Speed(Event Player, 200); + } +} + +rule("Close Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == False; + } + + actions + { + Stop Camera(Event Player); + Enable Hero HUD(Event Player); + Call Subroutine(EnablePlayer); + Set Aim Speed(Event Player, 100); + Set Facing(Event Player, Event Player.PlayerFacing, To World); + } +} + +rule("Subroutine: Disable Player") +{ + event + { + Subroutine; + DisablePlayer; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + Set Primary Fire Enabled(Event Player, False); + Set Secondary Fire Enabled(Event Player, False); + Set Ability 1 Enabled(Event Player, False); + Set Ability 2 Enabled(Event Player, False); + Set Melee Enabled(Event Player, False); + Set Jump Enabled(Event Player, False); + Set Crouch Enabled(Event Player, False); + Disallow Button(Event Player, Button(Ultimate)); + } +} + +rule("Subroutine: Enable Player") +{ + event + { + Subroutine; + EnablePlayer; + } + + actions + { + Stop Forcing Throttle(Event Player); + Set Primary Fire Enabled(Event Player, True); + Set Secondary Fire Enabled(Event Player, True); + Set Ability 1 Enabled(Event Player, True); + Set Ability 2 Enabled(Event Player, True); + Set Melee Enabled(Event Player, True); + Set Jump Enabled(Event Player, True); + Set Crouch Enabled(Event Player, True); + Allow Button(Event Player, Button(Ultimate)); + } +} + +rule("Buy Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Primary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + Event Player.isInMenu = !Event Player.isInMenu; + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Money[1] != 0); + Call Subroutine(Refund); + Else; + Small Message(Local Player, Custom String("You don't have anything to refund!")); + End; + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[13] += 1; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 2); + If(Event Player.Money[0] >= 900); + Event Player.Money[0] -= 900; + Event Player.Money[1] += 900; + Event Player.Abilities[9] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[5] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[1] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[14] += 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[10] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[6] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[2] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[15] += 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[11] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[7] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[3] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Global.AutoRepair != 5); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Global.AutoRepair += 1; + Event Player.Abilities[16] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[12] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[8] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[4] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + End; + } +} + +rule("Refund Single Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Secondary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[13] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[13] -= 1; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 0); + Event Player.Money[0] += 900; + Event Player.Money[1] -= 900; + Event Player.Abilities[9] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[5] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[1] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[14] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[14] -= 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[10] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[6] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[2] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[15] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[15] -= 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[11] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[7] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[3] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[16] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Global.AutoRepair -= 1; + Event Player.Abilities[16] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[12] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[8] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[4] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + End; + } +} + +rule("Create Player HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Custom String("{0}{1}", + Event Player, Event Player.isInMenu ? Custom String("(In Shop)") : Custom String("")), Custom String("{0}{1}", Is Alive( + Event Player) ? Custom String("{0} HP", Round To Integer(Health(Event Player), Up)) : Custom String("Dead"), Custom String( + ", {0}$", Event Player.Money)), Left, Local Player == Event Player ? -1 : Slot Of(Event Player), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), + Visible To Sort Order String and Color, Default Visibility); + Create HUD Text(Event Player.Abilities[13] || Global.DamageDone ? Event Player : Null, Null, Null, Custom String("+{0}% Damage", + Global.DamageDone + Event Player.Abilities[13] * 5), Left, 913, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[9] ? Event Player : Null, Null, Null, Custom String("Second Wind {0}", + Event Player.Abilities[9] == 1 ? Custom String("I") : Custom String("II")), Left, 908, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[5] ? Event Player : Null, Null, Null, Custom String("Charged {0}", + Event Player.Abilities[5] == 1 ? Custom String("I") : Custom String("II")), Left, 905, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[1] ? Event Player : Null, Null, Null, Custom String("Headhunter {0}", + Event Player.Abilities[1] == 1 ? Custom String("I") : Custom String("II")), Left, 901, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[14] || Global.MaxHealthDone ? Event Player : Null, Null, Null, Custom String("+{0}% Health", + Global.MaxHealthDone + Event Player.Abilities[14] * 5), Left, 914, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[10] ? Event Player : Null, Null, Null, Custom String("Binding Heal {0}", + Event Player.Abilities[10] == 1 ? Custom String("I") : Custom String("II")), Left, 909, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[6] ? Event Player : Null, Null, Null, Custom String("Haste {0}", + Event Player.Abilities[6] == 1 ? Custom String("I") : Custom String("II")), Left, 906, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[2] ? Event Player : Null, Null, Null, Custom String("Ambush {0}", + Event Player.Abilities[2] == 1 ? Custom String("I") : Custom String("II")), Left, 902, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[15] ? Event Player : Null, Null, Null, Custom String("+{0}% Healing", + Event Player.Abilities[15] * 5), Left, 915, Color(White), Color(White), Color(Turquoise), Visible To and String, + Default Visibility); + Create HUD Text(Event Player.Abilities[11] ? Event Player : Null, Null, Null, Custom String("Resilience {0}", + Event Player.Abilities[11] == 1 ? Custom String("I") : Custom String("II")), Left, 910, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[7] ? Event Player : Null, Null, Null, Custom String("Heavy Impact {0}", + Event Player.Abilities[7] == 1 ? Custom String("I") : Custom String("II")), Left, 907, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[3] ? Event Player : Null, Null, Null, Custom String("Quick Fix {0}", + Event Player.Abilities[3] == 1 ? Custom String("I") : Custom String("II")), Left, 903, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Global.AutoRepair ? Event Player : Null, Null, Null, Custom String("{0} total Auto-Repair/5s", + Global.AutoRepair * (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5)), Left, 916, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[2][0], Event Player.HeroTalentText[2][1]), Top, 902, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("Hero Talent 2"), Left, 912, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[1][0], Event Player.HeroTalentText[1][1]), Top, 901, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("Hero Talent 1"), Left, 911, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[4] ? Event Player : Null, Null, Null, Custom String("Heavyweight {0}", + Event Player.Abilities[4] == 1 ? Custom String("I") : Custom String("II")), Left, 904, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + } +} + +rule("Rein Pin detect") +{ + event + { + Player Dealt Knockback; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 1); + Has Status(Victim, Stunned) == True; + } + + actions + { + Event Player.ReinPin = Victim; + Wait(1, Ignore Condition); + Event Player.ReinPin = Null; + } +} + +rule("Boss Rotation") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.activeBoss == True; + } + + actions + { + If(Global.bossRotation == 0 || Global.bossRotation == 3); + Global.bossRotation = 1; + Global.lastBoss[1] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 1); + Global.bossRotation = 2; + Global.lastBoss[2] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 2); + Global.bossRotation = 3; + Global.lastBoss[3] = Hero Of(Global.activeBoss); + End; + } +} + +rule("15 minutes hud") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 10; + } + + actions + { + Create HUD Text(All Players(Team 1), Global.activeBoss ? Custom String("Boss: {0}, HP: {1}/{2}", Hero Of(Global.activeBoss), + Health(Global.activeBoss), Max Health(Global.activeBoss)) : Custom String(""), Null, Null, Top, 900, Color(Red), Color(White), + Color(White), Visible To and String, Default Visibility); + } +} + +rule("debug") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + (Is Button Held(Event Player, Button(Primary Fire)) && Is Button Held(Event Player, Button(Crouch))) == True; + } + + actions + { + Global.TimeSec = 59; + } +} + +disabled rule("debug") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + } + + actions + { + Create HUD Text(Local Player, Custom String("{0}", Position Of(Local Player)), Null, Null, Left, 0, Color(Yellow), Color(White), + Color(White), Visible To and String, Default Visibility); + Set Status(Event Player, Null, Invincible, 9999); + Set Status(Event Player, Null, Phased Out, 9999); + } +} + +rule("ending 1 part 1") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + } + + actions + { + Big Message(All Players(Team 1), Custom String("Exfiltration available! (optional - ends the mode)")); + Create In-World Text(All Players(Team 1), Custom String( + "Exfiltration available! Gather here!\n{0}/{1} Players ready to exfiltrate!", Count Of(Filtered Array(All Players(Team 1), + Distance Between(Vector(186, 11, -46.500), Current Array Element) <= 9)), Count Of(All Players(Team 1))), Vector(186, 15, + -46.500), 1.200, Do Not Clip, Visible To and String, Color(Green), Default Visibility); + } +} + +rule("ending 1 part 2") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + Distance Between(Vector(186, 11, -46.500), All Players(Team 1)) <= 9; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GG! YOU DID IT!")); + Destroy All Dummy Bots; + Disable Movement Collision With Environment(All Players(Team 1), True); + Start Accelerating(All Players(Team 1), Up, 100, 5, To World, Direction Rate and Max Speed); + Wait(5, Ignore Condition); + Declare Team Victory(Team 1); + } +} + +rule("Team 1 (Ability): Second Wind save life") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[9] == True; + Event Player.secondWindActive == True; + Health(Event Player) == 1; + } + + actions + { + Small Message(All Players(All Teams), Custom String("{0} received a second wind!", Event Player)); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Green), Event Player, 1); + Clear Status(Event Player, Unkillable); + Set Player Health(Event Player, Max Health(Event Player)); + Event Player.lastSecondWind = 30; + Event Player.secondWindActive = 0; + } +} + +rule("Team 1 (Ability): Second Wind after buying") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[9] == True; + Event Player.secondWindActive == False; + Event Player.lastSecondWind == 0; + } + + actions + { + If(Random Integer(1, 100) > Event Player.Abilities[9] * 30); + Wait(30, Ignore Condition); + Loop; + End; + Set Status(Event Player, Null, Unkillable, 9999); + Event Player.secondWindActive = 1; + } +} + +rule("Team 1 (Ability): Second Wind counter") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Player.lastSecondWind > 0; + } + + actions + { + Wait(1, Ignore Condition); + Event Player.lastSecondWind -= 1; + Loop If Condition Is True; + } +} \ No newline at end of file diff --git a/defendTheCastleExtended/old_versions/c124.ow b/defendTheCastleExtended/old_versions/c124.ow new file mode 100644 index 0000000..ff527b7 --- /dev/null +++ b/defendTheCastleExtended/old_versions/c124.ow @@ -0,0 +1,9331 @@ +settings +{ + main + { + Description: "Defend The Castle Extended v0.6.c124\nby ShuriZma#2349\nJ1K6F (Code Version: c123)\nOriginal mode by HuKuTa94#2589\n\nDefend the gate, kill enemies and don't allow them to damage the gate!\n\nSpecial Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents\n& Josbird for teaching me about Menus!\n\nFind this mode on: workshop.codes/defend-the-castle\nFind the Original Mode on: workshop.codes/BQEGS\nTell me what you think on Discord: discord.shurizma.de\n\nPS: SHINGEN PLS COME BACK" + Mode Name: "Defend The Castle Extended" + } + + lobby + { + Max Spectators: 0 + Max Team 1 Players: 4 + Max Team 2 Players: 0 + Return To Lobby: Never + Swap Teams After Match: No + } + + modes + { + Escort + { + enabled maps + { + Havana + } + } + + Team Deathmatch + { + enabled maps + { + } + } + + General + { + Game Mode Start: Immediately + Spawn Health Packs: Disabled + } + } + + workshop + { + Ana can nano herself even if there are other players only if no player targeted: On + Story Heroes: Off + } + + extensions + { + Beam Effects + Kinetic Explosion Effects + Explosion Sounds + Play More Effects + Spawn More Dummy Bots + } +} + +variables +{ + global: + 0: GatePosition + 1: ZenSpawnPositions + 2: SpawnPositionMaxId + 3: LoopIterator1 + 4: BigBossSpawnPositions + 5: PlayerSpawnPositions + 6: GateHealthChase + 7: GateHealth + 8: GateMaxHealth + 9: GateProgressBarColorCurrent + 10: GateProgressBarColorComponent + 11: GateHealthEvent + 12: BastionTargetPositions + 13: SniperPositions + 14: BallSpawnPositions + 15: ZenRespawnTime + 16: TimeMin + 17: TimeSec + 18: DefaultCurrentBot + 19: DefaultHeroBotsPool + 20: DefaultHeroBotsPoolCurrentId + 21: IsDebug + 22: BotOrisaParent + 23: IsStoryHeroes + 24: BotOrisaChild + 25: GateRepairPosition + 26: BotOrisaTargetPosition + 27: BotEchoRespawnPosition + 28: BotEchoTeleportPositions + 29: UpgradeGateMaxHealthValue + 30: UpgradeGateMaxHealthHudId + 31: UpgradePlayerMaxHealthValue + 32: UpgradePlayerMaxHealthHudId + 33: UpgradeCriticalDamageValue + 34: UpgradeCriticalDamageHudId + 35: UpgradeMaxAmmoValue + 36: UpgradeMaxAmmoHudId + 37: UpgradeMaxAmmoMaxValue + 38: UpgradePlayerMaxHealthMaxValue + 39: UpgradeCriticalDamageMaxValue + 40: UpgradeGateMaxHealthMaxValue + 41: DamageDone + 42: IsDebugAINavigation + 43: GameLogicCountOfUniqueHeroes + 44: IsNewWaveGameLogicProcessing + 45: AutoRepair + 46: UpgradePerkSharpshooterValue + 47: Perk + 48: MaxHealthDone + 49: StartMoney + 50: Time5Min + 51: SelfNanoWorkshopSetting + 52: ShopCamPos + 53: ShopBasePos + 54: ShopPosAngle + 55: activeBoss + 56: bossTrigger + 57: bossRotation + 58: lastBoss + 59: Time10Min + 60: MoneyMult + 61: challengeCount + 62: UpgradeBossHealthValue + 63: GlobalHuds + 112: AllPos + 113: AllDir + 114: firstpos + 115: secondpos + 116: firstpoint2 + 117: secondpoint2 + 118: second + 119: z + 120: Wall_ID + 121: showwalls + 122: is_Grounded + 123: g_beamType + 124: x + 125: NodePositions + 126: NodeConnections + 127: DistanceMatrix + + player: + 0: BotSeePlayer + 1: BotDoesUniqueBehaviour + 2: BotEffects + 3: BotRayCastHitPosition + 4: BotEventPosition + 5: CurrentHero + 6: IsDead + 7: IsRespawning + 8: BotBastionArtilleryDidShotsCount + 9: BotCounter + 10: HasBadStatus + 11: EventHealth + 12: HealOverTimeId + 13: BotIsOrisaChild + 14: BotEchoCapturedPlayer + 15: BotPlayersInRadius + 16: BotLoopIterator2 + 17: BotWidowShotTime + 18: BotWidowTeleportTime + 19: IsNanoed + 20: AbilityHUD + 21: Lucio_Dash_Active + 22: Lucio_Dash_Icon + 23: AnaEntityID + 24: Abilities + 25: Money + 26: HeroTalentText + 27: DamageDealt + 28: PlayerHealth + 29: AbilityCountdown + 30: HP_Pool + 31: Effects_ + 32: Ability_Projectile1 + 33: Ability_End + 34: Storm_Projectile + 35: Storm_EndPoint + 36: Storm_Effects + 37: Feared_until + 38: Modification_Damage + 39: Ability_Projectile2 + 40: Ability_Position + 41: Chain_Reaction_On + 42: Chain_Reaction_Immune + 43: Ability_Active + 44: Ability_Resource + 45: secondWindActive + 46: isInMenu + 47: ReinPin + 48: PlayerFacing + 49: isBoss + 50: Gen_Direction + 51: Gen_Available + 52: Ability_Player + 53: Ability_Countdown + 54: lastSecondWind + 55: deathPosition + 105: filterpos + 106: lastsavedpos + 107: closestbodypos + 108: fullbodypos + 109: prevpos_intersection + 110: active_wall + 111: closestwall + 112: x + 113: intersection_length + 114: thickness + 115: BotCancelPathFinding + 116: BotLoopIterator1 + 117: BotTempArray + 118: BotTargetPlayer + 119: BotTargetPosition + 120: BotClosestNodeIdToTarget + 121: BotClosestNodeIdToBot + 122: BotPrevNodeId + 123: BotNextNodeId + 124: BotNextNodePosition + 125: BotCurrentDistanceToTarget + 126: BotShortestDistanceToTarget + 127: BotIsPathFinding +} + +subroutines +{ + 0: BotBastionArtilleryDamage + 1: BotBastionFlameGunDamage + 2: BotBastionRespawn + 3: GateProgressBarColor + 4: BotZenyattaRespawn + 5: BotWidowRespawn + 6: BotBallRespawn + 7: GameLogicAddNextHeroInGame + 8: BotOrisaRespawn + 9: BotLandingFromSky + 10: BotEchoRespawn + 11: BotEchoDetachPlayer + 12: BotEchoFlyToPlayer + 13: BotEchoFlyToPortal + 14: GameLogicSetBotProperties + 15: DisablePlayer + 16: BotApearFromUnderground + 17: BotReinRespawn + 18: PlayerInit + 19: BotInit + 20: PlayerRespawn + 21: BotRespawn + 22: BotWidowBadStatus + 23: GameLogicWave0 + 24: Refund + 25: EnablePlayer + 26: GateRepair + 124: BotStartPathFinding + 125: BotGetClosestNodeIdToTarget + 126: BotGetNextNodeIdAndPosition + 127: BotResetPathFinding +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("MAP: HAVANA") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Havana); + } + + actions + { + Global.NodePositions = Array(Vector(147.588, 6.425, -46.749), Vector(136.181, 6.425, -57.159), Vector(130.189, 6.425, -63.781), + Vector(123.305, 6.425, -57.983), Vector(125.678, 6.504, -46.633), Vector(114.485, 7.471, -46.699), Vector(138.743, 6.425, + -32.974), Vector(126.498, 6.425, -39.920), Vector(124.572, 10.434, -34.300), Vector(138.605, 5.359, -18.647), Vector(119.009, + 2.331, -31.024), Vector(121.138, 5.228, -19.933), Vector(126.722, 6.425, -29.505), Vector(102.762, 3.157, -33.609), Vector( + 76.030, 7.418, -74.087), Vector(83.720, 9.425, -33.744), Vector(97.439, 7.238, -42.379), Vector(86.252, 12.416, -47.261), + Vector(65.178, 11.425, -73.187), Vector(97.466, 7.269, -50.596), Vector(113.039, 7.424, -37.337), Vector(106.179, 7.450, + -46.143), Vector(90.086, 7.411, -44.653), Vector(78.752, 7.418, -62.140), Vector(82.124, 7.428, -44.229), Vector(90.675, 7.231, + -51.234), Vector(85.717, 4.692, -63.446), Vector(90.830, 4.330, -70.697), Vector(102.425, 2.387, -72.817), Vector(81.443, + 4.425, -81.648), Vector(70.743, 6.418, -81.495), Vector(69.738, 6.419, -96.344), Vector(127.586, 12.643, -63.344), Vector( + 118.911, 13.468, -58.008), Vector(102.885, 1.092, -56.579), Vector(100.009, 2.967, -67.139), Vector(106.703, 0.465, -44.628), + Vector(81.695, 7.418, -52.140), Vector(126.979, 12.393, -55.079), Vector(153.720, 18.578, -21.745), Vector(155.301, 18.619, + -17.595), Vector(133.043, 10.425, -26.625), Vector(114.646, 7.278, -57.336), Vector(95.160, 3.688, -81.194), Vector(78.456, + 5.418, -93.581), Vector(75.455, 5.418, -101.492), Vector(148.071, 9.432, -32.123), Vector(146.706, 9.425, -27.858), Vector( + 144.273, 9.445, -63.119), Vector(144.278, 9.454, -58.447)); + Global.NodeConnections = Array(Array(1, 6, 4, 7), Array(2, 1, 4, 6, 7, 0, 49), Array(1, 3), Array(2, 4, 42), Array(3, 1, 5, 7, 6, + 1, 0), Array(4, 7, 20, 21, 19, 16, 42), Array(7, 1, 4, 1, 9, 12, 0, 46), Array(4, 5, 6, 1, 1, 12, 0), Array(7, 41), Array(6, + 11), Array(11, 13), Array(9, 10, 13), Array(6, 7, 10), Array(10, 16, 36), Array(18, 23, 30), Array(17, 24), Array(13, 19, 22, + 21, 25, 5), Array(15, 22, 25, 23), Array(14), Array(16, 21, 22, 26, 27, 35, 25, 5), Array(5, 13, 10), Array(19, 16, 5, 13, 22, + 34), Array(16, 19, 21, 24, 25), Array(14, 25, 26, 37), Array(22, 15, 37), Array(23, 22, 19, 16, 26, 27, 35, 37), Array(25, 19, + 27, 35, 29), Array(19, 26, 25, 29, 35, 43), Array(35, 34, 43), Array(27, 26, 30, 43, 44), Array(29, 14, 31), Array(30, 29, 45), + Array(33, 38, 1, 48), Array(32, 38, 42), Array(35, 36, 28), Array(28, 19, 25, 27, 26, 34), Array(13, 34), Array(25, 23, 24), + Array(5, 4, 1, 6, 1, 32, 33, 0), Array(40), Array(39), Array(6, 8, 47, 46), Array(3, 5, 34), Array(28, 27, 29, 44), Array(29, + 43, 45), Array(44, 31), Array(6, 47), Array(46, 41), Array(49, 32), Array(1, 0, 6, 48)); + Global.DistanceMatrix = Array(Array(0, 1, 2, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, + 4, 5, 4, 4, 5, 5, 5, 0, 0, 4, 3, 5, 6, 7, 2, 3, 3, 2), Array(1, 0, 1, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, + 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 3, 4, 4, 4, 5, 5, 4, 0, 0, 4, 3, 5, 6, 7, 2, 3, 2, 1), Array(2, 1, 0, 1, 2, 3, 2, 2, 6, 3, 4, 4, + 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 4, 6, 7, 8, 4, 5, 3, 4, 4, 6, 5, 0, 0, 5, 2, 5, 6, 7, 3, 4, 3, 2), Array(2, 2, + 1, 0, 1, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, 5, 6, 2, 3, 3, 5, 6, 0, 0, 5, 1, 4, + 5, 6, 3, 4, 4, 3), Array(1, 1, 2, 1, 0, 1, 1, 1, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, + 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, 2, 3, 3, 2), Array(2, 2, 3, 2, 1, 0, 2, 1, 6, 3, 2, 3, 2, 2, 4, 4, 1, 5, 5, 1, 1, 1, 2, 3, + 3, 2, 2, 2, 3, 3, 4, 5, 5, 6, 2, 2, 3, 3, 6, 0, 0, 5, 1, 3, 4, 5, 3, 4, 4, 3), Array(1, 1, 2, 2, 1, 2, 0, 1, 4, 1, 2, 2, 1, 3, + 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 4, 5, 4, 4, 4, 5, 5, 0, 0, 3, 3, 5, 6, 7, 1, 2, 3, 2), Array(1, 1, 2, 2, + 1, 1, 1, 0, 5, 2, 2, 3, 1, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, + 2, 3, 3, 2), Array(2, 2, 3, 3, 2, 2, 2, 1, 0, 3, 3, 4, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, + 5, 5, 6, 0, 0, 1, 3, 5, 6, 7, 2, 2, 4, 3), Array(2, 2, 3, 3, 2, 3, 1, 2, 5, 0, 2, 1, 2, 2, 6, 6, 3, 7, 7, 4, 4, 4, 4, 5, 5, 4, + 5, 5, 5, 6, 7, 8, 5, 6, 4, 5, 3, 5, 6, 0, 0, 4, 4, 6, 7, 8, 2, 3, 4, 3), Array(4, 4, 5, 5, 4, 3, 3, 4, 7, 2, 0, 1, 4, 1, 5, 5, + 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 7, 8, 3, 4, 2, 4, 8, 0, 0, 6, 4, 5, 6, 7, 4, 5, 6, 5), Array(3, 3, 4, 4, 3, 3, + 2, 3, 6, 1, 1, 0, 3, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 6, 7, 3, 4, 2, 4, 7, 0, 0, 5, 4, 5, 6, 7, 3, 4, + 5, 4), Array(2, 2, 3, 3, 2, 2, 1, 1, 5, 2, 1, 2, 0, 2, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, 3, 5, + 6, 0, 0, 4, 3, 5, 6, 7, 2, 3, 4, 3), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 3, 1, 2, 4, 0, 4, 4, 1, 5, 5, 2, 3, 2, 2, 3, 3, 2, 3, 3, + 3, 4, 5, 6, 7, 8, 2, 3, 1, 3, 8, 0, 0, 7, 3, 4, 5, 6, 5, 6, 6, 5), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 5, 6, 6, 4, 0, 4, 3, 5, + 1, 3, 5, 4, 3, 1, 3, 2, 2, 3, 4, 2, 1, 2, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 3, 3, 3, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, + 5, 10, 7, 5, 6, 6, 4, 3, 0, 3, 1, 4, 3, 5, 3, 2, 2, 1, 2, 3, 3, 4, 4, 4, 5, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 4, 5, 6, 7, 8, + 8, 7), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 3, 3, 0, 4, 4, 1, 2, 1, 1, 2, 2, 1, 2, 2, 3, 3, 4, 5, 6, 7, 2, 2, 2, 2, + 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 1, 2, 0, 3, 2, 4, 2, 1, 1, 2, 1, 2, 2, + 3, 3, 3, 4, 8, 9, 3, 2, 4, 2, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 6, 7, 7, 5, 1, 5, 4, 6, + 0, 4, 6, 5, 4, 2, 4, 3, 3, 4, 5, 3, 2, 3, 10, 11, 5, 4, 6, 3, 11, 0, 0, 10, 6, 4, 4, 4, 8, 9, 9, 8), Array(3, 3, 4, 3, 2, 1, 3, + 2, 7, 4, 3, 4, 3, 2, 3, 3, 1, 4, 4, 0, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 3, 4, 6, 7, 2, 1, 3, 2, 7, 0, 0, 6, 2, 2, 3, 4, 4, 5, 5, + 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 3, 1, 2, 3, 1, 5, 5, 2, 6, 6, 2, 0, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 6, 7, 3, 3, 2, 4, 7, + 0, 0, 6, 2, 4, 5, 6, 4, 5, 5, 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 4, 3, 1, 4, 5, 1, 2, 0, 1, 3, 2, 2, 2, 2, 2, + 3, 4, 5, 6, 7, 1, 2, 2, 3, 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 3, 2, 1, 3, 4, + 1, 3, 1, 0, 2, 1, 1, 2, 2, 3, 3, 4, 5, 7, 8, 2, 2, 3, 2, 8, 0, 0, 7, 3, 3, 4, 5, 5, 6, 6, 5), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, + 6, 4, 5, 5, 3, 1, 3, 2, 4, 2, 2, 4, 3, 2, 0, 2, 1, 1, 2, 3, 2, 2, 3, 8, 9, 3, 2, 4, 1, 9, 0, 0, 8, 4, 3, 3, 4, 6, 7, 7, 6), + Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 3, 1, 2, 2, 4, 2, 4, 2, 1, 2, 0, 2, 3, 3, 4, 4, 4, 5, 8, 9, 3, 3, 4, 1, 9, 0, + 0, 8, 4, 4, 5, 6, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 2, 3, 1, 4, 3, 1, 3, 2, 1, 1, 2, 0, 1, 1, 2, 2, + 3, 4, 7, 8, 2, 1, 3, 1, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, + 3, 2, 2, 2, 3, 1, 0, 1, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 2, 2, 3, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, + 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 0, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 1, 2, 3, 5, 6, 6, 5), Array( + 5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 4, 5, 3, 6, 5, 2, 4, 3, 3, 3, 4, 2, 2, 2, 0, 2, 3, 4, 8, 9, 1, 1, 2, 3, 9, 0, 0, 8, + 4, 1, 2, 3, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 2, 5, 3, 6, 3, 2, 4, 3, 3, 3, 4, 2, 1, 1, 2, 0, 1, 2, + 8, 9, 3, 2, 4, 3, 9, 0, 0, 8, 4, 1, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 1, 5, 4, 6, 2, 3, 5, 4, + 4, 2, 4, 3, 2, 2, 3, 1, 0, 1, 9, 10, 4, 3, 5, 3, 10, 0, 0, 9, 5, 2, 2, 2, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, + 7, 6, 5, 2, 6, 4, 7, 3, 3, 5, 4, 4, 3, 5, 3, 2, 2, 3, 1, 1, 0, 9, 10, 4, 3, 5, 4, 10, 0, 0, 9, 5, 2, 2, 1, 7, 8, 8, 7), Array( + 2, 1, 2, 3, 2, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 4, 5, 6, 7, 0, 1, 3, 4, 4, 5, 1, 0, 0, 5, + 2, 5, 6, 7, 3, 4, 1, 2), Array(2, 2, 3, 2, 2, 2, 2, 3, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, + 1, 0, 2, 3, 3, 5, 1, 0, 0, 5, 1, 4, 5, 6, 3, 4, 2, 3), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 5, 3, 4, 5, 2, 4, 5, 3, 6, 5, 2, 4, 3, + 3, 3, 4, 2, 2, 2, 1, 3, 4, 5, 8, 9, 0, 1, 1, 3, 9, 0, 0, 8, 4, 2, 3, 4, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, + 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 1, 1, 2, 3, 4, 7, 8, 1, 0, 2, 2, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(5, 5, + 6, 5, 4, 3, 5, 4, 9, 4, 2, 3, 5, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 8, 9, 1, 2, 0, 4, 9, 0, 0, 8, 4, 3, + 4, 5, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 2, 2, 3, 3, 2, 4, 3, 2, 1, 1, 1, 2, 2, 3, 3, 3, 4, 8, 9, + 3, 2, 4, 0, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(1, 1, 2, 2, 1, 1, 1, 2, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, + 4, 3, 3, 3, 4, 4, 5, 6, 1, 1, 3, 3, 4, 4, 0, 0, 0, 4, 2, 4, 5, 6, 2, 3, 2, 2), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(2, 2, 3, 3, 2, 3, 1, 2, 1, 2, 3, 3, 2, + 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 0, 4, 6, 7, 8, 1, 1, 4, 3), Array(3, 3, 2, + 1, 2, 1, 3, 2, 7, 4, 3, 4, 3, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 6, 7, 1, 2, 2, 4, 7, 0, 0, 6, 0, 3, 4, + 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 3, 5, 3, 6, 4, 2, 4, 3, 3, 3, 4, 2, 2, 1, 1, 1, 2, 3, 8, 9, 2, + 2, 3, 3, 9, 0, 0, 8, 4, 0, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 3, 6, 4, 7, 4, 3, 5, 4, 4, 4, 5, + 3, 2, 2, 2, 1, 2, 2, 9, 10, 3, 3, 4, 4, 10, 0, 0, 9, 5, 1, 0, 1, 7, 8, 8, 7), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 7, 8, 7, 6, + 3, 7, 5, 8, 4, 4, 6, 5, 5, 4, 6, 4, 3, 3, 3, 2, 2, 1, 10, 11, 4, 4, 5, 5, 11, 0, 0, 10, 6, 2, 1, 0, 8, 9, 9, 8), Array(2, 2, 3, + 3, 2, 3, 1, 2, 3, 2, 3, 3, 2, 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 2, 4, 6, 7, + 8, 0, 1, 4, 3), Array(3, 3, 4, 4, 3, 4, 2, 3, 2, 3, 4, 4, 3, 5, 8, 8, 5, 9, 9, 5, 5, 5, 6, 7, 7, 6, 6, 6, 7, 7, 8, 9, 6, 7, 6, + 6, 6, 7, 7, 0, 0, 1, 5, 7, 8, 9, 1, 0, 5, 4), Array(2, 2, 3, 4, 3, 3, 2, 3, 6, 3, 4, 4, 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, + 5, 5, 5, 5, 6, 7, 8, 1, 2, 4, 5, 5, 6, 2, 0, 0, 5, 3, 6, 7, 8, 3, 4, 0, 1), Array(1, 1, 2, 3, 2, 3, 1, 2, 5, 2, 3, 3, 2, 4, 7, + 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 2, 3, 5, 5, 5, 6, 3, 0, 0, 4, 4, 6, 7, 8, 2, 3, 1)); + } +} + +rule("SUBROUTINE: BOT - RESET PATH FINDING") +{ + event + { + Subroutine; + BotResetPathFinding; + } + + actions + { + Event Player.BotTargetPlayer = -1; + Event Player.BotTargetPosition = -1; + Event Player.BotPrevNodeId = -1; + Event Player.BotClosestNodeIdToTarget = -1; + Event Player.BotNextNodeId = -1; + Event Player.BotNextNodePosition = -1; + Event Player.BotIsPathFinding = False; + Event Player.BotCancelPathFinding = False; + Stop Throttle In Direction(Event Player); + disabled Stop Facing(Event Player); + } +} + +rule("SUBROUTINE: BOT - START PATH FINDING") +{ + event + { + Subroutine; + BotStartPathFinding; + } + + actions + { + disabled Abort If(Event Player.BotIsPathFinding == True); + Call Subroutine(BotGetNextNodeIdAndPosition); + disabled Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Event Player.BotIsPathFinding = True; + } +} + +rule("SUBROUTINE: BOT - GET NEXT NODE ID AND POSITION") +{ + event + { + Subroutine; + BotGetNextNodeIdAndPosition; + } + + actions + { + "BOT JUST START FOLLOW PATH OR LOST NEXT NODE" + If(Event Player.BotPrevNodeId == -1); + Event Player.BotClosestNodeIdToBot = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array(Global.NodePositions, + Is In Line of Sight(Position Of(Event Player) + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS) == True), + Distance Between(Position Of(Event Player), Current Array Element))[0]); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + "NEXT NODE IS TARGET (DISTANCE TO TARGET NODE = 1)" + If(Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1); + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToTarget; + "CHECK CONNECTIONS OF REACHED NODE" + Else; + Event Player.BotShortestDistanceToTarget = 999; + Event Player.BotCurrentDistanceToTarget = Event Player.BotShortestDistanceToTarget; + Event Player.BotTempArray = Global.NodeConnections[Event Player.BotClosestNodeIdToBot]; + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotTempArray), 1); + Event Player.BotCurrentDistanceToTarget = Global.DistanceMatrix[Event Player.BotTempArray[Event Player.BotLoopIterator1]][Event Player.BotClosestNodeIdToTarget]; + If(Event Player.BotCurrentDistanceToTarget < Event Player.BotShortestDistanceToTarget); + Event Player.BotShortestDistanceToTarget = Event Player.BotCurrentDistanceToTarget; + Event Player.BotNextNodeId = Event Player.BotTempArray[Event Player.BotLoopIterator1]; + End; + End; + End; + "NEXT NODE IS HIGHER THAN BOT AND BOT DIDN'T REACH CLOSEST NODE" + If(Y Component Of(Position Of(Event Player)) - Y Component Of(Global.NodePositions[Event Player.BotNextNodeId]) + < -3 && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + "BOT CAN SEE TARGET POSITION AND NEXT NODE IS TARGET" + Else If( + Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1 && Is In Line of Sight( + Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotTargetPosition + Vector(0, 2, 0), Barriers Do Not Block LOS)); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Abort; + "BOT CAN'T SEE NEXT NODE AND PREV NODE != REACHED NODE" + Else If(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), + Global.NodePositions[Event Player.BotNextNodeId] + Vector(0, 2, 0), Barriers Do Not Block LOS) + == False && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + End; + Event Player.BotNextNodePosition = Global.NodePositions[Event Player.BotNextNodeId]; + } +} + +rule("SUBROUTINE: BOT - GET CLOSEST NODE ID AND POSITION TO TARGET") +{ + event + { + Subroutine; + BotGetClosestNodeIdToTarget; + } + + actions + { + Event Player.BotTargetPosition = Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Event Player.BotTargetPosition; + Event Player.BotClosestNodeIdToTarget = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array( + Global.NodePositions, Is In Line of Sight(Event Player.BotTargetPosition + Vector(0, 2, 0), Current Array Element, + Barriers Do Not Block LOS) == True), Distance Between(Event Player.BotTargetPosition, Current Array Element))[0]); + } +} + +rule("BOT: PATH FINDING - START") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + (Event Player.BotTargetPosition != -1 || Event Player.BotTargetPlayer != -1) == True; + } + + actions + { + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - CANCEL") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotCancelPathFinding == True; + } + + actions + { + Start Rule(BotResetPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - LOST THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + (Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotNextNodePosition + Vector(0, 2.500, 0), + Barriers Do Not Block LOS) == False && Speed Of In Direction(Event Player, Throttle Of(Event Player)) < 2) == True; + } + + actions + { + Wait(0.500, Abort When False); + "RESET PREV NODE ID TO INFORM BOT THAT IT LOST NEXT NODE" + Event Player.BotPrevNodeId = -1; + "TRY FIND NEW NEXT NODE" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodeId), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +rule("BOT: PATH FINDING - REACHED THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotClosestNodeIdToTarget >= 0; + (Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotNextNodePosition), 0, Z Component Of(Event Player.BotNextNodePosition))) < 0.850) == True; + } + + actions + { + Event Player.BotPrevNodeId = Event Player.BotNextNodeId; + Event Player.BotClosestNodeIdToBot = Event Player.BotNextNodeId; + "BOT'S TARGET IS PLAYER" + If(Event Player.BotTargetPlayer != -1); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + Event Player.BotCurrentDistanceToTarget = Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of( + Position Of(Event Player))), Vector(X Component Of(Event Player.BotTargetPosition), 0, Z Component Of( + Event Player.BotTargetPosition))); + "BOT REACHED THE TARGET NODE OR TARGET POSITION" + If(Event Player.BotNextNodeId == Event Player.BotClosestNodeIdToTarget || Event Player.BotCurrentDistanceToTarget <= 0.850); + "BOT DIDN'T REACH TARGET POSITION" + If(Event Player.BotCurrentDistanceToTarget > 0.850); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Skip(6); + "BOT REACHED TARGET" + Else; + Call Subroutine(BotResetPathFinding); + Abort; + End; + End; + "CONTINUE FOLLOW PATH" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: GAME MODE INIT - WORKSHOP SETTINGS") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.IsDebug = False; + Global.IsDebugAINavigation = False; + Global.GateMaxHealth = Workshop Setting Integer(Custom String("Defend The Castle Extended"), Custom String("GATE MAX HEALTH"), 500, + 100, 1000, 0); + Global.MoneyMult = Workshop Setting Real(Custom String("Defend The Castle Extended"), Custom String("Money Multiplicator"), 1, + 0.500, 2, 0); + Global.IsStoryHeroes = Workshop Setting Toggle(Custom String("Defend The Castle Extended"), Custom String("Story Heroes"), True, + 0); + Global.SelfNanoWorkshopSetting = Workshop Setting Toggle(Custom String("Ana Self Nano"), Custom String( + "Ana can nano herself even if there are other players (only if no player targeted)"), False, 0); + } +} + +rule("GLOBAL: GAME MODE INIT - COMMON PROPERTIES") +{ + event + { + Ongoing - Global; + } + + actions + { + Create HUD Text(All Players(All Teams), Null, Null, Custom String( + "Defend The Castle Extended v0.6.c124 BY ShuriZma#2349\r\nOriginal mode by HUKUTA94#2589\r\nDiscord: discord.shurizma.de\r\n{0}", + Custom String( + "Special Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents &\nJosbird for teaching me about Menus{0}", + Custom String(" \nPS: SHINGEN PLS COME BACK"))), Right, -1000, Null, Null, Color(White), Visible To, Default Visibility); + Global.GateRepairPosition = Vector(153, 8, -46.500); + Global.GatePosition = Vector(148.800, 6, -46.400); + Global.BallSpawnPositions = Array(Vector(104, 7, -46), Vector(106, 2, -31)); + Global.SniperPositions = Array(Vector(154, 18, -22.600), Vector(86, 12, -46.600), Vector(80.880, 11.300, -71.600), Vector(98, 9, + -19)); + Global.ZenSpawnPositions = Array(Vector(79.500, 5, -100), Vector(90, 4, -88), Vector(65, 11, -70), Vector(85, 4, -68), Vector(96, + 2, -73), Vector(84, 7, -47), Vector(95, 9, -34), Vector(108, 1.700, -28), Vector(113, 7, -37), Vector(123, 5, -19), Vector(144, + 5, -19), Vector(123, 6, -39), Vector(123, 6, -61), Vector(129, 6, -30.500), Vector(135, 6, -63)); + Global.PlayerSpawnPositions = Array(Vector(153.300, 10, -63.800), Vector(153.300, 10, -61.700), Vector(153.300, 10, -31.700), + Vector(153.300, 10, -29.600)); + Global.BigBossSpawnPositions = Array(Vector(78, 4, -84), Vector(95, 4, -82)); + Global.BastionTargetPositions = Array(Vector(131, 12, -62), Vector(115, 7, -46), Objective Position(2), Vector(136, 10, -27)); + Global.SpawnPositionMaxId = 2; + Global.BotOrisaTargetPosition = Vector(104, 7, -46); + Global.BotEchoRespawnPosition = Vector(130, 23, -44); + Global.BotEchoTeleportPositions = Array(Vector(88, 23, -79), Vector(108, 18, -27)); + Global.DefaultHeroBotsPool = Array(Hero(Zenyatta), Hero(Widowmaker), Null, Hero(Bastion), Hero(Echo), Hero(Bastion)); + Global.ZenRespawnTime = 10; + Global.GameLogicCountOfUniqueHeroes = 5; + Global.lastBoss = Array(Null, Null, Null, Null); + Create Effect(All Players(Team 1), Ring, Color(Sky Blue), Vector(186, 11, -46.500), 9, Visible To Position and Radius); + } +} + +disabled rule("PLAYER: DEBUG - PRESS INTERACT") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Host Player == True; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + disabled Modify Player Score(Event Player, 10); + disabled Global.GateHealth -= 5; + disabled Start Rule(GateProgressBarColor, Restart Rule); + Global.TimeSec = 59; + Set Status(Event Player, Null, Phased Out, 9999); + disabled Set Ultimate Charge(Event Player, 100); + disabled Kill(Event Player, Null); + disabled Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: DEBUG - AI NAVIGATION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.IsDebugAINavigation == True; + } + + actions + { + For Global Variable(LoopIterator1, 0, Count Of(Global.NodePositions), 1); + Create Effect(All Players(All Teams), Sphere, Color(Red), Global.NodePositions[Global.LoopIterator1], 0.850, Visible To); + Create In-World Text(All Players(All Teams), Custom String("NODE {0}", Global.LoopIterator1), + Global.NodePositions[Global.LoopIterator1], 1.200, Clip Against Surfaces, Visible To, Color(White), Default Visibility); + End; + } +} + +disabled rule("GLOBAL: DEBUG - CREATE BOTS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + Create Dummy Bot(Hero(Bastion), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + Create Dummy Bot(Hero(Orisa), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +disabled rule("PLAYER: DEBUG - INFOS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + Host Player == Event Player; + Has Spawned(Event Player) == True; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Create HUD Text(Event Player, Custom String("POS {0}\r\nFACING {1}", Position Of(Event Player), Facing Direction Of(Event Player)), + Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + Create HUD Text(Event Player, Custom String("SERVER PERFORMANCE\r\nLOAD {0}%\r\nPEAK {1}%\r\nAVG {2}%", Server Load, + Server Load Peak, Server Load Average), Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create Progress Bar HUD Text(Event Player, 45, Custom String("45 / 100 KILLS"), Left, -99, Color(Blue), Color(White), + Visible To Values and Color, Default Visibility); + disabled Create HUD Text(Event Player, Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Null, Custom String( + "LEVEL 1 - 50 AMMO CLIP"), Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + "ЭФФЕКТ С ОФФСЕТОМ ОТ ПОЗИЦИИ ГЛАЗ" + disabled Create Beam Effect(All Players(All Teams), Bad Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + Facing Direction Of( + Event Player) * 3, Eye Position(Event Player) + Facing Direction Of(Event Player) * 50, Color(Purple), + Visible To Position and Radius); + } +} + +disabled rule("=== TEAM UPGRADES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: TEAM UPGRADES - INIT") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.UpgradeMaxAmmoMaxValue[0] = 250; + Global.UpgradeMaxAmmoMaxValue[1] = 500; + Global.UpgradeMaxAmmoMaxValue[2] = 1000; + Global.UpgradeCriticalDamageMaxValue[0] = 10; + Global.UpgradeCriticalDamageMaxValue[1] = 5; + Global.UpgradeCriticalDamageMaxValue[2] = 5; + Global.UpgradePlayerMaxHealthMaxValue[0] = 2500; + Global.UpgradePlayerMaxHealthMaxValue[1] = 5000; + Global.UpgradePlayerMaxHealthMaxValue[2] = 10000; + Global.UpgradeGateMaxHealthMaxValue[0] = Round To Integer(Global.GateMaxHealth + Global.GateMaxHealth * 0.500, Up); + Global.UpgradeGateMaxHealthMaxValue[1] = Global.UpgradeGateMaxHealthMaxValue[0] + Global.UpgradeGateMaxHealthMaxValue[0]; + Global.UpgradeGateMaxHealthMaxValue[2] = Global.UpgradeGateMaxHealthMaxValue[1] + Global.UpgradeGateMaxHealthMaxValue[1]; + Abort If(Global.IsDebug == False); + Global.UpgradeMaxAmmoMaxValue[0] = 1; + Global.UpgradeCriticalDamageMaxValue[0] = 1; + Global.UpgradePlayerMaxHealthMaxValue[0] = 1; + Global.UpgradeGateMaxHealthMaxValue[0] = 1; + Global.UpgradeMaxAmmoMaxValue[1] = 1; + Global.UpgradeCriticalDamageMaxValue[1] = 1; + Global.UpgradePlayerMaxHealthMaxValue[1] = 1; + Global.UpgradeGateMaxHealthMaxValue[1] = 1; + Global.UpgradeMaxAmmoMaxValue[2] = 1; + Global.UpgradeCriticalDamageMaxValue[2] = 1; + Global.UpgradePlayerMaxHealthMaxValue[2] = 1; + Global.UpgradeGateMaxHealthMaxValue[2] = 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GATE'S MAX HEALTH UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Global.GateMaxHealth = Global.UpgradeGateMaxHealthMaxValue[0]; + Global.GateHealth = Global.GateMaxHealth; + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Right, 1, Color( + Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X GATE REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[1]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X GATE REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X GATE REPAIR"), Right, 2, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X AUTO-REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[2]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[2] = Last Text ID; + Global.GateHealth = Global.GateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 3 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X AUTO-REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X AUTO-REPAIR"), Right, 3, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.UpgradeGateMaxHealthHudId[2] = Last Text ID; + Global.GateHealth = Global.GateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - PLAYER'S MAX HEALTH - DEALT HEALING") +{ + event + { + Player Received Healing; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + disabled Healer != Event Player; + Global.UpgradePlayerMaxHealthValue < Global.UpgradePlayerMaxHealthMaxValue[2]; + } + + actions + { + Global.UpgradePlayerMaxHealthValue += Event Healing; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +50%"), Right, 4, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("Up You Go: You respawn twice as fast"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[1]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.MaxHealthDone = 50; + All Players(Team 1).PlayerHealth = 100 + Global.MaxHealthDone + All Players(Team 1).Abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).PlayerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK UP YOU GO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("UP YOU GO UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String("Up You Go"), + Right, 5, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +100%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[2]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[2] = Last Text ID; + Set Respawn Max Time(All Players(Team 1), 5); + Heal(All Players(Team 1), Null, 9999); + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.Perk[2] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[17] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH 2 UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +100%"), Right, 6, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[2] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.MaxHealthDone = 150; + All Players(Team 1).PlayerHealth = 100 + Global.MaxHealthDone + All Players(Team 1).Abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).PlayerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Hero Of(Victim) == Hero(Widowmaker); + Global.UpgradeCriticalDamageValue < Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradeCriticalDamageValue += 1; + Small Message(All Players(Team 1), Custom String("CRITICAL DAMAGE CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - CRITICAL DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("CRITICAL DAMAGE 150% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "CRITICAL DAMAGE 150%"), Right, 7, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String( + "Sharpshooter: Deal 40% more damage to enemies that are further than 15 meters away"), Custom String("KILL ECHO {0}/{1}", + Global.UpgradePerkSharpshooterValue, Global.UpgradeCriticalDamageMaxValue[1]), Left, 14, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - UNLOCKED") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.500); + } +} + +rule("PLAYER: UPGRADE - PERK SHARPSHOOTER - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Echo); + Global.UpgradePerkSharpshooterValue < Global.UpgradeCriticalDamageMaxValue[1]; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradePerkSharpshooterValue += 1; + Small Message(All Players(Team 1), Custom String("SHARPSHOOTER CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - PERK SHARPSHOOTER - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("SHARPSHOOTER UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Sharpshooter"), Right, 8, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("-10% BOSS HEALTH"), Custom String("KILL Bosses {0}/{1}", + Global.UpgradeBossHealthValue, Global.UpgradeCriticalDamageMaxValue[2]), Left, 14, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[2] = Last Text ID; + Global.Perk[0] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[18] = Last Text ID; + Global.challengeCount += 1; + } +} + +disabled rule("PLAYER: UPGRADE - -10% BOSS HEALTH - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]; + Global.UpgradeBossHealthValue < Global.UpgradeCriticalDamageMaxValue[2]; + Victim.isBoss == 1; + } + + actions + { + Global.UpgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - -10% BOSS HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("-10% BOSS HEALTH UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "-10% BOSS HEALTH"), Right, 9, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[2] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - MAX AMMO - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Zenyatta); + Global.UpgradeMaxAmmoValue < Global.UpgradeMaxAmmoMaxValue[2]; + } + + actions + { + If(Event Player.isBoss == 1); + Global.UpgradeMaxAmmoValue += 10; + Else; + Global.UpgradeMaxAmmoValue += 1; + End; + } +} + +rule("GLOBAL: UPGRADE - MAX AMMO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("MAX AMMO 200% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "MAX AMMO 200%"), Right, 10, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("Bulletstorm: Your weapon can hold unlimited ammo"), + Custom String("KILL {2}: {0}/{1}", Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[1], Hero(Zenyatta)), Left, 15, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0) * 2); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1) * 2); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0)); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1)); + End; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK BULLETSTORM - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("BULLETSTORM UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Bulletstorm"), Right, 11, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("+50% DAMAGE"), Custom String("KILL {2}: {0}/{1}", + Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[2], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[2] = Last Text ID; + Global.Perk[1] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[19] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - +50% DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("+50% DAMAGE UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "+50% DAMAGE"), Right, 12, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[2] = Last Text ID; + Global.DamageDone = 50; + All Players(Team 1).DamageDealt = 100 + Global.DamageDone + All Players(Team 1).Abilities[13] * 5; + Set Damage Dealt(All Players(Team 1), All Players(Team 1).DamageDealt); + Global.challengeCount += 1; + } +} + +disabled rule("=== GAME PHASES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: ASEMBLING PHASE - MAKE CHALLENGES HUDS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Assembling Heroes == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Disable Inspector Recording; + Set Match Time(20); + End; + Create In-World Text(All Players(Team 1), Custom String(" {0}\r\nREPAIR\r\n {1}", Hero Icon String(Hero(Torbjörn)), + Ability Icon String(Hero(Bastion), Button(Secondary Fire))), Global.GatePosition + Vector(0, 1.400, 0), 1.200, Do Not Clip, + Visible To, Color(White), Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("TEAM CHALLENGES"), Left, 11, Color(White), Color(Blue), Color( + White), Visible To, Default Visibility); + "UPGRADE - GATE'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String( + "GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Custom String("REPAIR GATE {0}/{1} HP", + Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[0]), Left, 12, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 2, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - PLAYER'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +50%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[0]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 4, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - CRITICAL DAMAGE" + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("CRITICAL DAMAGE 150%"), Custom String( + "KILL WIDOW WITH HEADSHOT: {0}/{1}", Global.UpgradeCriticalDamageValue, Global.UpgradeCriticalDamageMaxValue[0]), Left, 14, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 6, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - MAX AMMO" + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("MAX AMMO 200%"), Custom String("KILL {2}: {0}/{1}", + Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[0], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Custom String("HOLD {0} - Reload to open the shop", Input Binding String(Button(Reload))), + Null, Null, Top, 1000, Color(Yellow), Color(White), Color(White), Visible To and String, Default Visibility); + } +} + +rule("GLOBAL: SETUP PHASE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Pause Match Time; + Create HUD Text(All Players(Team 1), Custom String("PRESS {0} TO START", Button(Interact)), Null, Null, Top, 50, Color(Red), Color( + White), Color(White), Visible To and String, Default Visibility); + Global.GlobalHuds[0] = Last Text ID; + Set Match Time(20); + Wait Until(Is True For Any(All Players(Team 1), Is Button Held(Current Array Element, Button(Interact))), 99999); + Destroy HUD Text(Global.GlobalHuds[0]); + Unpause Match Time; + End; + Set Objective Description(All Players(All Teams), Custom String("DEFEND GATE"), Visible To and String); + } +} + +rule("GLOBAL: GAME IN PROGRESS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + } + + actions + { + Set Match Time(3599); + Pause Match Time; + Disable Built-In Game Mode Scoring; + Disable Built-In Game Mode Announcer; + Disable Built-In Game Mode Completion; + Disable Game Mode HUD(All Players(All Teams)); + Disable Game Mode In-World UI(All Players(All Teams)); + Global.GateHealth = Global.GateMaxHealth; + Global.GateHealthChase = Global.GateHealth; + Global.GateProgressBarColorComponent = 255; + Global.GateProgressBarColorCurrent = Color(White); + Create Progress Bar HUD Text(All Players(Team 1), Global.GateHealthChase * 100 / Global.GateMaxHealth, Custom String( + "GATE {0}/{1}", Global.GateHealth, Global.GateMaxHealth), Top, 1, Global.GateProgressBarColorCurrent, Color(White), + Visible To Values and Color, Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("SURVIVED TIME: {0}:{1}", Global.TimeMin, + Global.TimeSec < 10 ? Custom String("0{0}", Global.TimeSec) : Global.TimeSec), Top, 2, Color(White), Color(White), Color( + White), Visible To and String, Default Visibility); + Start Rule(GameLogicWave0, Do Nothing); + } +} + +disabled rule("=== GAME - MAIN LOGIC ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: DEFEAT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.IsDebug == False; + Global.GateHealth <= 0; + } + + actions + { + Declare Team Victory(Team 2); + } +} + +rule("GLOBAL: TIMER - MAIN GAME LOOP") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + disabled Global.GateHealth > 0; + } + + actions + { + Wait(1, Ignore Condition); + Global.TimeSec += 1; + If(Global.TimeSec == 60); + Global.TimeSec = 0; + Global.TimeMin += 1; + Global.Time5Min = Round To Integer(Global.TimeMin / 5, Down); + Global.Time10Min = Round To Integer(Global.TimeMin / 10, Down); + Global.SpawnPositionMaxId += 1; + disabled Start Rule(GameLogicAddNextHeroInGame, Restart Rule); + Else If(Global.TimeSec == 30); + Global.SpawnPositionMaxId += 1; + End; + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GAME LOGIC - ADD NEXT HERO IN GAME") +{ + event + { + Subroutine; + GameLogicAddNextHeroInGame; + } + + actions + { + "REDUCE RESPAWN TIME FOR ZENS" + disabled Global.ZenRespawnTime -= 1.500; + disabled Global.ZenRespawnTime = Max(1, Global.ZenRespawnTime); + disabled Set Respawn Max Time(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Global.DefaultHeroBotsPool[0]), + Global.ZenRespawnTime); + "ALL HEROES WAS ADDED IN GAME" + Abort If(Global.DefaultHeroBotsPoolCurrentId == Count Of(Global.DefaultHeroBotsPool) - 1); + Global.DefaultHeroBotsPoolCurrentId += 1; + "ВРЕМЕННЫЙ КОСТЫЛЬ ЧТОБЫ ЭХО ЗАМЕНИЛА ХАМСТЕРА" + If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Hero(Echo)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Abort; + End; + "ABORT IF NEXT HERO IN ARRAY ORDER IS NULL" + Abort If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Null); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId], Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("SUBROUTINE: GAME LOGIC - SET BOT PROPERTIES") +{ + event + { + Subroutine; + GameLogicSetBotProperties; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + If(Global.TimeMin >= 10); + If(Filtered Array(Global.lastBoss, Current Array Element == Hero Of(Event Player)) == False); + If(Global.activeBoss == False); + If(Global.bossTrigger < Global.TimeMin); + Global.bossTrigger = Global.TimeMin; + Global.activeBoss = Event Player; + Event Player.isBoss = 1; + Big Message(All Players(Team 1), Custom String("BOSS SPAWNED - {0}", Hero Of(Event Player))); + End; + End; + End; + End; + "PROPERTIES BY DEFAULT" + Set Gravity(Event Player, 100); + Set Damage Dealt(Event Player, 100); + Set Respawn Max Time(Event Player, 10); + Start Scaling Player(Event Player, 1, False); + "INDIVIDUAL HERO'S PROPERTIES" + If(Hero Of(Event Player) == Hero(Zenyatta)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 30); + Set Max Health(Event Player, 5 * (100 + Global.TimeMin * 10) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 1.500, False); + Else; + If(20 + 3 * Number Of Players(Team 1) + 3 * Global.TimeMin > 75); + Set Move Speed(Event Player, 75); + Else; + Set Move Speed(Event Player, 20 + 3 * Count Of(All Players(Team 1)) + 3 * Global.TimeMin); + End; + Set Max Health(Event Player, 100 + Global.TimeMin * 10); + End; + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 20); + Set Max Health(Event Player, 5 * (70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + If(30 + Global.TimeMin + 2.500 * Global.Time5Min > 40); + Set Move Speed(Event Player, 40); + Else; + Set Move Speed(Event Player, 30 + Global.TimeMin + 2.500 * Global.Time5Min); + End; + Set Ultimate Charge(Event Player, 0); + Set Max Health(Event Player, 70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + If(Event Player.isBoss == 1); + Set Damage Dealt(Event Player, 2 * (85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min)); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 5 * (100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Event Player.BotCounter = 0; + Set Damage Dealt(Event Player, 85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Bastion)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 50); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Start Scaling Player(Event Player, 3, False); + Set Max Health(Event Player, 5 * (155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Else; + Set Move Speed(Event Player, 80); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Start Scaling Player(Event Player, 2, False); + Set Max Health(Event Player, 155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Orisa)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 5 * (220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Set Move Speed(Event Player, 30 + 5 * Global.Time5Min); + Else; + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min); + Set Move Speed(Event Player, 90 + 5 * Global.Time5Min); + End; + Else If(Hero Of(Event Player) == Hero(Echo)); + If(Event Player.isBoss == 1); + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 70 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 5 * (90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 130 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin); + End; + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.500, False); + Set Move Speed(Event Player, 70); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 5 * (55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin) / ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.100 : 1)); + Else; + disabled Start Scaling Player(Event Player, 0.850, False); + Set Move Speed(Event Player, 110); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin); + End; + End; + Wait(0.250, Ignore Condition); + "FILL HEALTH" + Heal(Event Player, Null, 100000); + } +} + +disabled rule("=== GATE ===") +{ + event + { + Ongoing - Global; + } +} + +rule("Subroutine: GATE REPAIR") +{ + event + { + Subroutine; + GateRepair; + } + + actions + { + Small Message(Event Player, Custom String("REPAIR +2% ULTIMATE")); + "UPGRADE - GATE'S MAX HEALTH" + If(Global.UpgradeGateMaxHealthValue < Global.UpgradeGateMaxHealthMaxValue[2]); + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.UpgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.UpgradeGateMaxHealthValue += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + End; + End; + "HEAL GATE" + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.GateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.GateHealth += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + "CHARGE ULTIMATE" + Else; + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + End; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + } +} + +rule("TORB: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Has Spawned(Event Player) == True; + Weapon(Event Player) == 2; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(Is Using Ability 2(Event Player) == True ? 0.350 : 0.700, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Brig: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 5; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Rein: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + Is Game In Progress == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Call Subroutine(GateRepair); + Wait(0.850, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GATE PROGRESS BAR COLOR") +{ + event + { + Subroutine; + GateProgressBarColor; + } + + actions + { + Stop Chasing Global Variable(GateHealthChase); + Chase Global Variable Over Time(GateHealthChase, Global.GateHealth, 0.100, Destination and Duration); + "GATE WAS DAMAGED" + If(Global.GateHealth < Global.GateHealthEvent); + For Global Variable(LoopIterator1, 0, 3, 1); + Global.GateProgressBarColorCurrent = Color(Red); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(White); + Wait(0.030, Ignore Condition); + End; + "GATE WAS REPAIRED" + Else; + Global.GateProgressBarColorCurrent = Color(Green); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(Yellow); + Wait(0.030, Ignore Condition); + End; + Global.GateHealthEvent = Global.GateHealth; + Global.GateProgressBarColorComponent = Global.GateHealth * 255 / Global.GateMaxHealth; + Global.GateProgressBarColorCurrent = Custom Color(255, Global.GateProgressBarColorComponent, Global.GateProgressBarColorComponent, + 255); + } +} + +disabled rule("=== COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("ALL: INIT") +{ + event + { + Player Joined Match; + All; + All; + } + + actions + { + "ALL (COMMON) INIT" + Event Player.IsDead = True; + Disable Kill Feed(Event Player); + Disable Game Mode In-World UI(Event Player); + Disable Death Spectate Target HUD(Event Player); + "BOT INIT" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotInit); + "PLAYER INIT" + Else; + Call Subroutine(PlayerInit); + End; + } +} + +rule("SUBROUTINE: BOT - INIT") +{ + event + { + Subroutine; + BotInit; + } + + actions + { + "INIT VARS" + Event Player.HasBadStatus = False; + Event Player.IsRespawning = False; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEventPosition = Vector(9999, 999, 9999); + "DISABLE ALL FOR BOT" + Disable Hero HUD(Event Player); + Disable Messages(Event Player); + Disable Text Chat(Event Player); + Disable Scoreboard(Event Player); + Disable Game Mode HUD(Event Player); + Disable Death Spectate All Players(Event Player); + Disable Voice Chat(Event Player, True, True, True); + "INIT AI NAVIGATION VARS" + Call Subroutine(BotResetPathFinding); + } +} + +rule("SUBROUTINE: PLAYER - INIT") +{ + event + { + Subroutine; + PlayerInit; + } + + actions + { + "STORY HEROES" + If(Global.IsStoryHeroes); + Reset Player Hero Availability(Event Player); + Set Player Allowed Heroes(Event Player, Array(Hero(Ana), Hero(Brigitte), Hero(Mercy), Hero(Lúcio), Hero(Moira), Hero(Baptiste), + Hero(Ashe), Hero(D.Va), Hero(Genji), Hero(Hanzo), Hero(Widowmaker), Hero(Cassidy), Hero(Reinhardt), Hero(Soldier: 76), Hero( + Torbjörn), Hero(Tracer), Hero(Winston), Hero(Pharah))); + End; + "TEAM CHALLENGE - PLAYER'S MAX HEALTH" + If(Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0]); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + End; + If(Is Game In Progress); + Disable Game Mode HUD(Event Player); + End; + } +} + +rule("ALL: RESPAWN") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + (Hero Of(Event Player) != Event Player.CurrentHero || Event Player.IsDead == True) == True; + } + + actions + { + Event Player.IsDead = False; + "BOT RESPAWN" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotRespawn); + If(Global.IsDebugAINavigation); + Create Beam Effect(All Players(All Teams), Good Beam, Eye Position(Event Player), Event Player.BotNextNodePosition, Color(Green), + Visible To Position and Radius); + End; + "PLAYER RESPAWN" + Else; + Call Subroutine(PlayerRespawn); + End; + "MUST BE AFTER ALL RESPAWN SUBROUTINES!" + Event Player.CurrentHero = Hero Of(Event Player); + } +} + +rule("SUBROUTINE: BOT - RESPAWN") +{ + event + { + Subroutine; + BotRespawn; + } + + actions + { + "RESET COMMON PROPERTIES" + Event Player.IsRespawning = True; + Enable Nameplates(Event Player, All Players(Team 1)); + Call Subroutine(BotResetPathFinding); + disabled If(Hero Of(Event Player) != Event Player.CurrentHero); + Call Subroutine(GameLogicSetBotProperties); + disabled End; + "INDIVIDUAL HERO'S RESPAWN SCRIPTS" + If(Hero Of(Event Player) == Hero(Bastion)); + Call Subroutine(BotBastionRespawn); + Else If(Hero Of(Event Player) == Hero(Zenyatta)); + Call Subroutine(BotZenyattaRespawn); + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + Call Subroutine(BotWidowRespawn); + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Call Subroutine(BotBallRespawn); + Else If(Hero Of(Event Player) == Hero(Orisa)); + Call Subroutine(BotOrisaRespawn); + Else If(Hero Of(Event Player) == Hero(Echo)); + Call Subroutine(BotEchoRespawn); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Call Subroutine(BotReinRespawn); + End; + Event Player.IsRespawning = False; + } +} + +rule("SUBROUTINE: PLAYER - RESPAWN") +{ + event + { + Subroutine; + PlayerRespawn; + } + + actions + { + "TEAM CHALLENGE - MAX AMMO" + If(Hero Of(Event Player) != Event Player.CurrentHero && Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]); + Set Max Ammo(Event Player, 0, Ammo(Event Player, 0) * 2); + Set Max Ammo(Event Player, 1, Ammo(Event Player, 1) * 2); + Set Ammo(Event Player, 0, Max Ammo(Event Player, 0)); + Set Ammo(Event Player, 1, Max Ammo(Event Player, 1)); + End; + "MUST BE AFTER TEAM CHALLENGE MAX AMMO!" + disabled Event Player.CurrentHero = Hero Of(Event Player); + "PLAYER RESPAWN" + Set Status(Event Player, Null, Phased Out, 3); + Set Facing(Event Player, Vector(-1, 0, 0), To World); + If(Ability Cooldown(Players On Hero(Hero(Mercy), Team 1), Button(Ability 2)) >= 29); + Teleport(Event Player, Event Player.deathPosition); + Else; + Teleport(Event Player, Global.PlayerSpawnPositions[Slot Of(Event Player) == Count Of(Global.PlayerSpawnPositions) ? Random Integer( + 0, Count Of(Global.PlayerSpawnPositions) - 1) : Slot Of(Event Player)]); + End; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + } +} + +rule("PLAYER: DEATH") +{ + event + { + Player Died; + Team 1; + All; + } + + actions + { + If(Hero Of(Event Player) == Hero(Roadhog)); + Event Player.Abilities[8] -= 1; + Wait(Global.Perk[2] ? 5 : 10, Ignore Condition); + Event Player.Abilities[8] += 1; + End; + Event Player.deathPosition = Position Of(Event Player); + disabled If(Event Player.lastSecondWind > 0); + disabled Event Player.lastSecondWind = 0; + disabled End; + Event Player.IsDead = True; + } +} + +rule("BOT: DEATH") +{ + event + { + Player Died; + Team 2; + All; + } + + actions + { + If(Event Player.isBoss == 1); + If(Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]); + If(Global.UpgradeBossHealthValue < Global.UpgradeCriticalDamageMaxValue[2]); + Global.UpgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + End; + End; + Event Player.isBoss = 0; + Global.activeBoss = Null; + Big Message(All Players(Team 1), Custom String("BOSS DIED - {0}", Hero Of(Event Player))); + End; + Event Player.IsDead = True; + Event Player.HasBadStatus = False; + Event Player.BotDoesUniqueBehaviour = False; + Disable Nameplates(Event Player, All Players(Team 1)); + disabled Stop Holding Button(Event Player, Button(Ability 1)); + disabled Stop Holding Button(Event Player, Button(Primary Fire)); + disabled Stop Holding Button(Event Player, Button(Secondary Fire)); + "BOT HAS 1 EFFECT IN VAR (NOT ARRAY)" + Skip If(!Entity Exists(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects); + "BOT HAS MORE THEN 1 EFFECT IN VAR (ARRAY)" + Skip If(Count Of(Event Player.BotEffects) == 0, 3); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects[Event Player.BotLoopIterator1]); + End; + } +} + +disabled rule("=== BOT COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BAD STATUS") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + Event Player.HasBadStatus = True; + "PROCESS BAD STATUS" + If(Hero Of(Event Player) == Hero(Widowmaker)); + Start Rule(BotWidowBadStatus, Do Nothing); + End; + Wait Until(!Has Status(Event Player, Knocked Down) && !Has Status(Event Player, Asleep) && !Has Status(Event Player, Frozen) + && !Has Status(Event Player, Stunned), 15); + Event Player.HasBadStatus = False; + } +} + +rule("SUBROUTINE: BOT - LANDING FROM SKY") +{ + event + { + Subroutine; + BotLandingFromSky; + } + + actions + { + Stop Throttle In Direction(Event Player); + "SET RESPAWN POSITION" + Event Player.BotEventPosition = Random Value In Array(Global.BigBossSpawnPositions); + "CREATE EFFECTS" + disabled Create Effect(All Players(All Teams), Light Shaft, Color(Red), Event Player.BotEventPosition, 3, Visible To); + disabled Event Player.BotEffects = Last Created Entity; + "RESPAWN IN LIGHT SHAFT EFFECT" + Teleport(Event Player, Event Player.BotEventPosition + Vector(0, 25, 0)); + Wait(0.020, Ignore Condition); + "SLOW LANDING" + Set Gravity(Event Player, 50); + While(Is In Air(Event Player) == True); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Position Of(Event Player) + Vector(0, -2.700, 0), 2); + Wait(0.250, Ignore Condition); + End; + Set Gravity(Event Player, 100); + disabled Destroy Effect(Event Player.BotEffects); + "LANDING EFFECTS" + Play Effect(All Players(All Teams), Wrecking Ball Piledriver Impact Effect, Custom Color(105, 87, 46, 255), Position Of( + Event Player), 8); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Sound, Color(White), Position Of(Event Player), 150); + } +} + +rule("SUBROUTINE: BOT - APPEAR FROM UNDERGROUND") +{ + event + { + Subroutine; + BotApearFromUnderground; + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1); + Wait(0.200, Ignore Condition); + Set Gravity(Event Player, 20); + Disable Movement Collision With Environment(Event Player, True); + Teleport(Event Player, Global.ZenSpawnPositions[Random Integer(Min(Global.TimeMin, Count Of(Global.ZenSpawnPositions) - 10), Min( + Global.SpawnPositionMaxId, Count Of(Global.ZenSpawnPositions) - 4))] + Vector(0, -1.500, 0)); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Sigma Accretion Impact Effect, Custom Color(220, 175, 100, 255), Eye Position(Event Player), + 3); + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(Gray), Eye Position(Event Player), 50); + Apply Impulse(Event Player, Up, 3.500, To World, Cancel Contrary Motion); + Wait(0.400, Ignore Condition); + Clear Status(Event Player, Knocked Down); + Set Gravity(Event Player, 100); + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("=== PLAYER MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("PLAYER: DARKNESS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + !Entity Exists(Event Player.BotEffects) == True; + } + + actions + { + Disable Nameplates(Event Player, All Players(All Teams)); + Start Forcing Player Outlines(Event Player, All Players(All Teams), False, Color(White), Default); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 14), 25, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(-5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + } +} + +rule("PLAYER: HEALTH REGEN") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + actions + { + Stop Heal Over Time(Event Player.HealOverTimeId); + Event Player.EventHealth = Health(Event Player); + Wait(4, Ignore Condition); + "TOOK DAMAGE, RESET REGENERATION TIMER" + Loop If(Is Alive(Event Player) && Event Player.EventHealth > Health(Event Player)); + Start Heal Over Time(Event Player, Null, 3, Max Health(Event Player) / 3); + Event Player.HealOverTimeId = Last Heal Over Time ID; + } +} + +disabled rule("=== NERFS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("REINHARDT: ANTI-CHARGE FOR BASTION & ORISA") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Using Ability 1(Event Player) == True; + Hero Of(Ray Cast Hit Player(Eye Position(Event Player) + Vector(0, 2, 0), Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 2, All Living Players(Team 2), Event Player, True)) == (Hero(Bastion) == True || Hero( + Orisa) == True); + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1.500); + } +} + +rule("HOG: ANTI-HOOK FOR BASTION & ORISA") +{ + event + { + Player Dealt Damage; + Team 1; + Roadhog; + } + + conditions + { + Event Ability == Button(Ability 1); + (Hero Of(Victim) == Hero(Bastion) || Hero Of(Victim) == Hero(Orisa)) == True; + } + + actions + { + Set Status(Event Player, Null, Stunned, 0.005); + } +} + +disabled rule("=== ZENYATTA ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ZEN - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Zenyatta; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + } + + actions + { + Set Ammo(Event Player, 0, 0); + Communicate(Event Player, Hello); + disabled Call Subroutine(BotResetPathFinding); + Wait(1.500, Ignore Condition); + Abort If(Is Dead(Event Player) == True); + Kill(Event Player, Null); + } +} + +rule("BOT: ZEN - DEATH") +{ + event + { + Player Died; + Team 2; + Zenyatta; + } + + actions + { + "EFFECT" + Play Effect(All Players(All Teams), Junkrat Frag Launcher Explosion Effect, Color(Red), Eye Position(Event Player), 2.500); + Play Effect(All Players(All Teams), Ashe Dynamite Explosion Sound, Color(Red), Eye Position(Event Player), 70); + "DAMAGE AND APPLY IMPULSE TO PLAYERS" + Event Player.BotPlayersInRadius = Players Within Radius(Position Of(Event Player), 2.500, All Teams, Surfaces And Enemy Barriers); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotPlayersInRadius), 1); + Apply Impulse(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Direction Towards(Position Of(Event Player), + Eye Position(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1])), 5, To World, Incorporate Contrary Motion); + If(Team Of(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1]) == Team 1); + Damage(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Event Player, 50); + End; + End; + "DAMAGE GATE" + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 125; + Else; + Global.GateHealth -= 25; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Respawn(Event Player); + Abort; + End; + "KILLED BY PLAYER" + Teleport(Event Player, Vector(0, -999, 0)); + Wait(2, Ignore Condition); + Respawn(Event Player); + Wait(2, Ignore Condition); + } +} + +rule("SUBROUTINE: ZEN - RESPAWN") +{ + event + { + Subroutine; + BotZenyattaRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WRECKING BALL ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BALL - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + disabled Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Set Ammo(Event Player, 0, 0); + Wait(1, Ignore Condition); + Set Ultimate Charge(Event Player, 100); + Start Holding Button(Event Player, Button(Ultimate)); + Wait Until(Is Using Ultimate(Event Player), 0.600); + Abort If(Is Dead(Event Player)); + Kill(Event Player, Null); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Effect, Color(Orange), Eye Position(Event Player), 6); + Play Effect(All Players(All Teams), DVa Self Destruct Explosion Sound, Color(White), Eye Position(Event Player), 250); + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 300; + Else; + Global.GateHealth -= 150; + End; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Damage(Players Within Radius(Eye Position(Event Player), 7, Team 1, Surfaces And All Barriers), Event Player, 200); + } +} + +rule("BOT: BALL - ALTERNATIVE FORM") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is In Alternate Form(Event Player) == False; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is In Alternate Form(Event Player), 10); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: BALL - DEATH") +{ + event + { + Player Died; + Team 2; + Wrecking Ball; + } + + actions + { + Stop Holding Button(Event Player, Button(Ability 1)); + Stop Holding Button(Event Player, Button(Ultimate)); + } +} + +rule("SUBROUTINE: BALL - RESPAWN") +{ + event + { + Subroutine; + BotBallRespawn; + } + + actions + { + "RESPAWN IN AIR" + Teleport(Event Player, Random Value In Array(Global.BallSpawnPositions) + Vector(0, 20, 0)); + Stop Holding Button(Event Player, Button(Ultimate)); + Wait(0.250, Ignore Condition); + "LANDING" + Start Holding Button(Event Player, Button(Crouch)); + Wait Until(Is On Ground(Event Player), 9999); + Stop Holding Button(Event Player, Button(Crouch)); + "LANDING IMPACT EFFECT" + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(White), Event Player, 150); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Effect, Color(Gray), Position Of(Event Player), 10); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Eye Position(Event Player), 1.500, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + "PATH FINDING TO GATE" + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +disabled rule("=== ECHO ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ECHO - FLY ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is Using Ability 1(Event Player) == False; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), 0); + Press Button(Event Player, Button(Ability 1)); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - BEAM ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Using Ability 1(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == True; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - BAD STATUS - RESET BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.HasBadStatus == True; + disabled (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + Wait Until(Event Player.HasBadStatus, 7); + } +} + +rule("BOT: ECHO - CAN'T SEE PORTAL - APPLY IMPULSE") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == True; + Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Wait(0.300, Abort When False); + Apply Impulse(Event Player, Vector(Random Integer(-1, 1), 1, Random Integer(-1, 1)), 20, To World, Incorporate Contrary Motion); + Wait(1, Ignore Condition); + If(!Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + Event Player.BotTargetPosition = Global.BotEchoRespawnPosition; + Start Rule(BotStartPathFinding, Restart Rule); + Else; + Call Subroutine(BotResetPathFinding); + End; + Loop If Condition Is True; + } +} + +disabled rule("BOT: ECHO - MAIN LOGIC - BACKUP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(!Event Player.BotIsPathFinding); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Is In Line of Sight(Eye Position(Event Player), + Eye Position(Current Array Element), Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), + Position Of(Current Array Element)))[0]; + End; + "NO PLAYERS IN VIEW RANGE" + disabled If(Event Player.BotSeePlayer == Null); + disabled Stop Throttle In Direction(Event Player); + disabled End; + "FLY TO PLAYER" + If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + > 4 && Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + "ACTIVATE FOCUS BEAM" + Else If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + < 4 && Event Player.BotDoesUniqueBehaviour == False && Event Player.HasBadStatus == False); + Event Player.BotDoesUniqueBehaviour = True; + Set Status(Event Player.BotSeePlayer, Event Player, Stunned, 1); + Set Status(Event Player.BotSeePlayer, Event Player, Hacked, 99999); + Attach Players(Event Player.BotSeePlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + "TELEPORT PLAYER TO AWAY" + Else If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotSeePlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotSeePlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotSeePlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + "BEGIN TO FLY TO THE PORTAL" + Else If(Event Player.BotDoesUniqueBehaviour == True); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + End; + "TELEPORT PLAYER SO FAR" + If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotEchoCapturedPlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotEchoCapturedPlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + End; + "BEGIN TO FLY TO THE PORTAL WITH A PLAYER" + If(Event Player.BotDoesUniqueBehaviour); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotEchoCapturedPlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - DEFEND PORTAL") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + } + + actions + { + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPlayer); + } +} + +rule("BOT: ECHO - PATH FINDING TO PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Call Subroutine(BotStartPathFinding); + } +} + +rule("BOT: ECHO - ATTACH PLAYER BY BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotEchoCapturedPlayer == Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 3; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Event Player.BotEchoCapturedPlayer = Event Player.BotSeePlayer; + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Stunned, 0.700); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Hacked, 10); + Attach Players(Event Player.BotEchoCapturedPlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - PLAYER DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Dead(Event Player.BotEchoCapturedPlayer) != Null; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - DEATH") +{ + event + { + Player Died; + Team 2; + Echo; + } + + actions + { + Call Subroutine(BotEchoDetachPlayer); + Stop Holding Button(Event Player, Button(Jump)); + Wait(5, Ignore Condition); + Teleport(Event Player, Vector(0, 999, 0)); + Start Forcing Player To Be Hero(Event Player, Hero(Orisa)); + } +} + +rule("SUBROUTINE: ECHO - RESPAWN") +{ + event + { + Subroutine; + BotEchoRespawn; + } + + actions + { + Event Player.BotCounter = 0; + Event Player.BotEffects = Empty Array; + Create Effect(All Players(All Teams), Good Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Energy Sound, Color(White), Global.BotEchoRespawnPosition, 200, Visible To); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Chase Player Variable Over Time(Event Player, BotCounter, 3, 0.800, Destination and Duration); + Play Effect(All Players(All Teams), Sombra EMP Explosion Effect, Color(Sky Blue), Global.BotEchoRespawnPosition, 12); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Null, Global.BotEchoRespawnPosition, 100); + Wait(3, Ignore Condition); + Teleport(Event Player, Global.BotEchoRespawnPosition); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Global.BotEchoRespawnPosition, 2.500); + Play Effect(All Players(All Teams), Debuff Impact Sound, Null, Global.BotEchoRespawnPosition, 100); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PLAYER") +{ + event + { + Subroutine; + BotEchoFlyToPlayer; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Stop Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PORTAL") +{ + event + { + Subroutine; + BotEchoFlyToPortal; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - DETACH PLAYER") +{ + event + { + Subroutine; + BotEchoDetachPlayer; + } + + actions + { + Detach Players(Event Player.BotEchoCapturedPlayer); + Clear Status(Event Player.BotEchoCapturedPlayer, Hacked); + "IF PLAYER INSIDE THE WALL" + If(Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotEchoCapturedPlayer), Barriers Do Not Block LOS)); + Teleport(Event Player.BotEchoCapturedPlayer, Position Of(Event Player)); + End; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEchoCapturedPlayer = Null; + } +} + +disabled rule("=== REINHARDT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: REIN - SET PLAYER AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + disabled Event Player.BotIsPathFinding == False; + "BOT IS FAR FROM GATES" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Global.GatePosition), 0, Z Component Of(Global.GatePosition))) > 20; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET CLOSEST PLAYER TO BOT AS TARGET AND FOLLOW HIM" + Event Player.BotTargetPlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - SET GATE AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "BOT DOESN'T FOLLOW PLAYER" + Event Player.BotTargetPlayer == -1; + "CAN'T SEE ANY PLAYER" + disabled Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), !Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET GATE AS TARGET" + Event Player.BotTargetPosition = Global.GatePosition; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - TARGET DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer != -1; + Is Dead(Event Player.BotTargetPlayer) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + } +} + +rule("BOT: REIN - ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) < 4; + "CAN ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) < 4; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + "TARGET IS PLAYER" + Abort If(Event Player.BotTargetPlayer != -1); + If(Event Player.isBoss == 1); + "TARGET IS GATE" + Global.GateHealth -= 25; + Else; + Global.GateHealth -= 5; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: REIN - STOP ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) > 4; + "CAN'T ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) > 4; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + } +} + +rule("BOT: REIN - USE SHIELD") +{ + event + { + Player Took Damage; + Team 2; + Reinhardt; + } + + conditions + { + Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) > 3; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Attacker)), 200, To World, + Direction and Turn Rate); + Start Holding Button(Event Player, Button(Secondary Fire)); + Wait Until(Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) < 3, 3); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("BOT: REIN - CHARGE IN GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer == -1; + Is Using Ability 1(Event Player) == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == True; + Is In View Angle(Event Player, Global.GatePosition, 7.500) == True; + } + + actions + { + disabled Wait(0.800, Abort When False); + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is Using Ability 1(Event Player), 1); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: REIN - DEATH") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("SUBROUTINE: REIN - RESPAWN") +{ + event + { + Subroutine; + BotReinRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WIDOW ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: WIDOW - SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer == Null; + Event Player.HasBadStatus == False; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Event Player.BotWidowShotTime = Total Time Elapsed + (Global.TimeMin >= 9 ? Random Real(2, 5) : Random Real(5, 10)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 9999, To World, + Direction and Turn Rate); + } +} + +rule("BOT: WIDOW - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer != Null; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowShotTime; + } + + actions + { + Press Button(Event Player, Button(Primary Fire)); + Stop Facing(Event Player); + Event Player.BotSeePlayer = Null; + } +} + +rule("BOT: WIDOW - Aim Sound") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Alive(Event Player) == True; + Is In Line of Sight(Eye Position(Players On Hero(Hero(Widowmaker), Team 2)), Eye Position(Event Player), Barriers Do Not Block LOS) + == True; + Is Alive(Players On Hero(Hero(Widowmaker), Team 2)) == True; + Players On Hero(Hero(Widowmaker), Team 2).BotSeePlayer == True; + } + + actions + { + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 100); + Wait(1, Abort When False); + Loop If Condition Is True; + } +} + +rule("BOT: WIDOW - TELEPORT TO NEW POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowTeleportTime; + } + + actions + { + Event Player.BotWidowTeleportTime = Total Time Elapsed + 28; + Event Player.BotWidowShotTime = Total Time Elapsed + Random Real(1, 1.600); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Event Player, 1); + Wait(0.016, Ignore Condition); + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + Event Player.BotWidowShotTime = Total Time Elapsed + (Global.TimeMin >= 9 ? Random Real(2, 5) : Random Real(5, 10)); + } +} + +rule("BOT: WIDOW - DEATH") +{ + event + { + Player Died; + Team 2; + Widowmaker; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + Wait(0.250, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - RESPAWN") +{ + event + { + Subroutine; + BotWidowRespawn; + } + + actions + { + "RESPAWN ON RANDOM SNIPER POSITION" + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Wait(0.700, Ignore Condition); + Start Holding Button(Event Player, Button(Secondary Fire)); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait Until(Is Dead(Event Player), 99999); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - BAD STATUS") +{ + event + { + Subroutine; + BotWidowBadStatus; + } + + actions + { + Stop Facing(Event Player); + Destroy Effect(Event Player.BotEffects); + Wait Until(!Event Player.HasBadStatus, 15); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + } +} + +disabled rule("=== BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("BOT: BASTION - FLAME GUN") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 50) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 8; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Stop Holding Button(Event Player, Button(Primary Fire)); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Update Every Frame(Eye Position(Event Player) + World Vector Of( + Vector(-1, -1.200, 1.800), Event Player, Rotation)), 1, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Start Rule(BotBastionFlameGunDamage, Do Nothing); + Wait(1.100, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(4, Ignore Condition); + Loop If Condition Is True; + } +} + +disabled rule("BOT: BASTION - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + disabled Event Player.BotSeePlayer == Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - CAN'T SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == False; + } + + actions + { + Event Player.BotSeePlayer = Null; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - MOVE TO BASTION'S TARGET (POSITION)") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotTargetPosition = Random Value In Array(Filtered Array(Global.BastionTargetPositions, Distance Between(Position Of( + Event Player), Current Array Element) > 3.500)); + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("BOT: BASTION - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + "SEE THE PLAYER" + If(Event Player.BotSeePlayer != Null); + Stop Holding Button(Event Player, Button(Secondary Fire)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer) - Vector(0, 0.500, + 0)), 100, To World, Direction and Turn Rate); + "SELF REPAIRING" + Else If(!Is Firing Secondary(Event Player) && Health(Event Player) < Max Health(Event Player)); + Start Holding Button(Event Player, Button(Secondary Fire)); + End; + "START FOLLOW PATH" + disabled If(!Event Player.BotIsPathFinding && !Event Player.BotDoesUniqueBehaviour); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled Wait(0.050, Ignore Condition); + disabled Event Player.BotTargetPosition = Random Value In Array(Global.BastionTargetPositions); + disabled Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Event Player.BotTargetPosition + Vector(0, 2, 0)), 100, + To World, Direction and Turn Rate); + disabled Start Rule(BotStartPathFinding, Do Nothing); + "REACHED PATH TARGET" + disabled Else If(Distance Between(Position Of(Event Player), Event Player.BotTargetPosition) <= 3); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled End; + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - ARTILLERY") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 30) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) > 18; + Distance Between(Eye Position(Event Player), Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Up * 99, Null, Event Player, False)) >= 35; + } + + actions + { + "TRYING TO CAPTURE TARGET" + Wait(0.800, Abort When False); + "CAPTURE TARGET" + Event Player.BotDoesUniqueBehaviour = True; + Stop Throttle In Direction(Event Player); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Update Every Frame(Eye Position(Event Player)), + Update Every Frame(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 1000, All Living Players(Team 1), Event Player, True)), Color(Sky Blue), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait(1.400, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Event Player.BotEventPosition = Position Of(Event Player.BotSeePlayer); + "SHOOT FROM ARTILLERY" + Event Player.BotBastionArtilleryDidShotsCount = 0; + For Player Variable(Event Player, BotLoopIterator1, 0, 4, 1); + Event Player.BotBastionArtilleryDidShotsCount += 1; + Play Effect(All Players(All Teams), Wrecking Ball Minefield Explosion Sound, Color(White), Eye Position(Event Player), 250); + Play Effect(All Players(All Teams), Pharah Barrage Explosion Effect, Color(Orange), Eye Position(Event Player) + World Vector Of( + Vector(0, 1.400, -0.700), Event Player, Rotation), 2); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) + World Vector Of(Vector(0, 1.400, + -0.700), Event Player, Rotation), Eye Position(Event Player) + World Vector Of(Vector(Random Real(-1, 1), Random Integer(40, + 80), Random Real(0.500, 1.500)), Event Player, Rotation), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + If(Is Dead(Event Player)); + Break; + End; + End; + disabled Call Subroutine(BotResetPathFinding); + disabled Start Rule(BotStartPathFinding, Do Nothing); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Wait(1.500, Ignore Condition); + Start Rule(BotBastionArtilleryDamage, Do Nothing); + Wait(4, Ignore Condition); + } +} + +rule("BOT: BASTION - PRIMARY FIRE") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 40) == True; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Stop Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Bastion; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + For Player Variable(Event Player, BotLoopIterator1, 0, 3, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Effect, Color(White), Event Player, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player, 100); + Wait(0.250, Ignore Condition); + End; + } +} + +rule("SUBROUTINE: BASTION - RESPAWN") +{ + event + { + Subroutine; + BotBastionRespawn; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + Call Subroutine(BotLandingFromSky); + Set Ammo(Event Player, 0, 0); + Wait Until(!Is Reloading(Event Player), 99999); + Event Player.BotTargetPosition = Objective Position(2); + } +} + +rule("SUBROUTINE: BASTION - ARTILLERY DAMAGE") +{ + event + { + Subroutine; + BotBastionArtilleryDamage; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = False; + "EXPLOSIONS OF ARTILLERY" + For Player Variable(Event Player, BotLoopIterator2, 0, Event Player.BotBastionArtilleryDidShotsCount, 1); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotEventPosition + Vector(0, 50, 0), + Event Player.BotEventPosition + Vector(Random Integer(-4, 4), -15, Random Integer(-4, 4)), Null, Event Player, True); + Damage(Players Within Radius(Event Player.BotEventPosition, 8, Team 1, Surfaces And Enemy Barriers), Event Player, 50); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Pharah Rocket Launcher Explosion Effect, Color(Orange), Event Player.BotEventPosition, 5); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Event Player.BotEventPosition, + Event Player.BotEventPosition + Vector(0, 60, 0), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + End; + } +} + +disabled rule("SUBROUTINE: BASTION - FLAME GUN DAMAGE") +{ + event + { + Subroutine; + BotBastionFlameGunDamage; + } + + actions + { + Event Player.BotRayCastHitPosition = Eye Position(Event Player) + World Vector Of(Vector(-1, -1.200, 1.800), Event Player, + Rotation); + "FIRE PARTICLES OF FLAME GUN" + For Player Variable(Event Player, BotLoopIterator1, 1, 13, 3); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotRayCastHitPosition, + Event Player.BotRayCastHitPosition + Facing Direction Of(Event Player) * Event Player.BotLoopIterator1, Null, Event Player, + True); + Damage(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Surfaces And Enemy Barriers), Event Player, 20); + Set Status(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Off), Event Player, Burning, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.BotEventPosition, 2.500); + Wait(0.200, Ignore Condition); + End; + Event Player.BotDoesUniqueBehaviour = False; + } +} + +disabled rule("=== ORISA + BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ORISA-BASTION - REACHED TARGET POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotIsPathFinding == True; + Distance Between(Position Of(Event Player), Global.BotOrisaTargetPosition) < 1.500; + } + + actions + { + Call Subroutine(BotResetPathFinding); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Vector(X Component Of(Global.GatePosition), -999, + Z Component Of(Global.GatePosition))), 80, To World, Direction and Turn Rate); + Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + disabled Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element) && Is In Line of Sight(Eye Position(Event Player), Position Of(Current Array Element), + Barriers Do Not Block LOS)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + Press Button(Event Player, Button(Ability 1)); + Wait Until(Y Component Of(Facing Direction Of(Event Player)) < -0.300, 99999); + Press Button(Event Player, Button(Ability 2)); + Wait(0.800, Ignore Condition); + Global.BotOrisaChild.BotDoesUniqueBehaviour = False; + Disallow Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ORISA-BASTION - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + While(Is Alive(Event Player)); + disabled Create Effect(All Players(All Teams), Bad Aura, Color(Purple), Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3.200, 1, Visible To Position and Radius); + disabled Event Player.BotEffects = Last Created Entity; + Wait(1.500, Ignore Condition); + disabled Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Press Button(Event Player, Button(Primary Fire)); + Press Button(Event Player, Button(Reload)); + Event Player.BotRayCastHitPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Facing Direction Of(Event Player) * 999, All Players(Team 1), All Players(Team 2), True); + "ANTI-SHIELD BUG" + Event Player.BotRayCastHitPosition = Event Player.BotRayCastHitPosition + Direction Towards(Event Player.BotRayCastHitPosition, + Eye Position(Event Player)) * 0.200; + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3, Event Player.BotRayCastHitPosition, Color(Purple), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Damage(Players Within Radius(Event Player.BotRayCastHitPosition, 4, Team 1, Surfaces And All Barriers), Event Player, 0.040); + Play Effect(All Players(All Teams), Pharah Concussive Blast Effect, Color(Purple), Event Player.BotRayCastHitPosition, 4); + Play Effect(All Players(All Teams), Pharah Concussive Blast Sound, Color(Purple), Event Player.BotRayCastHitPosition, 250); + Play Effect(All Players(All Teams), Bad Explosion, Color(Purple), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 3.300, 2); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Color(Purple), Eye Position(Event Player), 170); + If(Distance Between(Event Player.BotRayCastHitPosition, Global.GatePosition) < 4 && Is In Line of Sight( + Event Player.BotRayCastHitPosition, Global.GatePosition, Enemy Barriers Block LOS)); + Global.GateHealth -= 80; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Wait(0.150, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.060, Ignore Condition); + Wait Until(!Is Reloading(Event Player), 2.500); + End; + } +} + +rule("BOT: ORISA-BASTION - CAN'T SEE THE TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: ORISA-BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Orisa; + } + + actions + { + Allow Button(Event Player, Button(Ability 2)); + Kill(Global.BotOrisaChild, Null); + Detach Players(Global.BotOrisaChild); + Clear Status(Global.BotOrisaChild, Phased Out); + Set Damage Dealt(Global.BotOrisaChild, 100); + Global.BotOrisaChild.BotIsOrisaChild = False; + Global.BotOrisaChild = Null; + Global.BotOrisaParent = Null; + Start Forcing Player To Be Hero(Event Player, Hero(Widowmaker)); + } +} + +rule("SUBROUTINE: ORISA - RESPAWN") +{ + event + { + Subroutine; + BotOrisaRespawn; + } + + actions + { + Global.BotOrisaParent = Event Player; + "WAITING FOR ANY BASTION TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero(Bastion)), + 99999); + "SETUP BASTION AS CHILD" + Global.BotOrisaChild = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Bastion))[0]; + Global.BotOrisaChild.BotIsOrisaChild = True; + Global.BotOrisaChild.BotDoesUniqueBehaviour = True; + Wait(2, Ignore Condition); + Respawn(Global.BotOrisaChild); + Start Scaling Player(Global.BotOrisaChild, 1.800, False); + Set Damage Dealt(Global.BotOrisaChild, 2000); + Set Status(Global.BotOrisaChild, Null, Phased Out, 9999); + Disable Nameplates(Global.BotOrisaChild, All Players(All Teams)); + Set Facing(Global.BotOrisaChild, Vector(X Component Of(Facing Direction Of(Event Player)), 9999, Z Component Of( + Facing Direction Of(Event Player))), To World); + Start Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Wait Until(Is In Alternate Form(Global.BotOrisaChild), 5); + Stop Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Teleport(Global.BotOrisaChild, Position Of(Event Player)); + Attach Players(Global.BotOrisaChild, Global.BotOrisaParent, Vector(0, 1.800, 0.230)); + disabled Wait(1, Ignore Condition); + disabled Stop Holding Button(Global.BotOrisaChild, Button(Primary Fire)); + disabled Wait(0.250, Ignore Condition); + Call Subroutine(BotLandingFromSky); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 0 - ZENS, REINS, BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 0; + } + + actions + { + "CREATE BOTS - ZEN" + While(Count Of(All Players(Team 2)) < 13); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "BALL" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "REPLACE DEAD ZEN TO REIN" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) != 3); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 1 - WIDOW") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 1; + } + + actions + { + Global.IsNewWaveGameLogicProcessing = True; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Global.IsNewWaveGameLogicProcessing = False; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 3 - BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 3; + } + + actions + { + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 5 - REINS WAVE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 5; + } + + actions + { + "PREPARE WAVE - DESTROY WIDOW AND BALLS" + Destroy Dummy Bot(Team 2, Slot Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))[0])); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))[0]; + Kill(Global.DefaultCurrentBot, Null); + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + "BOSS WAVE" + Big Message(All Players(All Teams), Custom String("BOSS WAVE - {1} {0}", Hero Icon String(Hero(Reinhardt)), Hero(Reinhardt))); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) < 6); + Wait Until(Is True For Any(All Players(Team 2), Distance Between(Position Of(Current Array Element), Global.GatePosition) + > 13 && Hero Of(Current Array Element) == Hero(Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + disabled Wait(0.200, Ignore Condition); + disabled Set Max Health(Global.DefaultCurrentBot, 50); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) > 3); + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Reinhardt)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Reinhardt))[0]; + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(All Players(Team 2)) < 13); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Big Message(All Players(All Teams), Custom String("BOSS WAVE FINISHED!")); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 7 - BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 7; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 9 - ECHO, +1 BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 9; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Echo))) == 0); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + "FILL EMPTY SLOTS BY ZENS" + While(Count Of(All Players(Team 2)) < 12); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("Ana Nano Variable") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + } + + actions + { + Player Closest To Reticle(Event Player, Team 1).IsNanoed = 1; + } +} + +rule("IsNanoed") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.IsNanoed == True; + } + + actions + { + If(Is Dead(Event Player)); + Event Player.IsNanoed = 0; + End; + Wait(8, Ignore Condition); + Event Player.IsNanoed = 0; + } +} + +rule("money on kill") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + actions + { + If(Hero Of(Victim) == Hero(Zenyatta)); + All Players(Team 1).Money[0] += 10 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 10 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Reinhardt)); + All Players(Team 1).Money[0] += 20 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 20 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Wrecking Ball)); + All Players(Team 1).Money[0] += 25 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 25 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Widowmaker)); + All Players(Team 1).Money[0] += 30 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 30 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Bastion)); + All Players(Team 1).Money[0] += 50 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 50 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Echo)); + All Players(Team 1).Money[0] += 75 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 75 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Orisa)); + All Players(Team 1).Money[0] += 100 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 100 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + } +} + +rule("Abilities and Hero Talents by Shingen and LemonAid") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.DamageDealt = 100; + Event Player.PlayerHealth = 100; + Event Player.Money[0] = 2400 + Global.StartMoney; + If(Custom String("{0}", Event Player) == Custom String("ShuriZma")); + Create HUD Text(Event Player, Custom String("Serverload: {0}, AVG {1}, Peak {2}", Server Load, Server Load Average, + Server Load Peak), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create HUD Text(Event Player, Custom String("Last SW: {0}, SW Active {1}", Event Player.lastSecondWind, + Event Player.secondWindActive), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + End; + } +} + +rule("Team 1 (Ability): Headhunter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[1] == True; + Event Was Critical Hit == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[1] * 40 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Ambush") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[2] == True; + Event Ability != Null; + (Y Component Of(Position Of(Event Player)) - Y Component Of(Position Of(Victim)) >= 3 || Absolute Value(Horizontal Angle Towards( + Victim, Event Player)) >= 90) == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[2] * 30 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Quick Fix") +{ + event + { + Player Earned Elimination; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[3] == True; + } + + actions + { + Heal(Event Player, Null, Event Player.Abilities[3] * 50); + Set Move Speed(Event Player, 100 + Event Player.Abilities[3] * 20); + Wait(5, Restart When True); + Set Move Speed(Event Player, 100); + } +} + +rule("Team 1 (Ability): Heavyweight") +{ + event + { + Player Dealt Knockback; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[4] == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[4] * 25 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Charged") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[5] == True; + Ultimate Charge Percent(Event Player) < Event Player.Abilities[5] * 20; + } + + actions + { + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + If(Is Duplicating(Event Player)); + Wait(0.016, Ignore Condition); + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + End; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Team 1 (Ability): Haste Primary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Primary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Primary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Primary Fire))); + } +} + +rule("Team 1 (Ability): Haste Secondary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Secondary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Secondary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Secondary Fire))); + } +} + +rule("Team 1 (Ability): Haste Ability 1") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 1)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 1))); + } +} + +rule("Team 1 (Ability): Haste Ability 2") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 2)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 2))); + } +} + +rule("Team 1 (Ability): Haste Jump") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Jump)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Jump), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Jump))); + } +} + +rule("Team 1 (Ability): Haste Crouch") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Crouch)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Crouch), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Crouch))); + } +} + +rule("Team 1 (Ability): Heavy Impact") +{ + event + { + Player Took Damage; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[7] == True; + } + + actions + { + Abort If(Random Real(-0.020, 1) > Event Damage / Max Health(Event Player)); + Set Status(Event Player, Attacker, Stunned, 1 * Attacker.Abilities[7]); + Wait(5, Ignore Condition); + } +} + +rule("Team 1 (Ability): Binding Heal") +{ + event + { + Player Dealt Healing; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[10] == True; + Healee != Event Player; + } + + actions + { + Set Player Health(Event Player, Health(Event Player) + Event Player.Abilities[10] * 0.250 * Event Healing); + } +} + +rule("Team 1 (Ability): Resilience") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[11] == True; + Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300; + } + + actions + { + Set Damage Received(Event Player, 70); + Wait Until(!(Event Player.Abilities[11] && Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Auto Repair") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.AutoRepair == True; + Global.GateHealth < Global.GateMaxHealth; + } + + actions + { + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2]); + Global.GateHealth += 10 * Global.AutoRepair; + Global.UpgradeGateMaxHealthValue += 10 * Global.AutoRepair; + Else; + Global.GateHealth += 5 * Global.AutoRepair; + Global.UpgradeGateMaxHealthValue += 5 * Global.AutoRepair; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(5, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ana Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ana), Button(Ability 1)), Custom String( + "Sleep Paralysis: Slept enemies cannot be woken up by damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Ana), Button(Ability 2)), Custom String( + "Multinade: Ana throws multiple Biotic Grenades")); + } +} + +rule("Brigitte Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Brigitte), Button(Ability 1)), Custom String( + "Heavy Iron: Hitting enemies with Whip Flail will root them in pace")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Brigitte), Button(Ultimate)), Custom String( + "Endeavor: Gain a health, damage and speed boost when your barrier breaks")); + } +} + +rule("Mercy Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mercy), Button(Ability 2)), Custom String( + "Angelic blessing: Healing an ally slowly charges their ultimate")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mercy), Button(Ultimate)), Custom String( + "Holy light missiles: Unleash blasts of holy light missiles during valkyrie")); + } +} + +rule("Lúcio Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Lúcio), Button(Secondary Fire)), Custom String( + "Healing Wave: Soundwave heals allies for 30% of their max HP")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Lúcio), Button(Ability 1)), Custom String( + "Reverse Amp: Amp It Up inflicts the opposite effect of the currently played song to enemies")); + } +} + +rule("Moira Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Moira), Button(Secondary Fire)), Custom String( + "Hose: Biotic Grasp primary will damage and push enemies back")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Moira), Button(Ability 2)), Custom String( + "Flourish: Biotic Orbs are 3x more effective")); + } +} + +rule("Baptiste Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String( + "Corrode: Regenerative Burst will damage and poison enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Breakthrough: Immortality Field HP threshold increased to 100%; allies inside gain ultimate")); + } +} + +rule("Ashe Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ashe), Button(Ability 2)), Custom String( + "Wildfire: Shooting a burning enemy ignites other nearby enemies")); + Event Player.HeroTalentText[2] = Array(Icon String(Fire), Custom String( + "Flare trigger: Coach gun instantly damages all burning enemies")); + } +} + +rule("D.Va Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(D.Va), Button(Secondary Fire)), Custom String( + "Voltage Grid: Defense Matrix will damage and root enemies it's casted over")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(D.Va), Button(Ability 1)), Custom String( + "Shooting Star: Boosters set enemies on fire")); + } +} + +rule("Genji Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Genji), Button(Ability 1)), Custom String( + "Venomous Strike: Swift Strike poisons enemies; heal for poison damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Genji), Button(Ultimate)), Custom String( + "Dragon's Breath: Dragonblade fires large explosive energy charges")); + } +} + +rule("Hanzo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Hanzo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "Stormbreak: Enemies eliminated by hanzo unleash a thundercloud")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Hanzo), Button(Ability 2)), Custom String( + "Punch II: Storm Arrows deal more damage and stun and knockback enemies")); + } +} + +rule("Widowmaker Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Widowmaker; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Widowmaker), Button(Ultimate)), Custom String( + "Kiss Of Death: Scoped critical hits against enemies below 30% health explode and instantly die")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Widowmaker), Button(Ability 2)), Custom String( + "Epidemic: Enemies hurt by Venom Mine unleash toxic pulses; heal for dealt damage")); + } +} + +rule("McCree Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Cassidy), Button(Ability 2)), Custom String( + "Panic: Flashbang puts enemies in fear; deal +120% more damage to enemies in fear")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Cassidy), Button(Ultimate)), Custom String( + "Clocked: Deadeye deals more damage and knocks enemies down")); + } +} + +rule("Reinhardt Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reinhardt), Button(Ability 2)), Custom String( + "Fire Blast: Fire Strike explodes as it deals damage, setting enemies on fire")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reinhardt), Button(Ultimate)), Custom String( + "Epicenter: Earthshatter travels in all directions")); + } +} + +rule("Soldier: 76 Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ultimate)), Custom String( + "Triple Threat: 2 more rockets are fired alongside Helix Rockets")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Soldier: 76), Button(Ability 1)), Custom String( + "Shoulder Check: Sprinting into enemies will damage and tackle them to the ground")); + } +} + +rule("Torbjörn Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Torbjörn), Button(Ability 2)), Custom String( + "Melting point: Unleash heatwaves during overload and molten core")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Torbjörn), Button(Ultimate)), Custom String( + "Roots Of Magma: Enemies trapped in Molten Core blots cannot move")); + } +} + +rule("Tracer Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Tracer), Button(Ability 2)), Custom String( + "Vortex: Recall pulls and roots enemies towards the activation point")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Tracer), Button(Ultimate)), Custom String( + "Chain Reaction: Pulse Bomb creates chain explosions on enemies damaged by it")); + } +} + +rule("Winston Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Winston), Button(Ability 2)), Custom String( + "Blast Barrier: Barrier Projector damages enemies inside the area")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Winston), Button(Ultimate)), Custom String( + "Next Generation: Eliminations during Primal Rage add +15% ultimate charge towards the next")); + } +} + +rule("Pharah Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Pharah; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ability 2)), Custom String( + "Head Trauma: Concussive Blast stuns and damages enemies for 25% of their max health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Pharah), Button(Ability 1)), Custom String( + "Thunderbird: Gain 150 shields and deal 4x the damage to barriers and objects")); + } +} + +rule("Bastion Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Bomblets: Bullets shot during sentry configuration are explosive")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ability 1)), Custom String( + "Tesla: A powerful mounted laser will autmotically attack one enemy at a time")); + } +} + +rule("Doomfist Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Jump)), Custom String( + "Phase Shifter: Immune to damage while any ability is active")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Doomfist), Button(Ultimate)), Custom String( + "Fissure: Meteor Strike leaves a large fissure behind that burns enemies over it")); + } +} + +rule("Echo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Focusing Optics: Focusing Beam damage ramp starts at 90% health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Streamline: Fire many more sticky bombs per burst")); + } +} + +rule("Junkrat Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Junkrat; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Fire), Custom String("Pyromania: All explosive attacks inflict fire damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Junkrat), Button(Ability 2)), Custom String( + "Short Fused: Steel Trap sets off violent explosions once triggered")); + } +} + +rule("Mei Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mei), Button(Ultimate)), Custom String( + "Cold Snap: Instantly freeze neaerby enemies once Cryo-Freeze expires")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mei), Button(Ability 2)), Custom String( + "Icebound: While Ice Wall is up, Icicles freeze and deal much more damage")); + } +} + +rule("Orisa Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Orisa), Button(Ability 1)), Custom String( + "Immovable Object: During Fortify, become immune and convert 50% of taken damage to healing")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Orisa), Button(Secondary Fire)), Custom String( + "Unstoppable Force: Halt! is much larger and pushes enemies. When triggered, it explodes violently")); + } +} + +rule("Reaper Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reaper), Button(Ability 1)), Custom String( + "shadow streak: shadow step creates a beam that damages enemies who cross")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reaper), Button(Ultimate)), Custom String( + "Loom: Traumatize enemies in front of you when using Wraith Form")); + } +} + +rule("Roadhog Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String("Stench: Roadhog constantly damages enemies nearby")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Roadhog), Button(Ability 1)), Custom String( + "Rusted Anchor: Hook deals more damage; Eliminations will reset hook cooldown")); + } +} + +rule("Sigma Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sigma), Button(Ability 1)), Custom String( + "Gravity Well: Kinetic Grasp gives invincibility")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sigma), Button(Ultimate)), Custom String( + "Gravity Channels: Gravitic Flux damages enemies for 75% of max hp instead of 50%")); + } +} + +rule("Sombra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sombra), Button(Secondary Fire)), Custom String( + "Malware: Enemies hacked or in fear take +100% more damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sombra), Button(Ultimate)), Custom String( + "Glitch: EMP leaves behind a large hack zone ")); + } +} + +rule("Symmetra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Symmetra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "High Voltage: Enemies eliminated by Symmetra explode and damage other enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ultimate)), Custom String( + "Energy Source: While Photon Barrier is active, all players regenerate health and gain ultimate")); + } +} + +rule("Wrecking Ball Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ultimate)), Custom String( + "Mirror Ball: Reflect 100% of taken damage to nearby enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ability 2)), Custom String( + "Distort: Adaptive Shields damages and hacks nearby enemies")); + } +} + +rule("Zarya Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zarya; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Zarya), Button(Ability 1)), Custom String( + "Augment: Health and barrier hp increased by 50%; barrier sized doubled")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Perpetual Energy: secondary inflicts burn damage that continues to last until the enemy dies")); + } +} + +rule("Zenyatta Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Vigor: The ally under the effect of Harmony Orb is immune to damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Zenyatta), Button(Ultimate)), Custom String( + "Perfect Balance: Transcendence damages enemies in a large proximity")); + } +} + +rule("Ana: Sleep Paralysis") +{ + event + { + Player Dealt Damage; + Team 1; + Ana; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Black), Victim, 1); + Wait(0.250, Ignore Condition); + Set Status(Victim, Null, Knocked Down, 5); + } +} + +rule("Ana: Multinade") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.AbilityCountdown = 4; + While(Event Player.AbilityCountdown > 0); + Wait(0.030, Ignore Condition); + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Cancel Primary Action(Event Player); + Wait(0.050, Ignore Condition); + Press Button(Event Player, Button(Ability 2)); + Event Player.AbilityCountdown -= 1; + End; + Wait(2, Ignore Condition); + } +} + +rule("Brigitte: Heavy Iron") +{ + event + { + Player Dealt Damage; + Team 1; + Brigitte; + } + + conditions + { + (Event Ability == Button(Primary Fire) || Event Ability == Button(Ability 1)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Victim, 1.500); + Set Status(Victim, Null, Rooted, 0.500); + Set Environment Credit Player(Victim, Event Player); + } +} + +rule("Brigitte: Endeavor") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Ability Cooldown(Event Player, Button(Secondary Fire)) >= 0.100; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Eye Position(Event Player), 15); + Heal(Players Within Radius(Event Player, 15, Team Of(Event Player), Off), Event Player, 200); + Event Player.DamageDealt *= 2.500; + Set Move Speed(Event Player, 100 * 1.750); + Add Health Pool To Player(Event Player, Armor, Max Health(Event Player) / 2, False, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(Is Dead(Event Player), 6); + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Move Speed(Event Player, 100); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Mercy: Angelic Blessing") +{ + event + { + Player Dealt Healing; + All; + Mercy; + } + + conditions + { + Event Player.Abilities[8] == True; + Healee != Event Player; + Normalized Health(Healee) < True; + } + + actions + { + Set Ultimate Charge(Healee, Ultimate Charge Percent(Healee) + 1); + Wait(0.400, Ignore Condition); + } +} + +rule("Mercy: Aurora") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ultimate(Event Player) == True; + } + + actions + { + Wait(1.500, Ignore Condition); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(All Teams), Event Player, True); + Create Beam Effect(All Players(All Teams), Mercy Heal Beam, Event Player, Event Player.Ability_Projectile1, Color(White), + Visible To Position and Radius); + Event Player.Effects_[3] = Last Created Entity; + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 70, Destination and Rate); + While(Event Player.Ability_End != Event Player.Ability_Projectile1); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Event Player.Ability_Projectile1, 1); + Wait(0.032, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[3]); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 120); + Loop If Condition Is True; + } +} + +rule("Lucio: Healing Wave") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4); + Heal(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 4, 4, Team Of(Event Player), Surfaces), + Event Player, Max Health(Filtered Array(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4, Team Of(Event Player), Surfaces), Is Alive(Current Array Element))) * 0.300); + } +} + +rule("Lucio: Reverse Amp") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + If(Is Using Ability 1(Event Player)); + Set Status(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Rooted, 4); + Else; + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 16.250); + End; + Play Effect(All Players(All Teams), Ring Explosion, Is Using Ability 1(Event Player) ? Color(Green) : Color(Yellow), Event Player, + 1); + Wait(0.400, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Hose") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Event Player.Abilities[8] == True; + Ability Resource(Event Player, Button(Primary Fire)) > False; + } + + actions + { + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Facing Direction Of(Event Player), 15, To World, + Cancel Contrary Motion); + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && !Is In Line of Sight(Current Array Element, Event Player, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Up, 8, To World, Cancel Contrary Motion); + Start Damage Over Time(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), + Distance Between(Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS)), Event Player, 1, 15); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Flourish - Damage") +{ + event + { + Player Dealt Damage; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("[Moira] Flourish - Healing") +{ + event + { + Player Dealt Healing; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Heal(Healee, Event Player, Event Healing * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Healee, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("Baptiste: Corrode") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 20); + Wait(0.200, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 12); + } +} + +rule("Baptiste: Breakthrough") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Status(Event Player, Unkillable) == True; + (Event Player.Abilities[12] ? Players On Hero(Hero(Baptiste), Team Of(Event Player)) : Empty Array).Abilities[12] == True; + } + + actions + { + Heal(Event Player, Event Player, 10000); + Set Status(Event Player, Null, Invincible, 0.800); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ashe: Firebourne") +{ + event + { + Player Dealt Damage; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability == Button(Primary Fire); + Has Status(Victim, Burning) == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Null, Burning, 10); + Start Damage Over Time(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Event Player, 10, 15); + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 5); + Wait(0.250, Ignore Condition); + } +} + +rule("Ashe: Taunt") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Damage(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, Burning)), + Event Player, 125); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Frozen, + 0.016); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Stunned, + 2); + } +} + +rule("D.Va: Voltage Grid") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 2, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 5, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 8, 0.500); + Wait(0.300, Ignore Condition); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Wait(0.016, Ignore Condition); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Loop If Condition Is True; + } +} + +rule("D.Va: Shooting Star") +{ + event + { + Player Dealt Knockback; + Team 1; + D.Va; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, 40); + Set Status(Victim, Null, Burning, 3); + Start Damage Over Time(Victim, Event Player, 3, 35); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 1); + } +} + +rule("Genji: Venomous Strike") +{ + event + { + Player Dealt Damage; + Team 1; + Genji; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 3, 25); + Start Damage Over Time(Victim, Event Player, 3, 25); + Damage(Victim, Event Player, 25); + Heal(Event Player, Event Player, 25); + } +} + +rule("Genji: Dragon's Breath") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is Firing Primary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Good Aura, Color(Lime Green), Event Player.Ability_Projectile1, 1, + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 80, Destination and Rate); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True); + Wait Until(Event Player.Ability_End == Event Player.Ability_Projectile1, 1); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Green), Event Player.Ability_Projectile1, 100); + Play Effect(All Players(All Teams), Bad Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Green), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 100); + } +} + +rule("[Hanzo] Stormbreak (Storm_Effects6)") +{ + event + { + Player Died; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[8] == True; + Hero Of(Attacker) == Hero(Hanzo); + } + + actions + { + Event Player.Storm_Projectile = Eye Position(Event Player); + Event Player.Storm_EndPoint = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Up * 12, Null, + All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Storm_Projectile, Event Player.Storm_EndPoint, 4, Destination and Rate); + Create Effect(All Players(All Teams), Cloud, Color(White), Vector(False, -0.500, False) + Event Player.Storm_Projectile, 4, + Visible To Position and Radius); + Event Player.Storm_Effects[3] = Last Created Entity; + Create Effect(All Players(All Teams), Bad Aura, Color(White), Event Player.Storm_Projectile, 3, Visible To Position and Radius); + Event Player.Storm_Effects[4] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(White), Event Player.Storm_Projectile, 3.500, Visible To Position and Radius); + Event Player.Storm_Effects[5] = Last Created Entity; + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Storm_Projectile, Ray Cast Hit Position( + Event Player.Storm_Projectile, Vector(0.100, 0, 0) + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), + False), Color(Aqua), Visible To Position and Radius); + Event Player.Storm_Effects[6] = Last Created Entity; + While(Distance Between(Event Player.Storm_Projectile, Event Player.Storm_EndPoint) > 1); + Wait(0.600, Ignore Condition); + Damage(Players Within Radius(Ray Cast Hit Position(Event Player.Storm_Projectile, Event Player.Storm_Projectile + Down * 1000, + Null, All Players(All Teams), False), 3, Team Of(Event Player), Surfaces), Attacker, 50); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + End; + Destroy Effect(Event Player.Storm_Effects[3]); + Destroy Effect(Event Player.Storm_Effects[4]); + Destroy Effect(Event Player.Storm_Effects[5]); + Destroy Effect(Event Player.Storm_Effects[6]); + } +} + +rule("Hanzo: Punch II") +{ + event + { + Player Dealt Damage; + Team 1; + Hanzo; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + Hero Of(Victim) != Hero(Torbjörn); + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.800); + Apply Impulse(Victim, Facing Direction Of(Event Player), 12, To World, Cancel Contrary Motion); + Apply Impulse(Victim, Up, 5, To World, Cancel Contrary Motion); + Set Environment Credit Player(Victim, Event Player); + Set Status(Victim, Null, Stunned, 1); + } +} + +rule("Widowmaker: Kiss Of Death") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + (Normalized Health(Victim) <= 0.300 || Event Damage >= Normalized Health(Victim) + Event Damage) == True; + Is Firing Secondary(Event Player) == True; + Event Ability == Button(Primary Fire); + Event Player.Abilities[8] == True; + Event Damage >= 40; + Event Was Critical Hit == True; + } + + actions + { + Kill(Victim, Event Player); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 2), Victim, 3); + Damage(Players Within Radius(Victim, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage * 1.500); + } +} + +rule("Widowmaker: Epidemic") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 8); + Play Effect(All Players(All Teams), Good Explosion, Color(Purple), Victim, 4); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Victim, 16); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Victim, 3); + Start Damage Over Time(Players Within Radius(Victim, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, 50); + Start Heal Over Time(Event Player, Event Player, 3, 50); + Wait(0.500, Ignore Condition); + } +} + +rule("McCree: Panic") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Victim.Feared_until = Total Time Elapsed + 3.500; + } +} + +rule("McCree: Panic - Damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), + Event Player.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 220, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("McCree: Clocked") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Damage(Victim, Event Player, Event Damage * 1.500); + Set Status(Victim, Null, Knocked Down, 3); + } +} + +rule("Reinhardt: Fire Blast") +{ + event + { + Player Dealt Damage; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Start Damage Over Time(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, 20); + Set Status(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Burning, 5); + } +} + +rule("Reinhardt: Epicenter") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is On Ground(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, Knocked Down, 2.500); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 10); + Damage(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, 50); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 20); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 30); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 40); + Wait(5, Ignore Condition); + } +} + +rule("[Soldier: 76] Rocket Assault Rifle") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile2 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(-2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Projectile1 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Position = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, + 0), Event Player, Rotation); + Event Player.Ability_End = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, 0), + Event Player, Rotation); + Chase Player Variable At Rate(Event Player, Ability_Position, Event Player.Ability_Projectile1, 60, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_End, Event Player.Ability_Projectile2, 60, Destination and Rate); + Wait Until(Event Player.Ability_Position == 0 && Event Player.Ability_End == 0, 2.500); + } +} + +rule("[Soldier: 76] First Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile1 != Event Player.Ability_Position; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_Position, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_Position, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_Position, 2.500); + Stop Chasing Player Variable(Event Player, Ability_Position); + Wait(0.016, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 80); + Stop Chasing Player Variable(Event Player, Ability_Position); + Event Player.Ability_Position = 0; + Event Player.Ability_Projectile1 = 0; + Wait(0.016, Ignore Condition); + } +} + +rule("[Soldier: 76] Second Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile2 != Event Player.Ability_End; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_End, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_End, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_End, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_End, 2.500); + Stop Chasing Player Variable(Event Player, Ability_End); + Damage(Players Within Radius(Event Player.Ability_End, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Event Player.Ability_End = 0; + Event Player.Ability_Projectile2 = 0; + } +} + +rule("Soldier: 76 - Init rockets") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile1 = Event Player.Ability_Position; + Event Player.Ability_Projectile2 = Event Player.Ability_End; + } +} + +rule("[Soldier: 76] Shoulder Check") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 3; + Is Alive(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) == True; + } + + actions + { + Damage(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Event Player, 55); + Set Status(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Null, Knocked Down, 1.500); + Apply Impulse(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Facing Direction Of(Event Player), 15, + To World, Cancel Contrary Motion); + Apply Impulse(Event Player, Vector(0, 8, 15), 15, To Player, Cancel Contrary Motion); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Closest Player To(Event Player, Opposite Team Of(Team Of( + Event Player))), 1); + Set Ability Cooldown(Event Player, Button(Melee), 0); + Press Button(Event Player, Button(Melee)); + Wait(1, Ignore Condition); + } +} + +rule("Torbjorn: Melting Point") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Event Player.Abilities[8] == True; + (Is Using Ability 2(Event Player) || Is Using Ultimate(Event Player)) == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Event Player, 8); + Play Effect(All Players(All Teams), Bad Explosion, Color(Yellow), Event Player, 8); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 16); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, + 25); + Set Status(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Off), Null, Burning, 3); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player, 100); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Torbjorn: Roots of Magma") +{ + event + { + Player Dealt Damage; + Team 1; + Torbjörn; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Set Status(Victim, Null, Rooted, 1); + Wait(1, Ignore Condition); + } +} + +rule("Tracer: Vortex") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, 0); + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 10); + Play Effect(All Players(All Teams), Ring Explosion, Color(Red), Position Of(Event Player), 24); + Play Effect(All Players(All Teams), Ring Explosion, Color(Yellow), Position Of(Event Player), 18); + Play Effect(All Players(All Teams), Ring Explosion, Color(Green), Position Of(Event Player), 12); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player), 6); + Set Environment Credit Player(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player); + } +} + +rule("Tracer: Vortex 2") +{ + event + { + Player Received Healing; + Team 2; + All; + } + + conditions + { + Healer.Abilities[8] == True; + Hero Of(Healer) == Hero(Tracer); + Is Using Ability 2(Healer) == True; + Event Ability == Null; + Event Damage <= 20; + } + + actions + { + Apply Impulse(Event Player, Up, 5, To World, Cancel Contrary Motion); + Wait(0.100, Ignore Condition); + Apply Impulse(Event Player, Direction Towards(Event Player, Healer), Distance Between(Event Player, Healer) * 3.500, To World, + Cancel Contrary Motion); + Set Status(Event Player, Null, Rooted, 1.300); + } +} + +rule("Tracer: Chain Reaction") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is True For Any(Filtered Array(All Players(Team Of(Event Player)), Current Array Element.Chain_Reaction_On), Distance Between( + Event Player, Current Array Element) <= 8 && True) == True; + Event Player.Chain_Reaction_Immune == False; + Event Player.Chain_Reaction_On == False; + Is Alive(Event Player) == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Event Player.Chain_Reaction_On = True; + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player, 3); + } +} + +rule("Tracer: Chain Reaction 2") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Event Player.Chain_Reaction_On == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Aqua), Event Player, 3); + Damage(Event Player, Players On Hero(Hero(Tracer), Opposite Team Of(Team Of(Event Player))), 200); + Wait(0.500, Ignore Condition); + Event Player.Chain_Reaction_Immune = True; + Event Player.Chain_Reaction_On = False; + Wait(2, Ignore Condition); + Event Player.Chain_Reaction_Immune = False; + } +} + +rule("Tracer: Chain Reaction 3") +{ + event + { + Player Dealt Damage; + Team 1; + Tracer; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Damage > 20; + Event Player.Abilities[12] == True; + } + + actions + { + Victim.Chain_Reaction_On = True; + } +} + +rule("[Winston] Electric Field") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 65); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Orb, Color(White), Event Player.Ability_Projectile1, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Stop Chasing Player Variable(Event Player, Ability_Resource); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Down * 1000, Null, + All Players(All Teams), False); + Wait(0.100, Ignore Condition); + Event Player.Ability_Resource = 5; + Wait(0.250, Ignore Condition); + Chase Player Variable At Rate(Event Player, Ability_Resource, 20, 7, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, Event Player.Ability_Resource, + Destination and Rate); + Wait(8.650, Restart When True); + Event Player.Ability_Active = False; + } +} + +rule("[Winston] Electric Field 2") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 33); + Play Effect(All Players(All Teams), Ring Explosion, Color(Blue), Event Player.Ability_Projectile1, 10); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 80); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Event Player.Ability_Projectile1, 12); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player.Ability_Projectile1, 125); + } +} + +rule("Winston: Next Generation") +{ + event + { + Player Earned Elimination; + Team 1; + Winston; + } + + conditions + { + Ultimate Charge Percent(Event Player) <= 80; + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 15); + } +} + +rule("Pharah: Head Trauma") +{ + event + { + Player Dealt Knockback; + Team 1; + Pharah; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Victim != Event Player; + } + + actions + { + Damage(Victim, Event Player, Max Health(Victim) * 0.300); + Set Status(Victim, Event Player, Knocked Down, 1); + Play Effect(All Players(All Teams), Good Explosion, Color(Team 1), Victim, 1); + } +} + +rule("Pharah: Thunderbird") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[12] == True; + Hero Of(Event Player) == Hero(Pharah); + } + + actions + { + Event Player.DamageDealt *= 4; + Start Damage Modification(All Players(All Teams), Event Player, 25, Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Add Health Pool To Player(Event Player, Shields, 150, True, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(!Event Player.Abilities[12] || Hero Of(Event Player) != Hero(Pharah), 99999); + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Stop Damage Modification(Event Player.Modification_Damage[1]); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + } +} + +rule("Orisa: Unstoppable Force") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Direction = Facing Direction Of(Event Player); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Sphere, Color(Green), Event Player.Ability_Projectile1, 4, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player) + Facing Direction Of(Event Player) * 0.500; + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 100, Null, All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 25, Destination and Rate); + Wait(0.250, Ignore Condition); + Wait Until((!Event Player.Gen_Available && Is Button Held(Event Player, Button(Secondary Fire))) || ( + Event Player.Ability_Projectile1 == Event Player.Ability_End), 99999); + Stop Chasing Player Variable(Event Player, Ability_Projectile1); + Wait(0.500, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, + 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Orisa: Availability for Halt!") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Available = True; + Wait Until(!Is Button Held(Event Player, Button(Secondary Fire)), 99999); + Event Player.Gen_Available = False; + } +} + +rule("Orisa: Drag effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Player.Ability_Active == True; + } + + actions + { + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Is Alive(Event Player) ? Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of( + Event Player)), Surfaces) : Empty Array, Event Player.Ability_Projectile1), 8, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Event Player.Ability_Projectile1, Event Player.Ability_End), 20, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Up, 5, + To Player, Cancel Contrary Motion); + Wait(0.200, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Orisa: Immoveable Object - Reduce dmg") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Damage Received(Event Player, 100 * 0.003); + Wait Until(!Is Using Ability 1(Event Player), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Orisa: Immovable Object - Healing") +{ + event + { + Player Took Damage; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Event Player, Null, Event Damage * 3); + } +} + +rule("[Reaper] Shadow Streak (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Event Player.Ability_Position = Position Of(Event Player) + Vector(0, 1, 0); + Wait(2, Abort When False); + Event Player.Ability_End = Position Of(Event Player) + Vector(0, 1, 0); + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Ability_End, Event Player.Ability_Position, Color(Black), + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player) || Is Using Ability 2(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage start to end (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players(Opposite Team Of(Team Of( + Event Player))), Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_Position, + Event Player.Ability_End, All Living Players(All Teams), Event Player, True), 1); + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage end to start (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Players(Opposite Team Of(Team Of(Event Player))), + Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_End, + Event Player.Ability_Position, All Living Players(All Teams), Event Player, True), 1); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Reaper: Loom") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Hacked, 1.500); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Rooted, 1.500); + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Event Player, 45); + } +} + +rule("Sigma: Gravity Well") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, 25); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Null, Rooted, 2); + Set Status(Event Player, Null, Invincible, 1); + Play Effect(Event Player, Ring Explosion, Color(Blue), Eye Position(Event Player), 50); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Sigma: Gravity Channels") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ultimate(Event Player)), Event Player, 150, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[12], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Echo: Focusing Optics") +{ + event + { + Player Dealt Damage; + Team 1; + Echo; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Normalized Health(Victim) > 0.500; + Normalized Health(Victim) <= 0.900; + Is Duplicating(Event Player) == False; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 3); + Play Effect(All Players(All Teams), Bad Explosion, Color(Violet), Victim, 0.500); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Wait(0.700, Abort When False); + Cancel Primary Action(Event Player); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Set Projectile Speed(Event Player, 100); + Wait(0.150, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Bomblets") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Is In Alternate Form(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Orange), Null + Ray Cast Hit Position(Eye Position(Event Player), + Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, All Living Players(Opposite Team Of(Team Of( + Event Player))), All Players(Team Of(Event Player)), True), 2); + Damage(Players Within Radius(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 2, + Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 12); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Taser - Loop damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is True For Any(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive(Current Array Element) + && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status(Current Array Element, + Phased Out) && Distance Between(Event Player, Current Array Element) <= 25) == True; + Is Alive(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Explosion Sound, Color(White), Event Player.Ability_Player, 80); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Event Player.Ability_Player, 1); + Event Player.Ability_Player = Filtered Array(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive( + Current Array Element) && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status( + Current Array Element, Phased Out) && Distance Between(Event Player, Current Array Element) <= 25); + Damage(Players Within Radius(Event Player.Ability_Player, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 30); + Wait(0.450, Ignore Condition); + Loop If Condition Is True; + Event Player.Ability_Player = Null; + } +} + +rule("Bastion: Taser - Visual beam") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player + Vector(False, 1, False), + Event Player.Ability_Player != Null ? Event Player.Ability_Player : Event Player, Color(Aqua), + Visible To Position Radius and Color); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[12], 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Sombra: Malware") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, + Hacked) || Current Array Element.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 200, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Sombra: Glitch") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Ability_Active = True; + Event Player.Ability_Position = Position Of(Event Player); + Create Effect(All Players(All Teams), Sphere, Color(Purple), Event Player.Ability_Position, 15, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait(8, Ignore Condition); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Sombra: Glitch - Loop") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Ability_Active == True; + } + + actions + { + Set Status(Players Within Radius(Event Player.Ability_Position, 15, Opposite Team Of(Team Of(Event Player)), Off), Null, Hacked, + 0.750); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Mei: Cold Snap") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Event Player, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Is Using Ability 1(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Damage(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Frozen, 2); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Rooted, 2); + Play Effect(All Players(All Teams), Ring Explosion, Color(White), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Sky Blue), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player) + Vector(0, 1, 0), 20); + } +} + +rule("Mei: Icebound") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Aqua), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Set Projectile Speed(Event Player, 200); + Wait Until(!Is Firing Secondary(Event Player), 99999); + Destroy Effect(Event Player.Effects_[2]); + Set Projectile Speed(Event Player, 100); + } +} + +rule("Mei: Icebound - Icicles hit") +{ + event + { + Player Dealt Damage; + Team 1; + Mei; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 1.250); + Set Status(Victim, Null, Frozen, 1); + Set Status(Victim, Null, Rooted, 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Victim, 1); + } +} + +rule("Wrecking Ball: Mirror Ball") +{ + event + { + Player Took Damage; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 4.500, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage); + Wait(0.100, Ignore Condition); + } +} + +rule("Wrecking Ball: Distort") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Set Status(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Hacked, Count Of( + Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces)) * 1.500); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Violet), Position Of(Event Player), 125); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Sound, Color(Purple), Position Of(Event Player), 16); + Play Effect(All Players(All Teams), Explosion Sound, Color(Violet), Position Of(Event Player), 80); + } +} + +rule("Symmetra: High voltage") +{ + event + { + Player Dealt Final Blow; + Team 1; + Symmetra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Victim, 10); + Play Effect(All Players(All Teams), Bad Explosion, Color(Aqua), Victim, 8); + Damage(Players Within Radius(Victim, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 150); + } +} + +rule("Symmetra: Energy Source") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is True For Any(Players On Hero(Hero(Symmetra), Team Of(Event Player)), Is Using Ultimate(Current Array Element) + && Current Array Element.Abilities[12]) == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 1, 40); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Event Player, 0.100); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Junkrat: Pyromania") +{ + event + { + Player Dealt Knockback; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability != Button(Melee); + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 2, 30); + Set Status(Victim, Null, Burning, 2); + } +} + +rule("Junkrat: Short Fused") +{ + event + { + Player Dealt Damage; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + } + + actions + { + Event Player.Ability_Countdown = 4; + While(Event Player.Ability_Countdown > 0); + Event Player.Ability_Countdown -= 1; + Event Player.Ability_Position = Position Of(Victim) + Vector(Random Real(-2, 2), Random Real(-2, 2), Random Real(-2, 2)); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 4); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Position, 4); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 35); + Set Status(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player, Stunned, 0.800); + Wait(0.200, Ignore Condition); + End; + } +} + +rule("Zenyatta: Vigor") +{ + event + { + Player Dealt Healing; + Team 1; + Zenyatta; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Healee, Null, Invincible, 1); + Wait(0.800, Ignore Condition); + } +} + +rule("Zenyatta: Perfect Balance") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Over Time(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 0.750, 200); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player, 24); + Wait(0.600, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Stench") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Violet), Event Player, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Roadhog: Stench effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 8; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 9); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Rusted Anchor") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ability 1(Event Player)), Event Player, 400, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Roadhog: Rusted Anchor - Reset cooldown") +{ + event + { + Player Earned Elimination; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ability 1(Event Player), 3); + Set Ability Cooldown(Event Player, Button(Ability 1), False); + } +} + +rule("Zarya: Augment") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Scaling Barriers(Event Player, 2, True); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5 + 50; + Set Max Health(Event Player, Event Player.PlayerHealth); + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Zarya), 99999); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Stop Scaling Barriers(Event Player); + } +} + +rule("Zarya: Perpetual Energy") +{ + event + { + Player Dealt Knockback; + Team 1; + Zarya; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Event Player.Abilities[12] == True; + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 9999, 15); + Set Status(Victim, Null, Burning, 9999); + } +} + +rule("Doomfist: Phase Shifter") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + (Is Firing Secondary(Event Player) || Is Using Ability 1(Event Player) || Is Using Ability 2(Event Player)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Event Player, Null, Phased Out, 1); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ultimate(Event Player), 99999); + Event Player.Ability_Position = Position Of(Event Player); + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player), 8); + Event Player.Ability_Active = False; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player.Ability_Position, 16); + While(Event Player.Ability_Active == True); + Damage(Players Within Radius(Event Player.Ability_Position, 8, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 34); + Wait(0.235, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[1]); + Destroy Effect(Event Player.Effects_[2]); + } +} + +rule("Team 1 (Perk): Sharpshooter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Global.Perk[0] == True; + Event Ability != Null; + Distance Between(Event Player, Victim) >= 10; + } + + actions + { + Damage(Victim, Event Player, 50 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Perk): Bulletstorm") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.Perk[1] == True; + (Ammo(Event Player, 0) < Max Ammo(Event Player, 0) || Ammo(Event Player, 1) < Max Ammo(Event Player, 1)) == True; + } + + actions + { + Set Ammo(Event Player, 0, 1000); + Set Ammo(Event Player, 1, 1000); + } +} + +rule("Team 1 Challenges") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + If(Global.Perk[2] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[17] = Last Text ID; + End; + If(Global.Perk[0] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[18] = Last Text ID; + End; + If(Global.Perk[1] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[19] = Last Text ID; + End; + If(Global.MaxHealthDone == 50); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + End; + } +} + +rule("Remove Auto Repair when Player leaves") +{ + event + { + Player Left Match; + Team 1; + All; + } + + actions + { + Global.AutoRepair -= Event Player.Abilities[16]; + } +} + +rule("Refund") +{ + event + { + Subroutine; + Refund; + } + + actions + { + "Refund Money" + Event Player.Money[0] += Event Player.Money[1]; + Event Player.Money[1] = 0; + "Reset Headhunter" + Event Player.Abilities[1] = 0; + "Reset Ambush" + Event Player.Abilities[2] = 0; + "Reset QuickFix" + Event Player.Abilities[3] = 0; + "Reset HeavyWeight" + Event Player.Abilities[4] = 0; + "Reset Charged" + Event Player.Abilities[5] = 0; + "Reset Haste" + Event Player.Abilities[6] = 0; + "Reset HeavyImpact" + Event Player.Abilities[7] = 0; + "Reset HeroTalent1" + Event Player.Abilities[8] = 0; + "Reset SecondWind" + Event Player.Abilities[9] = 0; + "Reset BindingHeal" + Event Player.Abilities[10] = 0; + "Reset Resilience" + Event Player.Abilities[11] = 0; + "Reset HeroTalent2" + Event Player.Abilities[12] = 0; + "Reset Damage" + Event Player.Abilities[13] = 0; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + "Reset Health" + Event Player.Abilities[14] = 0; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + If(Global.MaxHealthDone == 0); + End; + "Reset Healing" + Event Player.Abilities[15] = 0; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + "Reset AutoRepair" + Global.AutoRepair -= Event Player.Abilities[16]; + Event Player.Abilities[16] = 0; + } +} + +rule("Lucio Dash HUD Creation") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + } + + actions + { + If(Event Player.Lucio_Dash_Active == False); + Event Player.Lucio_Dash_Active = True; + Create HUD Text(Event Player, Null, Null, Custom String("{0} Slam on ground - Press: {1}", Ability Icon String(Hero(Wrecking Ball), + Button(Crouch)), Input Binding String(Button(Crouch))), Left, 1000, Color(White), Color(White), Color(White), + Visible To and String, Default Visibility); + Event Player.Lucio_Dash_Icon = Last Text ID; + End; + } +} + +rule("Lucio Dash Remove HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) != Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + } + + actions + { + Destroy HUD Text(Event Player.Lucio_Dash_Icon); + Event Player.Lucio_Dash_Active = False; + } +} + +rule("Lucio Dash") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + Is On Ground(Event Player) == False; + Is Button Held(Event Player, Button(Crouch)) == True; + } + + actions + { + Apply Impulse(Event Player, Down, 20, To World, Cancel Contrary Motion); + } +} + +rule("Ana Self-Nano") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + Ultimate Charge Percent(Event Player) == 100; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Abort If(Global.SelfNanoWorkshopSetting == False && Number Of Players(Team 1) > 1); + Wait(0.100, Ignore Condition); + If(Is Using Ultimate(Event Player) == False); + Create Dummy Bot(Hero(Ana), Team Of(Event Player), -1, Position Of(Event Player) + Backward, Eye Position(Event Player)); + Event Player.AnaEntityID = Last Created Entity; + Wait(0.100, Ignore Condition); + Set Ultimate Charge(Event Player.AnaEntityID, 100); + Start Facing(Event Player.AnaEntityID, Direction Towards(Eye Position(Event Player.AnaEntityID), Position Of(Event Player) + Up), + 1000, To World, Direction and Turn Rate); + Set Invisible(Event Player.AnaEntityID, All); + Set Status(Event Player.AnaEntityID, Null, Phased Out, 9999); + Wait(0.150, Ignore Condition); + Press Button(Event Player.AnaEntityID, Button(Ultimate)); + Set Ultimate Charge(Event Player, 0); + Wait(0.150, Ignore Condition); + Teleport(Event Player.AnaEntityID, Position Of(First Of(Spawn Points(Team Of(Event Player))))); + Wait(10, Ignore Condition); + Destroy Dummy Bot(Team Of(Event Player), Slot Of(Event Player.AnaEntityID)); + End; + } +} + +rule("Reinhard Charge Cancel") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + } + + actions + { + Wait(0.600, Ignore Condition); + Wait Until(Is Button Held(Event Player, Button(Ability 1)), 5); + Set Status(Event Player, Null, Rooted, 0.001); + Wait Until(Event Player.ReinPin, 1); + If(Event Player.ReinPin != 0); + Apply Impulse(Event Player.ReinPin, Facing Direction Of(Event Player), 15, To World, Cancel Contrary Motion); + End; + } +} + +disabled rule("Map Editor Walls") +{ + event + { + Ongoing - Global; + } +} + +rule("Initial Global") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Empty Array; + Global.AllDir = Empty Array; + Global.firstpos = Empty Array; + Global.secondpos = Empty Array; + Global.firstpoint2 = Empty Array; + Global.secondpoint2 = Empty Array; + Global.second = Empty Array; + Global.z = Empty Array; + Global.Wall_ID = Empty Array; + Global.g_beamType = Empty Array; + } +} + +rule("Initial Player") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.filterpos = 0; + Event Player.lastsavedpos = 0; + Event Player.closestbodypos = 0; + Event Player.fullbodypos = 0; + Event Player.prevpos_intersection = 0; + Event Player.active_wall = Empty Array; + Event Player.closestwall = Empty Array; + } +} + +rule("Collision Logic") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Event Player.lastsavedpos = (Eye Position(Event Player) + Position Of(Event Player)) / 2; + Wait(0.016, Ignore Condition); + Event Player.closestwall = Filtered Array(Global.AllPos, Distance Between(Global.AllPos[Current Array Index], Event Player) + <= Distance Between(Global.AllPos[Current Array Index], Global.firstpos[Current Array Index]) + || Event Player.active_wall[Current Array Index] == 1 || (Dot Product(Direction Towards(Current Array Element, + Event Player.lastsavedpos), Global.AllDir[Current Array Index]) > 0) != (Dot Product(Direction Towards(Current Array Element, + Event Player), Global.AllDir[Current Array Index]) > 0)); + For Player Variable(Event Player, x, 0, Count Of(Event Player.closestwall), 1); + Global.z = Index Of Array Value(Global.AllPos, Event Player.closestwall[Event Player.x]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3 || Global.Wall_ID[Global.z] == 5); + If(Y Component Of(Global.firstpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.firstpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.firstpos[Global.z]; + Else If(Y Component Of(Global.secondpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.secondpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.secondpos[Global.z]; + Else; + Event Player.closestbodypos = Position Of(Event Player); + End; + Event Player.fullbodypos = Vector(X Component Of(Eye Position(Event Player)), Y Component Of(Event Player.closestbodypos), + Z Component Of(Eye Position(Event Player))); + Event Player.filterpos = Event Player.fullbodypos + Global.AllDir[Global.z] * Dot Product( + Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) / Dot Product(Global.AllDir[Global.z], + Global.AllDir[Global.z]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3); + If((Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.lastsavedpos), Global.AllDir[Global.z]) > 0) != ( + Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.fullbodypos), Global.AllDir[Global.z]) > 0)); + Event Player.intersection_length = Dot Product(Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) + / Dot Product(Direction Towards(Event Player.lastsavedpos, Event Player.fullbodypos), Global.AllDir[Global.z]); + Event Player.prevpos_intersection = Event Player.fullbodypos + Direction Towards(Event Player.lastsavedpos, + Event Player.fullbodypos) * Vector(1, Empty Array, 1) * Event Player.intersection_length; + If(Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of( + Global.firstpos[Global.z]), Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], + Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of( + Global.firstpos[Global.z]), Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), + Direction Towards(Global.firstpos[Global.z], Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards( + Global.secondpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.prevpos_intersection)) + >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.secondpos[Global.z], Event Player.prevpos_intersection)) >= 0); + Cancel Primary Action(Event Player); + Teleport(Event Player, Event Player.prevpos_intersection + Direction Towards(Event Player.prevpos_intersection, + Event Player.lastsavedpos) * Vector(1, Empty Array, 1) * 2); + End; + End; + End; + Event Player.thickness = 0; + If(Global.Wall_ID[Global.z] == 5); + Event Player.thickness = 4; + Else; + Event Player.thickness = 1; + End; + If(Distance Between(Event Player.fullbodypos, Event Player.filterpos) <= Event Player.thickness && Dot Product(Direction Towards( + Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], Event Player.filterpos)) + >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.firstpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector( + X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), Z Component Of( + Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product( + Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), Y Component Of( + Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], + Event Player.filterpos)) >= 0); + If(!Global.is_Grounded); + Set Gravity(Event Player, 100); + End; + If(Event Player.active_wall[Global.z] == False); + Event Player.active_wall[Global.z] = 1; + If((Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3) && Global.is_Grounded == False); + Set Gravity(Event Player, 100); + Else If(Global.Wall_ID[Global.z] == 5); + Disable Movement Collision With Environment(Event Player, False); + End; + End; + If(Global.Wall_ID[Global.z] == 1); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos) * Vector(1, Empty Array, 1), 0.001, + To World, Cancel Contrary Motion); + Set Move Speed(Event Player, 100 - Dot Product(Direction Towards(Eye Position(Event Player), Eye Position(Event Player) + + World Vector Of(Throttle Of(Event Player), Event Player, Rotation)), Direction Towards(Event Player.filterpos, + Event Player.fullbodypos) * -1) * 100); + Else If(Global.Wall_ID[Global.z] == 3); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos), Speed Of(Event Player), To World, + Cancel Contrary Motion); + End; + Else; + Event Player.active_wall[Global.z] = 0; + Set Move Speed(Event Player, 100); + End; + End; + End; + Loop; + } +} + +rule("Reset") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Count Of(Filtered Array(Event Player.active_wall, Current Array Element != 0)) == 0; + } + + actions + { + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("Effect Creation") +{ + event + { + Ongoing - Global; + } + + actions + { + Wait(5, Ignore Condition); + If(Global.showwalls); + For Global Variable(x, 0, Count Of(Global.AllPos), 1); + If(Global.Wall_ID[Global.x] == 5); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Else; + Skip(Array(14, 0, 5, 10)[Index Of Array Value(Array(1, 2, 3), Global.g_beamType[Global.x]) + 1]); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(9); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(4); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + End; + Wait(0.016, Ignore Condition); + End; + End; + } +} + +rule("Wall Data") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Array(Vector(155.968, 12.470, -30.507), Vector(155.962, 12.472, -62.500), Vector(81.153, 6.453, -103.851), Vector( + 69.148, 6.474, -104.548)); + Global.AllDir = Array(Vector(-1, 0, -0.002), Vector(1, 0, -0.001), Vector(0, 0, 1), Vector(0.001, 0, 1)); + Global.firstpos = Array(Vector(155.971, 11.047, -31.771), Vector(155.964, 11.050, -61.229), Vector(79.761, 5.030, -103.852), + Vector(67.738, 5.022, -104.547)); + Global.secondpos = Array(Vector(155.965, 13.894, -29.242), Vector(155.960, 13.894, -63.771), Vector(82.544, 7.876, -103.851), + Vector(70.558, 7.925, -104.550)); + Global.firstpoint2 = Array(Vector(155.971, 13.894, -31.771), Vector(155.964, 13.894, -61.229), Vector(79.761, 7.876, -103.852), + Vector(67.738, 7.925, -104.547)); + Global.secondpoint2 = Array(Vector(155.965, 11.047, -29.242), Vector(155.960, 11.050, -63.771), Vector(82.544, 5.030, -103.851), + Vector(70.558, 5.022, -104.550)); + Global.z = 3; + Global.g_beamType = Array(1, 1, 1, 1); + Global.showwalls = True; + Global.Wall_ID = Array(5, 5, 5, 5); + } +} + +disabled rule("NEW SHOP") +{ + event + { + Ongoing - Global; + } +} + +rule("Setting Shop Position") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.ShopCamPos = 900 * Up; + Global.ShopPosAngle[1] = Direction From Angles(Horizontal Angle From Direction(Forward), Vertical Angle From Direction(Forward) + - 90); + Global.ShopPosAngle[0] = Cross Product(Global.ShopPosAngle[1], Forward); + Global.ShopBasePos = Global.ShopCamPos - 9 * Global.ShopPosAngle[1] + 142 * Forward; + } +} + +rule("Create Shop Buttons") +{ + event + { + Ongoing - Global; + } + + actions + { + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] + 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] - 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Refund"), + Global.ShopBasePos + 45 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 3, Do Not Clip, Visible To, Color(Green), + Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("[{0}] Leave", + Input Binding String(Button(Reload))), Global.ShopBasePos + 45 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 3, + Do Not Clip, Visible To and String, Color(Green), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("{0}$\n", Local Player.Money[0]), + Global.ShopBasePos + 36.500 * Global.ShopPosAngle[1], 3, Do Not Clip, Visible To and String, Color(White), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("▲"), Update Every Frame( + Global.ShopBasePos - (4 + Vertical Facing Angle Of(Local Player)) * Global.ShopPosAngle[1] + Horizontal Facing Angle Of( + Local Player) * Global.ShopPosAngle[0]), 4, Do Not Clip, Visible To Position and Color, Custom Color( + 245 + 10 * Sine From Radians(4 * Total Time Elapsed), 205 + 50 * Sine From Radians(4 * Total Time Elapsed), + 200 * Sine From Radians(4 * Total Time Elapsed), 255), Default Visibility); + "Headhunter" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[1] ? Custom String("Headhunter II\n  800$") : Custom String("Headhunter I\n  800$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[1] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Ambush" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[2] ? Custom String("Ambush II\n 800$") : Custom String("Ambush I\n 800$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[2] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Quick Fix" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[3] ? Custom String("Quick Fix II\n  700$") : Custom String("Quick Fix I\n  700$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[3] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavyweight" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[4] ? Custom String("Heavyweight II\n  1000$") : Custom String("Heavyweight I\n  1000$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[4] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Charged" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[5] ? Custom String("Charged II\n  700$") : Custom String("Charged I\n  700$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[5] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Haste" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[6] ? Custom String("Haste II\n 700$") : Custom String("Haste I\n 700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[6] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavy Impact" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[7] ? Custom String("Heavy Impact II\n  1000$") : Custom String("Heavy Impact I\n  1000$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[7] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 1" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 1\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[8] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "Second Wind" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[9] ? Custom String("Second Wind II\n   900$") : Custom String("Second Wind I\n   900$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[9] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Binding Heal" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[10] ? Custom String("Binding Heal II\n   700$") : Custom String("Binding Heal I\n   700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[10] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Resilience" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[11] ? Custom String("Resilience II\n  800$") : Custom String("Resilience I\n  800$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[11] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 2" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 2\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[12] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "PlusDamage" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Damage\n  400$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealth" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Health\n 400$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Healing\n  400$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, Visible To and String, + Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "+{0} Auto-Repair\n    400$", Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Global.AutoRepair < 5 ? Color(Green) : Color(Gray), Default Visibility); + "Use Update Every Frame to avoid showing the String when the cursor is out of bounds, resulting in 0\r\n ROW 0" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -33.750 ? Array(Custom String("Leave Buy Menu\n"), Custom String( + ""), Custom String(""), Custom String("Refund your money\n"))[Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) + / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, + Color(White), Default Visibility); + "ROW 1" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 22.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -11.250 ? Array(Custom String("Increase your damage by 5%\n"), + Local Player.Abilities[9] ? Custom String( + "Second Wind II: 60% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds") + : Custom String( + "Second Wind I: 30% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds"), + Local Player.Abilities[5] ? Custom String("Charged II: Ultimates cost 40% less\n") : Custom String( + "Charged I: Ultimates cost 20% less\n"), Local Player.Abilities[1] ? Custom String( + "Headhunter II: Critical hits deal 80% more damage\n") : Custom String("Headhunter I: Critical hits deal 40% more damage\n")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 2" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 36.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 11.250 ? Array(Custom String("Increase your health by 5%\n"), + Local Player.Abilities[10] ? Custom String("Binding Heal II: Heal yourself for 50% the amount when healing allies\n") + : Custom String("Binding Heal I: Heal yourself for 25% the amount when healing allies\n"), + Local Player.Abilities[6] ? Custom String( + " Haste II: Ability cooldown is reduced by 50%\nDoes not affect abilities with multiple charges") : Custom String( + " Haste I: Ability cooldown is reduced by 25%\nDoes not affect abilities with multiple charges"), + Local Player.Abilities[2] ? Custom String("Ambush II: Deal 60% more damage when attacking enemies from behind or above\n") + : Custom String("Ambush I: Deal 30% more damage when attacking enemies from behind or above\n"))[Round To Integer(( + Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 3" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 83.750) < 72.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 33.750 ? Array(Custom String("Increase your healing by 5%\n"), + Local Player.Abilities[11] ? Custom String("Resilience II: Take 30% less damage while below 60% health\n") : Custom String( + "Resilience I: Take 30% less damage while below 30% health\n"), Local Player.Abilities[7] ? Custom String( + "Heavy Impact II: Every hit has a chance to stun the enemy for 2 seconds\n") : Custom String( + "Heavy Impact I: Every hit has a chance to stun the enemy for 1 second\n"), Local Player.Abilities[3] ? Custom String( + "Quick Fix II: Eliminations restore 100 HP and shortly increase speed by 40%\n") : Custom String( + "Quick Fix I: Eliminations restore 50 HP and shortly increase speed by 20%\n"))[Round To Integer((Horizontal Facing Angle Of( + Local Player) + 90) / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, + Visible To and String, Color(White), Default Visibility); + "ROW 4" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 133) < 99.250 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 56.250 ? Array(Custom String( + "Increase your auto-repair by {0}/5s\n", Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Custom String("{0}", Local Player.HeroTalentText[2][1]), Custom String("{0}", Local Player.HeroTalentText[1][1]), + Local Player.Abilities[4] ? Custom String( + "Heavyweight II: Your knock back attacks deal 50% more damage and knock back\n            You receive 33% less knock back") + : Custom String( + "Heavyweight I: Your knock back attacks deal 25% more damage and knock back\n            You receive 20% less knock back")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + } +} + +rule("Toggle Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + !Is Dummy Bot(Event Player) == True; + Is Button Held(Event Player, Button(Reload)) == True; + !Is Communicating Any Emote(Event Player) == True; + } + + actions + { + If(Event Player.isInMenu == False); + Wait Until(!Is Button Held(Event Player, Button(Reload)), 0.500); + If(!Is Button Held(Event Player, Button(Reload))); + Abort; + End; + End; + Event Player.isInMenu = !Event Player.isInMenu; + } +} + +rule("Open Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == True; + } + + actions + { + Event Player.PlayerFacing = Facing Direction Of(Event Player); + Start Camera(Event Player, Global.ShopCamPos, Global.ShopCamPos + Forward, 0); + Disable Hero HUD(Event Player); + Call Subroutine(DisablePlayer); + Set Aim Speed(Event Player, 200); + } +} + +rule("Close Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == False; + } + + actions + { + Stop Camera(Event Player); + Enable Hero HUD(Event Player); + Call Subroutine(EnablePlayer); + Set Aim Speed(Event Player, 100); + Set Facing(Event Player, Event Player.PlayerFacing, To World); + } +} + +rule("Subroutine: Disable Player") +{ + event + { + Subroutine; + DisablePlayer; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + Set Primary Fire Enabled(Event Player, False); + Set Secondary Fire Enabled(Event Player, False); + Set Ability 1 Enabled(Event Player, False); + Set Ability 2 Enabled(Event Player, False); + Set Melee Enabled(Event Player, False); + Set Jump Enabled(Event Player, False); + Set Crouch Enabled(Event Player, False); + Disallow Button(Event Player, Button(Ultimate)); + } +} + +rule("Subroutine: Enable Player") +{ + event + { + Subroutine; + EnablePlayer; + } + + actions + { + Stop Forcing Throttle(Event Player); + Set Primary Fire Enabled(Event Player, True); + Set Secondary Fire Enabled(Event Player, True); + Set Ability 1 Enabled(Event Player, True); + Set Ability 2 Enabled(Event Player, True); + Set Melee Enabled(Event Player, True); + Set Jump Enabled(Event Player, True); + Set Crouch Enabled(Event Player, True); + Allow Button(Event Player, Button(Ultimate)); + } +} + +rule("Buy Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Primary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + Event Player.isInMenu = !Event Player.isInMenu; + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Money[1] != 0); + Call Subroutine(Refund); + Else; + Small Message(Local Player, Custom String("You don't have anything to refund!")); + End; + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[13] += 1; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 2); + If(Event Player.Money[0] >= 900); + Event Player.Money[0] -= 900; + Event Player.Money[1] += 900; + Event Player.Abilities[9] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[5] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[1] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[14] += 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[10] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[6] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[2] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[15] += 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[11] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[7] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[3] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Global.AutoRepair != 5); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Global.AutoRepair += 1; + Event Player.Abilities[16] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[12] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[8] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[4] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + End; + } +} + +rule("Refund Single Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Secondary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[13] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[13] -= 1; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 0); + Event Player.Money[0] += 900; + Event Player.Money[1] -= 900; + Event Player.Abilities[9] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[5] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[1] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[14] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[14] -= 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[10] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[6] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[2] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[15] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[15] -= 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[11] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[7] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[3] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[16] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Global.AutoRepair -= 1; + Event Player.Abilities[16] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[12] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[8] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[4] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + End; + } +} + +rule("Create Player HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Custom String("{0}{1}", + Event Player, Event Player.isInMenu ? Custom String("(In Shop)") : Custom String("")), Custom String("{0}{1}", Is Alive( + Event Player) ? Custom String("{0} HP", Round To Integer(Health(Event Player), Up)) : Custom String("Dead"), Custom String( + ", {0}$", Event Player.Money)), Left, Local Player == Event Player ? -1 : Slot Of(Event Player), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), + Visible To Sort Order String and Color, Default Visibility); + Create HUD Text(Event Player.Abilities[13] || Global.DamageDone ? Event Player : Null, Null, Null, Custom String("+{0}% Damage", + Global.DamageDone + Event Player.Abilities[13] * 5), Left, 913, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[9] ? Event Player : Null, Null, Null, Custom String("Second Wind {0}", + Event Player.Abilities[9] == 1 ? Custom String("I") : Custom String("II")), Left, 908, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[5] ? Event Player : Null, Null, Null, Custom String("Charged {0}", + Event Player.Abilities[5] == 1 ? Custom String("I") : Custom String("II")), Left, 905, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[1] ? Event Player : Null, Null, Null, Custom String("Headhunter {0}", + Event Player.Abilities[1] == 1 ? Custom String("I") : Custom String("II")), Left, 901, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[14] || Global.MaxHealthDone ? Event Player : Null, Null, Null, Custom String("+{0}% Health", + Global.MaxHealthDone + Event Player.Abilities[14] * 5), Left, 914, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[10] ? Event Player : Null, Null, Null, Custom String("Binding Heal {0}", + Event Player.Abilities[10] == 1 ? Custom String("I") : Custom String("II")), Left, 909, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[6] ? Event Player : Null, Null, Null, Custom String("Haste {0}", + Event Player.Abilities[6] == 1 ? Custom String("I") : Custom String("II")), Left, 906, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[2] ? Event Player : Null, Null, Null, Custom String("Ambush {0}", + Event Player.Abilities[2] == 1 ? Custom String("I") : Custom String("II")), Left, 902, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[15] ? Event Player : Null, Null, Null, Custom String("+{0}% Healing", + Event Player.Abilities[15] * 5), Left, 915, Color(White), Color(White), Color(Turquoise), Visible To and String, + Default Visibility); + Create HUD Text(Event Player.Abilities[11] ? Event Player : Null, Null, Null, Custom String("Resilience {0}", + Event Player.Abilities[11] == 1 ? Custom String("I") : Custom String("II")), Left, 910, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[7] ? Event Player : Null, Null, Null, Custom String("Heavy Impact {0}", + Event Player.Abilities[7] == 1 ? Custom String("I") : Custom String("II")), Left, 907, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[3] ? Event Player : Null, Null, Null, Custom String("Quick Fix {0}", + Event Player.Abilities[3] == 1 ? Custom String("I") : Custom String("II")), Left, 903, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Global.AutoRepair ? Event Player : Null, Null, Null, Custom String("{0} total Auto-Repair/5s", + Global.AutoRepair * (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5)), Left, 916, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[2][0], Event Player.HeroTalentText[2][1]), Top, 902, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("Hero Talent 2"), Left, 912, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[1][0], Event Player.HeroTalentText[1][1]), Top, 901, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("Hero Talent 1"), Left, 911, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[4] ? Event Player : Null, Null, Null, Custom String("Heavyweight {0}", + Event Player.Abilities[4] == 1 ? Custom String("I") : Custom String("II")), Left, 904, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + } +} + +rule("Rein Pin detect") +{ + event + { + Player Dealt Knockback; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 1); + Has Status(Victim, Stunned) == True; + } + + actions + { + Event Player.ReinPin = Victim; + Wait(1, Ignore Condition); + Event Player.ReinPin = Null; + } +} + +rule("Boss Rotation") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.activeBoss == True; + } + + actions + { + If(Global.bossRotation == 0 || Global.bossRotation == 3); + Global.bossRotation = 1; + Global.lastBoss[1] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 1); + Global.bossRotation = 2; + Global.lastBoss[2] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 2); + Global.bossRotation = 3; + Global.lastBoss[3] = Hero Of(Global.activeBoss); + End; + } +} + +rule("15 minutes hud") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 10; + } + + actions + { + Create HUD Text(All Players(Team 1), Global.activeBoss ? Custom String("Boss: {0}, HP: {1}/{2}", Hero Of(Global.activeBoss), + Health(Global.activeBoss), Max Health(Global.activeBoss)) : Custom String(""), Null, Null, Top, 900, Color(Red), Color(White), + Color(White), Visible To and String, Default Visibility); + } +} + +rule("debug") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + (Is Button Held(Event Player, Button(Primary Fire)) && Is Button Held(Event Player, Button(Crouch))) == True; + } + + actions + { + Global.TimeSec = 59; + } +} + +disabled rule("debug") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + } + + actions + { + Create HUD Text(Local Player, Custom String("{0}", Position Of(Local Player)), Null, Null, Left, 0, Color(Yellow), Color(White), + Color(White), Visible To and String, Default Visibility); + Set Status(Event Player, Null, Invincible, 9999); + Set Status(Event Player, Null, Phased Out, 9999); + } +} + +rule("ending 1 part 1") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("Exfiltration available! (optional - ends the mode)"), Null, Null, Top, 50, + Color(Red), Color(White), Color(White), Visible To and String, Default Visibility); + Global.GlobalHuds[1] = Last Text ID; + Create In-World Text(All Players(Team 1), Custom String( + "Exfiltration available! Gather here!\n{0}/{1} Players ready to exfiltrate!", Count Of(Filtered Array(All Players(Team 1), + Distance Between(Vector(186, 11, -46.500), Current Array Element) <= 9)), Count Of(All Players(Team 1))), Vector(186, 15, + -46.500), 1.200, Do Not Clip, Visible To and String, Color(Green), Default Visibility); + Wait(3, Ignore Condition); + Destroy HUD Text(Global.GlobalHuds[1]); + } +} + +rule("ending 1 part 2") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + Distance Between(Vector(186, 11, -46.500), All Players(Team 1)) <= 9; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GG! YOU DID IT!")); + Destroy All Dummy Bots; + Disable Movement Collision With Environment(All Players(Team 1), True); + Start Accelerating(All Players(Team 1), Up, 100, 5, To World, Direction Rate and Max Speed); + Wait(5, Ignore Condition); + Declare Team Victory(Team 1); + } +} + +rule("Team 1 (Ability): Second Wind save life") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[9] == True; + Event Player.secondWindActive == True; + Health(Event Player) == 1; + } + + actions + { + Small Message(All Players(All Teams), Custom String("{0} received a second wind!", Event Player)); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Green), Event Player, 1); + Clear Status(Event Player, Unkillable); + Set Player Health(Event Player, Max Health(Event Player)); + Event Player.lastSecondWind = 30; + Event Player.secondWindActive = 0; + } +} + +rule("Team 1 (Ability): Second Wind after buying") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[9] == True; + Event Player.secondWindActive == False; + Event Player.lastSecondWind == 0; + } + + actions + { + If(Random Integer(1, 100) > Event Player.Abilities[9] * 30); + Wait(30, Ignore Condition); + Loop; + End; + Set Status(Event Player, Null, Unkillable, 9999); + Event Player.secondWindActive = 1; + } +} + +rule("Team 1 (Ability): Second Wind counter") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Player.lastSecondWind > 0; + } + + actions + { + Wait(1, Ignore Condition); + Event Player.lastSecondWind -= 1; + Loop If Condition Is True; + } +} \ No newline at end of file diff --git a/defendTheCastleExtended/old_versions/c125.ow b/defendTheCastleExtended/old_versions/c125.ow new file mode 100644 index 0000000..a9dfed3 --- /dev/null +++ b/defendTheCastleExtended/old_versions/c125.ow @@ -0,0 +1,9350 @@ +settings +{ + main + { + Description: "Defend The Castle Extended v0.6.c125\nby ShuriZma#2349\nJ1K6F (Code Version: c125)\nOriginal mode by HuKuTa94#2589\n\nDefend the gate, kill enemies and don't allow them to damage the gate!\n\nSpecial Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents\n& Josbird for teaching me about Menus!\n\nFind this mode on: workshop.codes/defend-the-castle\nFind the Original Mode on: workshop.codes/BQEGS\nTell me what you think on Discord: discord.shurizma.de\n\nPS: SHINGEN PLS COME BACK" + Mode Name: "Defend The Castle Extended" + } + + lobby + { + Max Spectators: 0 + Max Team 1 Players: 4 + Max Team 2 Players: 0 + Return To Lobby: Never + Swap Teams After Match: No + } + + modes + { + Escort + { + enabled maps + { + Havana + } + } + + Team Deathmatch + { + enabled maps + { + } + } + + General + { + Game Mode Start: Immediately + Spawn Health Packs: Disabled + } + } + + workshop + { + Ana can nano herself even if there are other players only if no player targeted: On + Story Heroes: Off + } + + extensions + { + Beam Effects + Kinetic Explosion Effects + Explosion Sounds + Play More Effects + Spawn More Dummy Bots + } +} + +variables +{ + global: + 0: GatePosition + 1: ZenSpawnPositions + 2: SpawnPositionMaxId + 3: LoopIterator1 + 4: BigBossSpawnPositions + 5: PlayerSpawnPositions + 6: GateHealthChase + 7: GateHealth + 8: GateMaxHealth + 9: GateProgressBarColorCurrent + 10: GateProgressBarColorComponent + 11: GateHealthEvent + 12: BastionTargetPositions + 13: SniperPositions + 14: BallSpawnPositions + 15: ZenRespawnTime + 16: TimeMin + 17: TimeSec + 18: DefaultCurrentBot + 19: DefaultHeroBotsPool + 20: DefaultHeroBotsPoolCurrentId + 21: IsDebug + 22: BotOrisaParent + 23: IsStoryHeroes + 24: BotOrisaChild + 25: GateRepairPosition + 26: BotOrisaTargetPosition + 27: BotEchoRespawnPosition + 28: BotEchoTeleportPositions + 29: UpgradeGateMaxHealthValue + 30: UpgradeGateMaxHealthHudId + 31: UpgradePlayerMaxHealthValue + 32: UpgradePlayerMaxHealthHudId + 33: UpgradeCriticalDamageValue + 34: UpgradeCriticalDamageHudId + 35: UpgradeMaxAmmoValue + 36: UpgradeMaxAmmoHudId + 37: UpgradeMaxAmmoMaxValue + 38: UpgradePlayerMaxHealthMaxValue + 39: UpgradeCriticalDamageMaxValue + 40: UpgradeGateMaxHealthMaxValue + 41: DamageDone + 42: IsDebugAINavigation + 43: GameLogicCountOfUniqueHeroes + 44: IsNewWaveGameLogicProcessing + 45: AutoRepair + 46: UpgradePerkSharpshooterValue + 47: Perk + 48: MaxHealthDone + 49: StartMoney + 50: Time5Min + 51: SelfNanoWorkshopSetting + 52: ShopCamPos + 53: ShopBasePos + 54: ShopPosAngle + 55: activeBoss + 56: bossTrigger + 57: bossRotation + 58: lastBoss + 59: Time10Min + 60: MoneyMult + 61: challengeCount + 62: UpgradeBossHealthValue + 112: AllPos + 113: AllDir + 114: firstpos + 115: secondpos + 116: firstpoint2 + 117: secondpoint2 + 118: second + 119: z + 120: Wall_ID + 121: showwalls + 122: is_Grounded + 123: g_beamType + 124: x + 125: NodePositions + 126: NodeConnections + 127: DistanceMatrix + + player: + 0: BotSeePlayer + 1: BotDoesUniqueBehaviour + 2: BotEffects + 3: BotRayCastHitPosition + 4: BotEventPosition + 5: CurrentHero + 6: IsDead + 7: IsRespawning + 8: BotBastionArtilleryDidShotsCount + 9: BotCounter + 10: HasBadStatus + 11: EventHealth + 12: HealOverTimeId + 13: BotIsOrisaChild + 14: BotEchoCapturedPlayer + 15: BotPlayersInRadius + 16: BotLoopIterator2 + 17: BotWidowShotTime + 18: BotWidowTeleportTime + 19: IsNanoed + 20: AbilityHUD + 21: Lucio_Dash_Active + 22: Lucio_Dash_Icon + 23: AnaEntityID + 24: Abilities + 25: Money + 26: HeroTalentText + 27: DamageDealt + 28: PlayerHealth + 29: AbilityCountdown + 30: HP_Pool + 31: Effects_ + 32: Ability_Projectile1 + 33: Ability_End + 34: Storm_Projectile + 35: Storm_EndPoint + 36: Storm_Effects + 37: Feared_until + 38: Modification_Damage + 39: Ability_Projectile2 + 40: Ability_Position + 41: Chain_Reaction_On + 42: Chain_Reaction_Immune + 43: Ability_Active + 44: Ability_Resource + 45: secondWindActive + 46: isInMenu + 47: ReinPin + 48: PlayerFacing + 49: isBoss + 50: Gen_Direction + 51: Gen_Available + 52: Ability_Player + 53: Ability_Countdown + 54: lastSecondWind + 55: deathPosition + 105: filterpos + 106: lastsavedpos + 107: closestbodypos + 108: fullbodypos + 109: prevpos_intersection + 110: active_wall + 111: closestwall + 112: x + 113: intersection_length + 114: thickness + 115: BotCancelPathFinding + 116: BotLoopIterator1 + 117: BotTempArray + 118: BotTargetPlayer + 119: BotTargetPosition + 120: BotClosestNodeIdToTarget + 121: BotClosestNodeIdToBot + 122: BotPrevNodeId + 123: BotNextNodeId + 124: BotNextNodePosition + 125: BotCurrentDistanceToTarget + 126: BotShortestDistanceToTarget + 127: BotIsPathFinding +} + +subroutines +{ + 0: BotBastionArtilleryDamage + 1: BotBastionFlameGunDamage + 2: BotBastionRespawn + 3: GateProgressBarColor + 4: BotZenyattaRespawn + 5: BotWidowRespawn + 6: BotBallRespawn + 7: GameLogicAddNextHeroInGame + 8: BotOrisaRespawn + 9: BotLandingFromSky + 10: BotEchoRespawn + 11: BotEchoDetachPlayer + 12: BotEchoFlyToPlayer + 13: BotEchoFlyToPortal + 14: GameLogicSetBotProperties + 15: DisablePlayer + 16: BotApearFromUnderground + 17: BotReinRespawn + 18: PlayerInit + 19: BotInit + 20: PlayerRespawn + 21: BotRespawn + 22: BotWidowBadStatus + 23: GameLogicWave0 + 24: Refund + 25: EnablePlayer + 26: GateRepair + 124: BotStartPathFinding + 125: BotGetClosestNodeIdToTarget + 126: BotGetNextNodeIdAndPosition + 127: BotResetPathFinding +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("MAP: HAVANA") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Havana); + } + + actions + { + Global.NodePositions = Array(Vector(147.588, 6.425, -46.749), Vector(136.181, 6.425, -57.159), Vector(130.189, 6.425, -63.781), + Vector(123.305, 6.425, -57.983), Vector(125.678, 6.504, -46.633), Vector(114.485, 7.471, -46.699), Vector(138.743, 6.425, + -32.974), Vector(126.498, 6.425, -39.920), Vector(124.572, 10.434, -34.300), Vector(138.605, 5.359, -18.647), Vector(119.009, + 2.331, -31.024), Vector(121.138, 5.228, -19.933), Vector(126.722, 6.425, -29.505), Vector(102.762, 3.157, -33.609), Vector( + 76.030, 7.418, -74.087), Vector(83.720, 9.425, -33.744), Vector(97.439, 7.238, -42.379), Vector(86.252, 12.416, -47.261), + Vector(65.178, 11.425, -73.187), Vector(97.466, 7.269, -50.596), Vector(113.039, 7.424, -37.337), Vector(106.179, 7.450, + -46.143), Vector(90.086, 7.411, -44.653), Vector(78.752, 7.418, -62.140), Vector(82.124, 7.428, -44.229), Vector(90.675, 7.231, + -51.234), Vector(85.717, 4.692, -63.446), Vector(90.830, 4.330, -70.697), Vector(102.425, 2.387, -72.817), Vector(81.443, + 4.425, -81.648), Vector(70.743, 6.418, -81.495), Vector(69.738, 6.419, -96.344), Vector(127.586, 12.643, -63.344), Vector( + 118.911, 13.468, -58.008), Vector(102.885, 1.092, -56.579), Vector(100.009, 2.967, -67.139), Vector(106.703, 0.465, -44.628), + Vector(81.695, 7.418, -52.140), Vector(126.979, 12.393, -55.079), Vector(153.720, 18.578, -21.745), Vector(155.301, 18.619, + -17.595), Vector(133.043, 10.425, -26.625), Vector(114.646, 7.278, -57.336), Vector(95.160, 3.688, -81.194), Vector(78.456, + 5.418, -93.581), Vector(75.455, 5.418, -101.492), Vector(148.071, 9.432, -32.123), Vector(146.706, 9.425, -27.858), Vector( + 144.273, 9.445, -63.119), Vector(144.278, 9.454, -58.447)); + Global.NodeConnections = Array(Array(1, 6, 4, 7), Array(2, 1, 4, 6, 7, 0, 49), Array(1, 3), Array(2, 4, 42), Array(3, 1, 5, 7, 6, + 1, 0), Array(4, 7, 20, 21, 19, 16, 42), Array(7, 1, 4, 1, 9, 12, 0, 46), Array(4, 5, 6, 1, 1, 12, 0), Array(7, 41), Array(6, + 11), Array(11, 13), Array(9, 10, 13), Array(6, 7, 10), Array(10, 16, 36), Array(18, 23, 30), Array(17, 24), Array(13, 19, 22, + 21, 25, 5), Array(15, 22, 25, 23), Array(14), Array(16, 21, 22, 26, 27, 35, 25, 5), Array(5, 13, 10), Array(19, 16, 5, 13, 22, + 34), Array(16, 19, 21, 24, 25), Array(14, 25, 26, 37), Array(22, 15, 37), Array(23, 22, 19, 16, 26, 27, 35, 37), Array(25, 19, + 27, 35, 29), Array(19, 26, 25, 29, 35, 43), Array(35, 34, 43), Array(27, 26, 30, 43, 44), Array(29, 14, 31), Array(30, 29, 45), + Array(33, 38, 1, 48), Array(32, 38, 42), Array(35, 36, 28), Array(28, 19, 25, 27, 26, 34), Array(13, 34), Array(25, 23, 24), + Array(5, 4, 1, 6, 1, 32, 33, 0), Array(40), Array(39), Array(6, 8, 47, 46), Array(3, 5, 34), Array(28, 27, 29, 44), Array(29, + 43, 45), Array(44, 31), Array(6, 47), Array(46, 41), Array(49, 32), Array(1, 0, 6, 48)); + Global.DistanceMatrix = Array(Array(0, 1, 2, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, + 4, 5, 4, 4, 5, 5, 5, 0, 0, 4, 3, 5, 6, 7, 2, 3, 3, 2), Array(1, 0, 1, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, + 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 3, 4, 4, 4, 5, 5, 4, 0, 0, 4, 3, 5, 6, 7, 2, 3, 2, 1), Array(2, 1, 0, 1, 2, 3, 2, 2, 6, 3, 4, 4, + 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 4, 6, 7, 8, 4, 5, 3, 4, 4, 6, 5, 0, 0, 5, 2, 5, 6, 7, 3, 4, 3, 2), Array(2, 2, + 1, 0, 1, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, 5, 6, 2, 3, 3, 5, 6, 0, 0, 5, 1, 4, + 5, 6, 3, 4, 4, 3), Array(1, 1, 2, 1, 0, 1, 1, 1, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, + 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, 2, 3, 3, 2), Array(2, 2, 3, 2, 1, 0, 2, 1, 6, 3, 2, 3, 2, 2, 4, 4, 1, 5, 5, 1, 1, 1, 2, 3, + 3, 2, 2, 2, 3, 3, 4, 5, 5, 6, 2, 2, 3, 3, 6, 0, 0, 5, 1, 3, 4, 5, 3, 4, 4, 3), Array(1, 1, 2, 2, 1, 2, 0, 1, 4, 1, 2, 2, 1, 3, + 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 4, 5, 4, 4, 4, 5, 5, 0, 0, 3, 3, 5, 6, 7, 1, 2, 3, 2), Array(1, 1, 2, 2, + 1, 1, 1, 0, 5, 2, 2, 3, 1, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, + 2, 3, 3, 2), Array(2, 2, 3, 3, 2, 2, 2, 1, 0, 3, 3, 4, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, + 5, 5, 6, 0, 0, 1, 3, 5, 6, 7, 2, 2, 4, 3), Array(2, 2, 3, 3, 2, 3, 1, 2, 5, 0, 2, 1, 2, 2, 6, 6, 3, 7, 7, 4, 4, 4, 4, 5, 5, 4, + 5, 5, 5, 6, 7, 8, 5, 6, 4, 5, 3, 5, 6, 0, 0, 4, 4, 6, 7, 8, 2, 3, 4, 3), Array(4, 4, 5, 5, 4, 3, 3, 4, 7, 2, 0, 1, 4, 1, 5, 5, + 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 7, 8, 3, 4, 2, 4, 8, 0, 0, 6, 4, 5, 6, 7, 4, 5, 6, 5), Array(3, 3, 4, 4, 3, 3, + 2, 3, 6, 1, 1, 0, 3, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 6, 7, 3, 4, 2, 4, 7, 0, 0, 5, 4, 5, 6, 7, 3, 4, + 5, 4), Array(2, 2, 3, 3, 2, 2, 1, 1, 5, 2, 1, 2, 0, 2, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, 3, 5, + 6, 0, 0, 4, 3, 5, 6, 7, 2, 3, 4, 3), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 3, 1, 2, 4, 0, 4, 4, 1, 5, 5, 2, 3, 2, 2, 3, 3, 2, 3, 3, + 3, 4, 5, 6, 7, 8, 2, 3, 1, 3, 8, 0, 0, 7, 3, 4, 5, 6, 5, 6, 6, 5), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 5, 6, 6, 4, 0, 4, 3, 5, + 1, 3, 5, 4, 3, 1, 3, 2, 2, 3, 4, 2, 1, 2, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 3, 3, 3, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, + 5, 10, 7, 5, 6, 6, 4, 3, 0, 3, 1, 4, 3, 5, 3, 2, 2, 1, 2, 3, 3, 4, 4, 4, 5, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 4, 5, 6, 7, 8, + 8, 7), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 3, 3, 0, 4, 4, 1, 2, 1, 1, 2, 2, 1, 2, 2, 3, 3, 4, 5, 6, 7, 2, 2, 2, 2, + 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 1, 2, 0, 3, 2, 4, 2, 1, 1, 2, 1, 2, 2, + 3, 3, 3, 4, 8, 9, 3, 2, 4, 2, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 6, 7, 7, 5, 1, 5, 4, 6, + 0, 4, 6, 5, 4, 2, 4, 3, 3, 4, 5, 3, 2, 3, 10, 11, 5, 4, 6, 3, 11, 0, 0, 10, 6, 4, 4, 4, 8, 9, 9, 8), Array(3, 3, 4, 3, 2, 1, 3, + 2, 7, 4, 3, 4, 3, 2, 3, 3, 1, 4, 4, 0, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 3, 4, 6, 7, 2, 1, 3, 2, 7, 0, 0, 6, 2, 2, 3, 4, 4, 5, 5, + 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 3, 1, 2, 3, 1, 5, 5, 2, 6, 6, 2, 0, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 6, 7, 3, 3, 2, 4, 7, + 0, 0, 6, 2, 4, 5, 6, 4, 5, 5, 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 4, 3, 1, 4, 5, 1, 2, 0, 1, 3, 2, 2, 2, 2, 2, + 3, 4, 5, 6, 7, 1, 2, 2, 3, 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 3, 2, 1, 3, 4, + 1, 3, 1, 0, 2, 1, 1, 2, 2, 3, 3, 4, 5, 7, 8, 2, 2, 3, 2, 8, 0, 0, 7, 3, 3, 4, 5, 5, 6, 6, 5), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, + 6, 4, 5, 5, 3, 1, 3, 2, 4, 2, 2, 4, 3, 2, 0, 2, 1, 1, 2, 3, 2, 2, 3, 8, 9, 3, 2, 4, 1, 9, 0, 0, 8, 4, 3, 3, 4, 6, 7, 7, 6), + Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 3, 1, 2, 2, 4, 2, 4, 2, 1, 2, 0, 2, 3, 3, 4, 4, 4, 5, 8, 9, 3, 3, 4, 1, 9, 0, + 0, 8, 4, 4, 5, 6, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 2, 3, 1, 4, 3, 1, 3, 2, 1, 1, 2, 0, 1, 1, 2, 2, + 3, 4, 7, 8, 2, 1, 3, 1, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, + 3, 2, 2, 2, 3, 1, 0, 1, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 2, 2, 3, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, + 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 0, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 1, 2, 3, 5, 6, 6, 5), Array( + 5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 4, 5, 3, 6, 5, 2, 4, 3, 3, 3, 4, 2, 2, 2, 0, 2, 3, 4, 8, 9, 1, 1, 2, 3, 9, 0, 0, 8, + 4, 1, 2, 3, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 2, 5, 3, 6, 3, 2, 4, 3, 3, 3, 4, 2, 1, 1, 2, 0, 1, 2, + 8, 9, 3, 2, 4, 3, 9, 0, 0, 8, 4, 1, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 1, 5, 4, 6, 2, 3, 5, 4, + 4, 2, 4, 3, 2, 2, 3, 1, 0, 1, 9, 10, 4, 3, 5, 3, 10, 0, 0, 9, 5, 2, 2, 2, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, + 7, 6, 5, 2, 6, 4, 7, 3, 3, 5, 4, 4, 3, 5, 3, 2, 2, 3, 1, 1, 0, 9, 10, 4, 3, 5, 4, 10, 0, 0, 9, 5, 2, 2, 1, 7, 8, 8, 7), Array( + 2, 1, 2, 3, 2, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 4, 5, 6, 7, 0, 1, 3, 4, 4, 5, 1, 0, 0, 5, + 2, 5, 6, 7, 3, 4, 1, 2), Array(2, 2, 3, 2, 2, 2, 2, 3, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, + 1, 0, 2, 3, 3, 5, 1, 0, 0, 5, 1, 4, 5, 6, 3, 4, 2, 3), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 5, 3, 4, 5, 2, 4, 5, 3, 6, 5, 2, 4, 3, + 3, 3, 4, 2, 2, 2, 1, 3, 4, 5, 8, 9, 0, 1, 1, 3, 9, 0, 0, 8, 4, 2, 3, 4, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, + 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 1, 1, 2, 3, 4, 7, 8, 1, 0, 2, 2, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(5, 5, + 6, 5, 4, 3, 5, 4, 9, 4, 2, 3, 5, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 8, 9, 1, 2, 0, 4, 9, 0, 0, 8, 4, 3, + 4, 5, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 2, 2, 3, 3, 2, 4, 3, 2, 1, 1, 1, 2, 2, 3, 3, 3, 4, 8, 9, + 3, 2, 4, 0, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(1, 1, 2, 2, 1, 1, 1, 2, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, + 4, 3, 3, 3, 4, 4, 5, 6, 1, 1, 3, 3, 4, 4, 0, 0, 0, 4, 2, 4, 5, 6, 2, 3, 2, 2), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(2, 2, 3, 3, 2, 3, 1, 2, 1, 2, 3, 3, 2, + 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 0, 4, 6, 7, 8, 1, 1, 4, 3), Array(3, 3, 2, + 1, 2, 1, 3, 2, 7, 4, 3, 4, 3, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 6, 7, 1, 2, 2, 4, 7, 0, 0, 6, 0, 3, 4, + 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 3, 5, 3, 6, 4, 2, 4, 3, 3, 3, 4, 2, 2, 1, 1, 1, 2, 3, 8, 9, 2, + 2, 3, 3, 9, 0, 0, 8, 4, 0, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 3, 6, 4, 7, 4, 3, 5, 4, 4, 4, 5, + 3, 2, 2, 2, 1, 2, 2, 9, 10, 3, 3, 4, 4, 10, 0, 0, 9, 5, 1, 0, 1, 7, 8, 8, 7), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 7, 8, 7, 6, + 3, 7, 5, 8, 4, 4, 6, 5, 5, 4, 6, 4, 3, 3, 3, 2, 2, 1, 10, 11, 4, 4, 5, 5, 11, 0, 0, 10, 6, 2, 1, 0, 8, 9, 9, 8), Array(2, 2, 3, + 3, 2, 3, 1, 2, 3, 2, 3, 3, 2, 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 2, 4, 6, 7, + 8, 0, 1, 4, 3), Array(3, 3, 4, 4, 3, 4, 2, 3, 2, 3, 4, 4, 3, 5, 8, 8, 5, 9, 9, 5, 5, 5, 6, 7, 7, 6, 6, 6, 7, 7, 8, 9, 6, 7, 6, + 6, 6, 7, 7, 0, 0, 1, 5, 7, 8, 9, 1, 0, 5, 4), Array(2, 2, 3, 4, 3, 3, 2, 3, 6, 3, 4, 4, 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, + 5, 5, 5, 5, 6, 7, 8, 1, 2, 4, 5, 5, 6, 2, 0, 0, 5, 3, 6, 7, 8, 3, 4, 0, 1), Array(1, 1, 2, 3, 2, 3, 1, 2, 5, 2, 3, 3, 2, 4, 7, + 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 2, 3, 5, 5, 5, 6, 3, 0, 0, 4, 4, 6, 7, 8, 2, 3, 1)); + } +} + +rule("SUBROUTINE: BOT - RESET PATH FINDING") +{ + event + { + Subroutine; + BotResetPathFinding; + } + + actions + { + Event Player.BotTargetPlayer = -1; + Event Player.BotTargetPosition = -1; + Event Player.BotPrevNodeId = -1; + Event Player.BotClosestNodeIdToTarget = -1; + Event Player.BotNextNodeId = -1; + Event Player.BotNextNodePosition = -1; + Event Player.BotIsPathFinding = False; + Event Player.BotCancelPathFinding = False; + Stop Throttle In Direction(Event Player); + disabled Stop Facing(Event Player); + } +} + +rule("SUBROUTINE: BOT - START PATH FINDING") +{ + event + { + Subroutine; + BotStartPathFinding; + } + + actions + { + disabled Abort If(Event Player.BotIsPathFinding == True); + Call Subroutine(BotGetNextNodeIdAndPosition); + disabled Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Event Player.BotIsPathFinding = True; + } +} + +rule("SUBROUTINE: BOT - GET NEXT NODE ID AND POSITION") +{ + event + { + Subroutine; + BotGetNextNodeIdAndPosition; + } + + actions + { + "BOT JUST START FOLLOW PATH OR LOST NEXT NODE" + If(Event Player.BotPrevNodeId == -1); + Event Player.BotClosestNodeIdToBot = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array(Global.NodePositions, + Is In Line of Sight(Position Of(Event Player) + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS) == True), + Distance Between(Position Of(Event Player), Current Array Element))[0]); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + "NEXT NODE IS TARGET (DISTANCE TO TARGET NODE = 1)" + If(Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1); + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToTarget; + "CHECK CONNECTIONS OF REACHED NODE" + Else; + Event Player.BotShortestDistanceToTarget = 999; + Event Player.BotCurrentDistanceToTarget = Event Player.BotShortestDistanceToTarget; + Event Player.BotTempArray = Global.NodeConnections[Event Player.BotClosestNodeIdToBot]; + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotTempArray), 1); + Event Player.BotCurrentDistanceToTarget = Global.DistanceMatrix[Event Player.BotTempArray[Event Player.BotLoopIterator1]][Event Player.BotClosestNodeIdToTarget]; + If(Event Player.BotCurrentDistanceToTarget < Event Player.BotShortestDistanceToTarget); + Event Player.BotShortestDistanceToTarget = Event Player.BotCurrentDistanceToTarget; + Event Player.BotNextNodeId = Event Player.BotTempArray[Event Player.BotLoopIterator1]; + End; + End; + End; + "NEXT NODE IS HIGHER THAN BOT AND BOT DIDN'T REACH CLOSEST NODE" + If(Y Component Of(Position Of(Event Player)) - Y Component Of(Global.NodePositions[Event Player.BotNextNodeId]) + < -3 && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + "BOT CAN SEE TARGET POSITION AND NEXT NODE IS TARGET" + Else If( + Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1 && Is In Line of Sight( + Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotTargetPosition + Vector(0, 2, 0), Barriers Do Not Block LOS)); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Abort; + "BOT CAN'T SEE NEXT NODE AND PREV NODE != REACHED NODE" + Else If(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), + Global.NodePositions[Event Player.BotNextNodeId] + Vector(0, 2, 0), Barriers Do Not Block LOS) + == False && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + End; + Event Player.BotNextNodePosition = Global.NodePositions[Event Player.BotNextNodeId]; + } +} + +rule("SUBROUTINE: BOT - GET CLOSEST NODE ID AND POSITION TO TARGET") +{ + event + { + Subroutine; + BotGetClosestNodeIdToTarget; + } + + actions + { + Event Player.BotTargetPosition = Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Event Player.BotTargetPosition; + Event Player.BotClosestNodeIdToTarget = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array( + Global.NodePositions, Is In Line of Sight(Event Player.BotTargetPosition + Vector(0, 2, 0), Current Array Element, + Barriers Do Not Block LOS) == True), Distance Between(Event Player.BotTargetPosition, Current Array Element))[0]); + } +} + +rule("BOT: PATH FINDING - START") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + (Event Player.BotTargetPosition != -1 || Event Player.BotTargetPlayer != -1) == True; + } + + actions + { + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - CANCEL") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotCancelPathFinding == True; + } + + actions + { + Start Rule(BotResetPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - LOST THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + (Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotNextNodePosition + Vector(0, 2.500, 0), + Barriers Do Not Block LOS) == False && Speed Of In Direction(Event Player, Throttle Of(Event Player)) < 2) == True; + } + + actions + { + Wait(0.500, Abort When False); + "RESET PREV NODE ID TO INFORM BOT THAT IT LOST NEXT NODE" + Event Player.BotPrevNodeId = -1; + "TRY FIND NEW NEXT NODE" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodeId), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +rule("BOT: PATH FINDING - REACHED THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotClosestNodeIdToTarget >= 0; + (Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotNextNodePosition), 0, Z Component Of(Event Player.BotNextNodePosition))) < 0.850) == True; + } + + actions + { + Event Player.BotPrevNodeId = Event Player.BotNextNodeId; + Event Player.BotClosestNodeIdToBot = Event Player.BotNextNodeId; + "BOT'S TARGET IS PLAYER" + If(Event Player.BotTargetPlayer != -1); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + Event Player.BotCurrentDistanceToTarget = Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of( + Position Of(Event Player))), Vector(X Component Of(Event Player.BotTargetPosition), 0, Z Component Of( + Event Player.BotTargetPosition))); + "BOT REACHED THE TARGET NODE OR TARGET POSITION" + If(Event Player.BotNextNodeId == Event Player.BotClosestNodeIdToTarget || Event Player.BotCurrentDistanceToTarget <= 0.850); + "BOT DIDN'T REACH TARGET POSITION" + If(Event Player.BotCurrentDistanceToTarget > 0.850); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Skip(6); + "BOT REACHED TARGET" + Else; + Call Subroutine(BotResetPathFinding); + Abort; + End; + End; + "CONTINUE FOLLOW PATH" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: GAME MODE INIT - WORKSHOP SETTINGS") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.IsDebug = False; + Global.IsDebugAINavigation = False; + Global.GateMaxHealth = Workshop Setting Integer(Custom String("Defend The Castle Extended"), Custom String("GATE MAX HEALTH"), 500, 100, 1000, + 0); + Global.MoneyMult = Workshop Setting Real(Custom String("Defend The Castle Extended"), Custom String("Money Multiplicator"), 1, 0.500, 2, 0); + Global.IsStoryHeroes = Workshop Setting Toggle(Custom String("Defend The Castle Extended"), Custom String("Story Heroes"), True, 0); + Global.SelfNanoWorkshopSetting = Workshop Setting Toggle(Custom String("Ana Self Nano"), Custom String( + "Ana can nano herself even if there are other players (only if no player targeted)"), False, 0); + } +} + +rule("GLOBAL: GAME MODE INIT - COMMON PROPERTIES") +{ + event + { + Ongoing - Global; + } + + actions + { + Create HUD Text(All Players(All Teams), Null, Null, Custom String( + "Defend The Castle Extended v0.6.c125 BY ShuriZma#2349\r\nOriginal mode by HUKUTA94#2589\r\nDiscord: discord.shurizma.de\r\n{0}", Custom String( + "Special Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents &\nJosbird for teaching me about Menus{0}", + Custom String(" \nPS: SHINGEN PLS COME BACK"))), Right, -1000, Null, Null, Color(White), Visible To, + Default Visibility); + Global.GateRepairPosition = Vector(153, 8, -46.500); + Global.GatePosition = Vector(148.800, 6, -46.400); + Global.BallSpawnPositions = Array(Vector(104, 7, -46), Vector(106, 2, -31)); + Global.SniperPositions = Array(Vector(154, 18, -22.600), Vector(86, 12, -46.600), Vector(80.880, 11.300, -71.600), Vector(98, 9, + -19)); + Global.ZenSpawnPositions = Array(Vector(79.500, 5, -100), Vector(90, 4, -88), Vector(65, 11, -70), Vector(85, 4, -68), Vector(96, + 2, -73), Vector(84, 7, -47), Vector(95, 9, -34), Vector(108, 1.700, -28), Vector(113, 7, -37), Vector(123, 5, -19), Vector(144, + 5, -19), Vector(123, 6, -39), Vector(123, 6, -61), Vector(129, 6, -30.500), Vector(135, 6, -63)); + Global.PlayerSpawnPositions = Array(Vector(153.300, 10, -63.800), Vector(153.300, 10, -61.700), Vector(153.300, 10, -31.700), + Vector(153.300, 10, -29.600)); + Global.BigBossSpawnPositions = Array(Vector(78, 4, -84), Vector(95, 4, -82)); + Global.BastionTargetPositions = Array(Vector(131, 12, -62), Vector(115, 7, -46), Objective Position(2), Vector(136, 10, -27)); + Global.SpawnPositionMaxId = 2; + Global.BotOrisaTargetPosition = Vector(104, 7, -46); + Global.BotEchoRespawnPosition = Vector(130, 23, -44); + Global.BotEchoTeleportPositions = Array(Vector(88, 23, -79), Vector(108, 18, -27)); + Global.DefaultHeroBotsPool = Array(Hero(Zenyatta), Hero(Widowmaker), Null, Hero(Bastion), Hero(Echo), Hero(Bastion)); + Global.ZenRespawnTime = 10; + Global.GameLogicCountOfUniqueHeroes = 5; + Global.lastBoss = Array(Null, Null, Null, Null); + Create Effect(All Players(Team 1), Ring, Color(Sky Blue), Vector(186, 11, -46.500), 9, Visible To Position and Radius); + Create Effect(All Players(Team 1), Ring, Color(Yellow), Vector(153.300, 10, -61.700), 2, Visible To Position and Radius); + } +} + +disabled rule("PLAYER: DEBUG - PRESS INTERACT") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Host Player == True; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + disabled Modify Player Score(Event Player, 10); + disabled Global.GateHealth -= 5; + disabled Start Rule(GateProgressBarColor, Restart Rule); + Global.TimeSec = 59; + Set Status(Event Player, Null, Phased Out, 9999); + disabled Set Ultimate Charge(Event Player, 100); + disabled Kill(Event Player, Null); + disabled Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: DEBUG - AI NAVIGATION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.IsDebugAINavigation == True; + } + + actions + { + For Global Variable(LoopIterator1, 0, Count Of(Global.NodePositions), 1); + Create Effect(All Players(All Teams), Sphere, Color(Red), Global.NodePositions[Global.LoopIterator1], 0.850, Visible To); + Create In-World Text(All Players(All Teams), Custom String("NODE {0}", Global.LoopIterator1), + Global.NodePositions[Global.LoopIterator1], 1.200, Clip Against Surfaces, Visible To, Color(White), Default Visibility); + End; + } +} + +disabled rule("GLOBAL: DEBUG - CREATE BOTS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + Create Dummy Bot(Hero(Bastion), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + Create Dummy Bot(Hero(Orisa), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +disabled rule("PLAYER: DEBUG - INFOS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + Host Player == Event Player; + Has Spawned(Event Player) == True; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Create HUD Text(Event Player, Custom String("POS {0}\r\nFACING {1}", Position Of(Event Player), Facing Direction Of(Event Player)), + Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + Create HUD Text(Event Player, Custom String("SERVER PERFORMANCE\r\nLOAD {0}%\r\nPEAK {1}%\r\nAVG {2}%", Server Load, + Server Load Peak, Server Load Average), Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create Progress Bar HUD Text(Event Player, 45, Custom String("45 / 100 KILLS"), Left, -99, Color(Blue), Color(White), + Visible To Values and Color, Default Visibility); + disabled Create HUD Text(Event Player, Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Null, Custom String( + "LEVEL 1 - 50 AMMO CLIP"), Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + "ЭФФЕКТ С ОФФСЕТОМ ОТ ПОЗИЦИИ ГЛАЗ" + disabled Create Beam Effect(All Players(All Teams), Bad Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + Facing Direction Of( + Event Player) * 3, Eye Position(Event Player) + Facing Direction Of(Event Player) * 50, Color(Purple), + Visible To Position and Radius); + } +} + +disabled rule("=== TEAM UPGRADES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: TEAM UPGRADES - INIT") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.UpgradeMaxAmmoMaxValue[0] = 250; + Global.UpgradeMaxAmmoMaxValue[1] = 500; + Global.UpgradeMaxAmmoMaxValue[2] = 1000; + Global.UpgradeCriticalDamageMaxValue[0] = 10; + Global.UpgradeCriticalDamageMaxValue[1] = 5; + Global.UpgradeCriticalDamageMaxValue[2] = 5; + Global.UpgradePlayerMaxHealthMaxValue[0] = 2500; + Global.UpgradePlayerMaxHealthMaxValue[1] = 5000; + Global.UpgradePlayerMaxHealthMaxValue[2] = 10000; + Global.UpgradeGateMaxHealthMaxValue[0] = Round To Integer(Global.GateMaxHealth + Global.GateMaxHealth * 0.500, Up); + Global.UpgradeGateMaxHealthMaxValue[1] = Global.UpgradeGateMaxHealthMaxValue[0] + Global.UpgradeGateMaxHealthMaxValue[0]; + Global.UpgradeGateMaxHealthMaxValue[2] = Global.UpgradeGateMaxHealthMaxValue[1] + Global.UpgradeGateMaxHealthMaxValue[1]; + Abort If(Global.IsDebug == False); + Global.UpgradeMaxAmmoMaxValue[0] = 1; + Global.UpgradeCriticalDamageMaxValue[0] = 1; + Global.UpgradePlayerMaxHealthMaxValue[0] = 1; + Global.UpgradeGateMaxHealthMaxValue[0] = 1; + Global.UpgradeMaxAmmoMaxValue[1] = 1; + Global.UpgradeCriticalDamageMaxValue[1] = 1; + Global.UpgradePlayerMaxHealthMaxValue[1] = 1; + Global.UpgradeGateMaxHealthMaxValue[1] = 1; + Global.UpgradeMaxAmmoMaxValue[2] = 1; + Global.UpgradeCriticalDamageMaxValue[2] = 1; + Global.UpgradePlayerMaxHealthMaxValue[2] = 1; + Global.UpgradeGateMaxHealthMaxValue[2] = 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GATE'S MAX HEALTH UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Global.GateMaxHealth = Global.UpgradeGateMaxHealthMaxValue[0]; + Global.GateHealth = Global.GateMaxHealth; + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Right, 1, Color( + Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X GATE REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[1]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X GATE REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X GATE REPAIR"), Right, 2, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X AUTO-REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[2]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[2] = Last Text ID; + Global.GateHealth = Global.GateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 3 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X AUTO-REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X AUTO-REPAIR"), Right, 3, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.UpgradeGateMaxHealthHudId[2] = Last Text ID; + Global.GateHealth = Global.GateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - PLAYER'S MAX HEALTH - DEALT HEALING") +{ + event + { + Player Received Healing; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + disabled Healer != Event Player; + Global.UpgradePlayerMaxHealthValue < Global.UpgradePlayerMaxHealthMaxValue[2]; + } + + actions + { + Global.UpgradePlayerMaxHealthValue += Event Healing; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +50%"), Right, 4, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("Up You Go: You respawn twice as fast"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[1]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.MaxHealthDone = 50; + All Players(Team 1).PlayerHealth = 100 + Global.MaxHealthDone + All Players(Team 1).Abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).PlayerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK UP YOU GO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("UP YOU GO UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String("Up You Go"), + Right, 5, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +100%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[2]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[2] = Last Text ID; + Set Respawn Max Time(All Players(Team 1), 5); + Heal(All Players(Team 1), Null, 9999); + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.Perk[2] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[17] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH 2 UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +100%"), Right, 6, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[2] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.MaxHealthDone = 150; + All Players(Team 1).PlayerHealth = 100 + Global.MaxHealthDone + All Players(Team 1).Abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).PlayerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Hero Of(Victim) == Hero(Widowmaker); + Global.UpgradeCriticalDamageValue < Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradeCriticalDamageValue += 1; + Small Message(All Players(Team 1), Custom String("CRITICAL DAMAGE CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - CRITICAL DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("CRITICAL DAMAGE 150% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "CRITICAL DAMAGE 150%"), Right, 7, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String( + "Sharpshooter: Deal 40% more damage to enemies that are further than 15 meters away"), Custom String("KILL ECHO {0}/{1}", + Global.UpgradePerkSharpshooterValue, Global.UpgradeCriticalDamageMaxValue[1]), Left, 14, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - UNLOCKED") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.500); + } +} + +rule("PLAYER: UPGRADE - PERK SHARPSHOOTER - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Echo); + Global.UpgradePerkSharpshooterValue < Global.UpgradeCriticalDamageMaxValue[1]; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradePerkSharpshooterValue += 1; + Small Message(All Players(Team 1), Custom String("SHARPSHOOTER CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - PERK SHARPSHOOTER - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("SHARPSHOOTER UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Sharpshooter"), Right, 8, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("-10% BOSS HEALTH"), Custom String("KILL Bosses {0}/{1}", + Global.UpgradeBossHealthValue, Global.UpgradeCriticalDamageMaxValue[2]), Left, 14, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[2] = Last Text ID; + Global.Perk[0] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[18] = Last Text ID; + Global.challengeCount += 1; + } +} + +disabled rule("PLAYER: UPGRADE - -10% BOSS HEALTH - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]; + Global.UpgradeBossHealthValue < Global.UpgradeCriticalDamageMaxValue[2]; + Victim.isBoss == 1; + } + + actions + { + Global.UpgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - -10% BOSS HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("-10% BOSS HEALTH UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "-10% BOSS HEALTH"), Right, 9, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[2] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - MAX AMMO - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Zenyatta); + Global.UpgradeMaxAmmoValue < Global.UpgradeMaxAmmoMaxValue[2]; + } + + actions + { + If(Event Player.isBoss == 1); + Global.UpgradeMaxAmmoValue += 10; + Else; + Global.UpgradeMaxAmmoValue += 1; + End; + } +} + +rule("GLOBAL: UPGRADE - MAX AMMO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("MAX AMMO 200% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "MAX AMMO 200%"), Right, 10, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("Bulletstorm: Your weapon can hold unlimited ammo"), + Custom String("KILL {2}: {0}/{1}", Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[1], Hero(Zenyatta)), Left, 15, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0) * 2); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1) * 2); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0)); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1)); + End; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK BULLETSTORM - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("BULLETSTORM UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Bulletstorm"), Right, 11, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("+50% DAMAGE"), Custom String("KILL {2}: {0}/{1}", + Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[2], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[2] = Last Text ID; + Global.Perk[1] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[19] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - +50% DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("+50% DAMAGE UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "+50% DAMAGE"), Right, 12, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[2] = Last Text ID; + Global.DamageDone = 50; + All Players(Team 1).DamageDealt = 100 + Global.DamageDone + All Players(Team 1).Abilities[13] * 5; + Set Damage Dealt(All Players(Team 1), All Players(Team 1).DamageDealt); + Global.challengeCount += 1; + } +} + +disabled rule("=== GAME PHASES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: ASEMBLING PHASE - MAKE CHALLENGES HUDS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Assembling Heroes == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Disable Inspector Recording; + Set Match Time(20); + End; + Create In-World Text(All Players(Team 1), Custom String(" {0}\r\nREPAIR\r\n {1}", Hero Icon String(Hero(Torbjörn)), + Ability Icon String(Hero(Bastion), Button(Secondary Fire))), Global.GatePosition + Vector(0, 1.400, 0), 1.200, Do Not Clip, + Visible To, Color(White), Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("TEAM CHALLENGES"), Left, 11, Color(White), Color(Blue), Color( + White), Visible To, Default Visibility); + "UPGRADE - GATE'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String( + "GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Custom String("REPAIR GATE {0}/{1} HP", + Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[0]), Left, 12, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 2, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - PLAYER'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +50%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[0]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 4, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - CRITICAL DAMAGE" + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("CRITICAL DAMAGE 150%"), Custom String( + "KILL WIDOW WITH HEADSHOT: {0}/{1}", Global.UpgradeCriticalDamageValue, Global.UpgradeCriticalDamageMaxValue[0]), Left, 14, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 6, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - MAX AMMO" + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("MAX AMMO 200%"), Custom String("KILL {2}: {0}/{1}", + Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[0], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Custom String("HOLD {0} - Reload to open the shop", Input Binding String(Button(Reload))), + Null, Null, Top, 1000, Color(Yellow), Color(White), Color(White), Visible To and String, Default Visibility); + } +} + +rule("GLOBAL: SETUP PHASE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Set Match Time(20); + End; + Set Objective Description(All Players(All Teams), Custom String("DEFEND GATE"), Visible To and String); + } +} + +rule("GLOBAL: GAME IN PROGRESS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + } + + actions + { + Set Match Time(3599); + Pause Match Time; + Disable Built-In Game Mode Scoring; + Disable Built-In Game Mode Announcer; + Disable Built-In Game Mode Completion; + Disable Game Mode HUD(All Players(All Teams)); + Disable Game Mode In-World UI(All Players(All Teams)); + Global.GateHealth = Global.GateMaxHealth; + Global.GateHealthChase = Global.GateHealth; + Global.GateProgressBarColorComponent = 255; + Global.GateProgressBarColorCurrent = Color(White); + Create Progress Bar HUD Text(All Players(Team 1), Global.GateHealthChase * 100 / Global.GateMaxHealth, Custom String( + "GATE {0}/{1}", Global.GateHealth, Global.GateMaxHealth), Top, 1, Global.GateProgressBarColorCurrent, Color(White), + Visible To Values and Color, Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("SURVIVED TIME: {0}:{1}", Global.TimeMin, + Global.TimeSec < 10 ? Custom String("0{0}", Global.TimeSec) : Global.TimeSec), Top, 2, Color(White), Color(White), Color( + White), Visible To and String, Default Visibility); + Start Rule(GameLogicWave0, Do Nothing); + } +} + +disabled rule("=== GAME - MAIN LOGIC ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: DEFEAT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.IsDebug == False; + Global.GateHealth <= 0; + } + + actions + { + Declare Team Victory(Team 2); + } +} + +rule("GLOBAL: TIMER - MAIN GAME LOOP") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + disabled Global.GateHealth > 0; + } + + actions + { + Wait(1, Ignore Condition); + Global.TimeSec += 1; + If(Global.TimeSec == 60); + Global.TimeSec = 0; + Global.TimeMin += 1; + Global.Time5Min = Round To Integer(Global.TimeMin / 5, Down); + Global.Time10Min = Round To Integer(Global.TimeMin / 10, Down); + Global.SpawnPositionMaxId += 1; + disabled Start Rule(GameLogicAddNextHeroInGame, Restart Rule); + Else If(Global.TimeSec == 30); + Global.SpawnPositionMaxId += 1; + End; + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GAME LOGIC - ADD NEXT HERO IN GAME") +{ + event + { + Subroutine; + GameLogicAddNextHeroInGame; + } + + actions + { + "REDUCE RESPAWN TIME FOR ZENS" + disabled Global.ZenRespawnTime -= 1.500; + disabled Global.ZenRespawnTime = Max(1, Global.ZenRespawnTime); + disabled Set Respawn Max Time(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Global.DefaultHeroBotsPool[0]), + Global.ZenRespawnTime); + "ALL HEROES WAS ADDED IN GAME" + Abort If(Global.DefaultHeroBotsPoolCurrentId == Count Of(Global.DefaultHeroBotsPool) - 1); + Global.DefaultHeroBotsPoolCurrentId += 1; + "ВРЕМЕННЫЙ КОСТЫЛЬ ЧТОБЫ ЭХО ЗАМЕНИЛА ХАМСТЕРА" + If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Hero(Echo)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Abort; + End; + "ABORT IF NEXT HERO IN ARRAY ORDER IS NULL" + Abort If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Null); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId], Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("SUBROUTINE: GAME LOGIC - SET BOT PROPERTIES") +{ + event + { + Subroutine; + GameLogicSetBotProperties; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + If(Global.TimeMin >= 10); + If(Filtered Array(Global.lastBoss, Current Array Element == Hero Of(Event Player)) == False); + If(Global.activeBoss == False); + If(Global.bossTrigger < Global.TimeMin); + Global.bossTrigger = Global.TimeMin; + Global.activeBoss = Event Player; + Event Player.isBoss = 1; + Big Message(All Players(Team 1), Custom String("BOSS SPAWNED - {0}", Hero Of(Event Player))); + End; + End; + End; + End; + "PROPERTIES BY DEFAULT" + Set Gravity(Event Player, 100); + Set Damage Dealt(Event Player, 100); + Set Respawn Max Time(Event Player, 10); + Start Scaling Player(Event Player, 1, False); + "INDIVIDUAL HERO'S PROPERTIES" + If(Hero Of(Event Player) == Hero(Zenyatta)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 30); + Set Max Health(Event Player, 10 * (100 + 10 * Global.TimeMin + 25 * Global.Time5Min + 50 * Global.Time10Min) * ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 1.500, False); + Else; + If(20 + 3 * Number Of Players(Team 1) + 3 * Global.TimeMin > 75); + Set Move Speed(Event Player, 75); + Else; + Set Move Speed(Event Player, 20 + 3 * Count Of(All Players(Team 1)) + 3 * Global.TimeMin); + End; + Set Max Health(Event Player, 100 + 10 * Global.TimeMin + 25 * Global.Time5Min + 50 * Global.Time10Min); + End; + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 20); + Set Max Health(Event Player, 5 * (70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin + 25 * Global.Time5Min + 50 * Global.Time10Min) * ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + If(30 + Global.TimeMin + 2.500 * Global.Time5Min > 40); + Set Move Speed(Event Player, 40); + Else; + Set Move Speed(Event Player, 30 + Global.TimeMin + 2.500 * Global.Time5Min); + End; + Set Ultimate Charge(Event Player, 0); + Set Max Health(Event Player, 70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin + 25 * Global.Time5Min + 50 * Global.Time10Min); + End; + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + If(Event Player.isBoss == 1); + Set Damage Dealt(Event Player, 2 * (85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min + 50 * Global.Time10Min)); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 5 * (100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin + 15 * Global.Time5Min + 40 * Global.Time10Min) * ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Event Player.BotCounter = 0; + Set Damage Dealt(Event Player, 85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min + 50 * Global.Time10Min); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin + 15 * Global.Time5Min + 40 * Global.Time10Min); + End; + Else If(Hero Of(Event Player) == Hero(Bastion)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 50); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min + 10 * Global.Time10Min); + Start Scaling Player(Event Player, 3, False); + Set Max Health(Event Player, 5 * (155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin + 40 * Global.Time5Min + 65 * Global.Time10Min) * ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Else; + Set Move Speed(Event Player, 80); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min + 10 * Global.Time10Min); + Start Scaling Player(Event Player, 2, False); + Set Max Health(Event Player, 155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin + 40 * Global.Time5Min + 65 * Global.Time10Min); + End; + Else If(Hero Of(Event Player) == Hero(Orisa)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 5 * (220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min + 100 * Global.Time10Min) * ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Set Move Speed(Event Player, 30 + 5 * Global.Time5Min); + Else; + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min + 100 * Global.Time10Min); + Set Move Speed(Event Player, 90 + 5 * Global.Time5Min); + End; + Else If(Hero Of(Event Player) == Hero(Echo)); + If(Event Player.isBoss == 1); + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 70 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 5 * (90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin + 25 * Global.Time5Min + 50 * Global.Time10Min) * ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 130 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin + 25 * Global.Time5Min + 50 * Global.Time10Min); + End; + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.500, False); + Set Move Speed(Event Player, 70); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min + 10 * Global.Time10Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 5 * (55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin + 25 * Global.Time5Min + 50 * Global.Time10Min) * ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Else; + disabled Start Scaling Player(Event Player, 0.850, False); + Set Move Speed(Event Player, 110); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min + 10 * Global.Time10Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin + 25 * Global.Time5Min + 50 * Global.Time10Min); + End; + End; + Wait(0.250, Ignore Condition); + "FILL HEALTH" + Heal(Event Player, Null, 100000); + } +} + +disabled rule("=== GATE ===") +{ + event + { + Ongoing - Global; + } +} + +rule("Subroutine: GATE REPAIR") +{ + event + { + Subroutine; + GateRepair; + } + + actions + { + Small Message(Event Player, Custom String("REPAIR +2% ULTIMATE")); + "UPGRADE - GATE'S MAX HEALTH" + If(Global.UpgradeGateMaxHealthValue < Global.UpgradeGateMaxHealthMaxValue[2]); + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.UpgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.UpgradeGateMaxHealthValue += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + End; + End; + "HEAL GATE" + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.GateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.GateHealth += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + "CHARGE ULTIMATE" + Else; + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + End; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + } +} + +rule("TORB: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Has Spawned(Event Player) == True; + Weapon(Event Player) == 2; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(Is Using Ability 2(Event Player) == True ? 0.350 : 0.700, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Brig: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 5; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Rein: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + Is Game In Progress == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Call Subroutine(GateRepair); + Wait(0.850, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GATE PROGRESS BAR COLOR") +{ + event + { + Subroutine; + GateProgressBarColor; + } + + actions + { + Stop Chasing Global Variable(GateHealthChase); + Chase Global Variable Over Time(GateHealthChase, Global.GateHealth, 0.100, Destination and Duration); + "GATE WAS DAMAGED" + If(Global.GateHealth < Global.GateHealthEvent); + For Global Variable(LoopIterator1, 0, 3, 1); + Global.GateProgressBarColorCurrent = Color(Red); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(White); + Wait(0.030, Ignore Condition); + End; + "GATE WAS REPAIRED" + Else; + Global.GateProgressBarColorCurrent = Color(Green); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(Yellow); + Wait(0.030, Ignore Condition); + End; + Global.GateHealthEvent = Global.GateHealth; + Global.GateProgressBarColorComponent = Global.GateHealth * 255 / Global.GateMaxHealth; + Global.GateProgressBarColorCurrent = Custom Color(255, Global.GateProgressBarColorComponent, Global.GateProgressBarColorComponent, + 255); + } +} + +disabled rule("=== COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("ALL: INIT") +{ + event + { + Player Joined Match; + All; + All; + } + + actions + { + "ALL (COMMON) INIT" + Event Player.IsDead = True; + Disable Kill Feed(Event Player); + Disable Game Mode In-World UI(Event Player); + Disable Death Spectate Target HUD(Event Player); + "BOT INIT" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotInit); + "PLAYER INIT" + Else; + Call Subroutine(PlayerInit); + End; + } +} + +rule("SUBROUTINE: BOT - INIT") +{ + event + { + Subroutine; + BotInit; + } + + actions + { + "INIT VARS" + Event Player.HasBadStatus = False; + Event Player.IsRespawning = False; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEventPosition = Vector(9999, 999, 9999); + "DISABLE ALL FOR BOT" + Disable Hero HUD(Event Player); + Disable Messages(Event Player); + Disable Text Chat(Event Player); + Disable Scoreboard(Event Player); + Disable Game Mode HUD(Event Player); + Disable Death Spectate All Players(Event Player); + Disable Voice Chat(Event Player, True, True, True); + "INIT AI NAVIGATION VARS" + Call Subroutine(BotResetPathFinding); + } +} + +rule("SUBROUTINE: PLAYER - INIT") +{ + event + { + Subroutine; + PlayerInit; + } + + actions + { + "STORY HEROES" + If(Global.IsStoryHeroes); + Reset Player Hero Availability(Event Player); + Set Player Allowed Heroes(Event Player, Array(Hero(Ana), Hero(Brigitte), Hero(Mercy), Hero(Lúcio), Hero(Moira), Hero(Baptiste), + Hero(Ashe), Hero(D.Va), Hero(Genji), Hero(Hanzo), Hero(Widowmaker), Hero(Cassidy), Hero(Reinhardt), Hero(Soldier: 76), Hero( + Torbjörn), Hero(Tracer), Hero(Winston), Hero(Pharah))); + End; + "TEAM CHALLENGE - PLAYER'S MAX HEALTH" + If(Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0]); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + End; + If(Is Game In Progress); + Disable Game Mode HUD(Event Player); + End; + } +} + +rule("ALL: RESPAWN") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + (Hero Of(Event Player) != Event Player.CurrentHero || Event Player.IsDead == True) == True; + } + + actions + { + Event Player.IsDead = False; + "BOT RESPAWN" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotRespawn); + If(Global.IsDebugAINavigation); + Create Beam Effect(All Players(All Teams), Good Beam, Eye Position(Event Player), Event Player.BotNextNodePosition, Color(Green), + Visible To Position and Radius); + End; + "PLAYER RESPAWN" + Else; + Call Subroutine(PlayerRespawn); + End; + "MUST BE AFTER ALL RESPAWN SUBROUTINES!" + Event Player.CurrentHero = Hero Of(Event Player); + } +} + +rule("SUBROUTINE: BOT - RESPAWN") +{ + event + { + Subroutine; + BotRespawn; + } + + actions + { + "RESET COMMON PROPERTIES" + Event Player.IsRespawning = True; + Enable Nameplates(Event Player, All Players(Team 1)); + Call Subroutine(BotResetPathFinding); + disabled If(Hero Of(Event Player) != Event Player.CurrentHero); + Call Subroutine(GameLogicSetBotProperties); + disabled End; + "INDIVIDUAL HERO'S RESPAWN SCRIPTS" + If(Hero Of(Event Player) == Hero(Bastion)); + Call Subroutine(BotBastionRespawn); + Else If(Hero Of(Event Player) == Hero(Zenyatta)); + Call Subroutine(BotZenyattaRespawn); + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + Call Subroutine(BotWidowRespawn); + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Call Subroutine(BotBallRespawn); + Else If(Hero Of(Event Player) == Hero(Orisa)); + Call Subroutine(BotOrisaRespawn); + Else If(Hero Of(Event Player) == Hero(Echo)); + Call Subroutine(BotEchoRespawn); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Call Subroutine(BotReinRespawn); + End; + Event Player.IsRespawning = False; + } +} + +rule("SUBROUTINE: PLAYER - RESPAWN") +{ + event + { + Subroutine; + PlayerRespawn; + } + + actions + { + "TEAM CHALLENGE - MAX AMMO" + If(Hero Of(Event Player) != Event Player.CurrentHero && Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]); + Set Max Ammo(Event Player, 0, Ammo(Event Player, 0) * 2); + Set Max Ammo(Event Player, 1, Ammo(Event Player, 1) * 2); + Set Ammo(Event Player, 0, Max Ammo(Event Player, 0)); + Set Ammo(Event Player, 1, Max Ammo(Event Player, 1)); + End; + "MUST BE AFTER TEAM CHALLENGE MAX AMMO!" + disabled Event Player.CurrentHero = Hero Of(Event Player); + "PLAYER RESPAWN" + Set Status(Event Player, Null, Phased Out, 3); + Set Facing(Event Player, Vector(-1, 0, 0), To World); + If(Ability Cooldown(Players On Hero(Hero(Mercy), Team 1), Button(Ability 2)) >= 29); + Wait(0.250, Ignore Condition); + Teleport(Event Player, Event Player.deathPosition); + Else; + Teleport(Event Player, Global.PlayerSpawnPositions[Slot Of(Event Player) == Count Of(Global.PlayerSpawnPositions) ? Random Integer( + 0, Count Of(Global.PlayerSpawnPositions) - 1) : Slot Of(Event Player)]); + End; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + } +} + +rule("PLAYER: DEATH") +{ + event + { + Player Died; + Team 1; + All; + } + + actions + { + If(Hero Of(Event Player) == Hero(Roadhog)); + Event Player.Abilities[8] -= 1; + Wait(Global.Perk[2] ? 5 : 10, Ignore Condition); + Event Player.Abilities[8] += 1; + End; + Event Player.deathPosition = Position Of(Event Player); + disabled If(Event Player.lastSecondWind > 0); + disabled Event Player.lastSecondWind = 0; + disabled End; + Event Player.IsDead = True; + } +} + +rule("BOT: DEATH") +{ + event + { + Player Died; + Team 2; + All; + } + + actions + { + If(Event Player.isBoss == 1); + If(Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]); + If(Global.UpgradeBossHealthValue < Global.UpgradeCriticalDamageMaxValue[2]); + Global.UpgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + End; + End; + Event Player.isBoss = 0; + Global.activeBoss = Null; + Big Message(All Players(Team 1), Custom String("BOSS DIED - {0}", Hero Of(Event Player))); + End; + Event Player.IsDead = True; + Event Player.HasBadStatus = False; + Event Player.BotDoesUniqueBehaviour = False; + Disable Nameplates(Event Player, All Players(Team 1)); + disabled Stop Holding Button(Event Player, Button(Ability 1)); + disabled Stop Holding Button(Event Player, Button(Primary Fire)); + disabled Stop Holding Button(Event Player, Button(Secondary Fire)); + "BOT HAS 1 EFFECT IN VAR (NOT ARRAY)" + Skip If(!Entity Exists(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects); + "BOT HAS MORE THEN 1 EFFECT IN VAR (ARRAY)" + Skip If(Count Of(Event Player.BotEffects) == 0, 3); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects[Event Player.BotLoopIterator1]); + End; + } +} + +disabled rule("=== BOT COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BAD STATUS") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + Event Player.HasBadStatus = True; + "PROCESS BAD STATUS" + If(Hero Of(Event Player) == Hero(Widowmaker)); + Start Rule(BotWidowBadStatus, Do Nothing); + End; + Wait Until(!Has Status(Event Player, Knocked Down) && !Has Status(Event Player, Asleep) && !Has Status(Event Player, Frozen) + && !Has Status(Event Player, Stunned), 15); + Event Player.HasBadStatus = False; + } +} + +rule("SUBROUTINE: BOT - LANDING FROM SKY") +{ + event + { + Subroutine; + BotLandingFromSky; + } + + actions + { + Stop Throttle In Direction(Event Player); + "SET RESPAWN POSITION" + Event Player.BotEventPosition = Random Value In Array(Global.BigBossSpawnPositions); + "CREATE EFFECTS" + disabled Create Effect(All Players(All Teams), Light Shaft, Color(Red), Event Player.BotEventPosition, 3, Visible To); + disabled Event Player.BotEffects = Last Created Entity; + "RESPAWN IN LIGHT SHAFT EFFECT" + Teleport(Event Player, Event Player.BotEventPosition + Vector(0, 25, 0)); + Wait(0.020, Ignore Condition); + "SLOW LANDING" + Set Gravity(Event Player, 50); + While(Is In Air(Event Player) == True); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Position Of(Event Player) + Vector(0, -2.700, 0), 2); + Wait(0.250, Ignore Condition); + End; + Set Gravity(Event Player, 100); + disabled Destroy Effect(Event Player.BotEffects); + "LANDING EFFECTS" + Play Effect(All Players(All Teams), Wrecking Ball Piledriver Impact Effect, Custom Color(105, 87, 46, 255), Position Of( + Event Player), 8); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Sound, Color(White), Position Of(Event Player), 150); + } +} + +rule("SUBROUTINE: BOT - APPEAR FROM UNDERGROUND") +{ + event + { + Subroutine; + BotApearFromUnderground; + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1); + Wait(0.200, Ignore Condition); + Set Gravity(Event Player, 20); + Disable Movement Collision With Environment(Event Player, True); + Teleport(Event Player, Global.ZenSpawnPositions[Random Integer(Min(Global.TimeMin, Count Of(Global.ZenSpawnPositions) - 10), Min( + Global.SpawnPositionMaxId, Count Of(Global.ZenSpawnPositions) - 4))] + Vector(0, -1.500, 0)); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Sigma Accretion Impact Effect, Custom Color(220, 175, 100, 255), Eye Position(Event Player), + 3); + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(Gray), Eye Position(Event Player), 50); + Apply Impulse(Event Player, Up, 3.500, To World, Cancel Contrary Motion); + Wait(0.400, Ignore Condition); + Clear Status(Event Player, Knocked Down); + Set Gravity(Event Player, 100); + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("=== PLAYER MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("PLAYER: DARKNESS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + !Entity Exists(Event Player.BotEffects) == True; + } + + actions + { + Disable Nameplates(Event Player, All Players(All Teams)); + Start Forcing Player Outlines(Event Player, All Players(All Teams), False, Color(White), Default); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 14), 25, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(-5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + } +} + +rule("PLAYER: HEALTH REGEN") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + actions + { + Stop Heal Over Time(Event Player.HealOverTimeId); + Event Player.EventHealth = Health(Event Player); + Wait(4, Ignore Condition); + "TOOK DAMAGE, RESET REGENERATION TIMER" + Loop If(Is Alive(Event Player) && Event Player.EventHealth > Health(Event Player)); + Start Heal Over Time(Event Player, Null, 3, Max Health(Event Player) / 3); + Event Player.HealOverTimeId = Last Heal Over Time ID; + } +} + +disabled rule("=== NERFS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("REINHARDT: ANTI-CHARGE FOR BASTION & ORISA") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Using Ability 1(Event Player) == True; + Hero Of(Ray Cast Hit Player(Eye Position(Event Player) + Vector(0, 2, 0), Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 2, All Living Players(Team 2), Event Player, True)) == (Hero(Bastion) == True || Hero( + Orisa) == True); + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1.500); + } +} + +rule("HOG: ANTI-HOOK FOR BASTION & ORISA") +{ + event + { + Player Dealt Damage; + Team 1; + Roadhog; + } + + conditions + { + Event Ability == Button(Ability 1); + (Hero Of(Victim) == Hero(Bastion) || Hero Of(Victim) == Hero(Orisa)) == True; + } + + actions + { + Set Status(Event Player, Null, Stunned, 0.005); + } +} + +disabled rule("=== ZENYATTA ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ZEN - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Zenyatta; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + } + + actions + { + Set Ammo(Event Player, 0, 0); + Communicate(Event Player, Hello); + disabled Call Subroutine(BotResetPathFinding); + Wait(1.500, Ignore Condition); + Abort If(Is Dead(Event Player) == True); + Kill(Event Player, Null); + } +} + +rule("BOT: ZEN - DEATH") +{ + event + { + Player Died; + Team 2; + Zenyatta; + } + + actions + { + "EFFECT" + Play Effect(All Players(All Teams), Junkrat Frag Launcher Explosion Effect, Color(Red), Eye Position(Event Player), 2.500); + Play Effect(All Players(All Teams), Ashe Dynamite Explosion Sound, Color(Red), Eye Position(Event Player), 70); + "DAMAGE AND APPLY IMPULSE TO PLAYERS" + Event Player.BotPlayersInRadius = Players Within Radius(Position Of(Event Player), 2.500, All Teams, Surfaces And Enemy Barriers); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotPlayersInRadius), 1); + Apply Impulse(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Direction Towards(Position Of(Event Player), + Eye Position(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1])), 5, To World, Incorporate Contrary Motion); + If(Team Of(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1]) == Team 1); + Damage(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Event Player, 50); + End; + End; + "DAMAGE GATE" + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 125; + Else; + Global.GateHealth -= 25; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Respawn(Event Player); + Abort; + End; + "KILLED BY PLAYER" + Teleport(Event Player, Vector(0, -999, 0)); + Wait(2, Ignore Condition); + Respawn(Event Player); + Wait(2, Ignore Condition); + } +} + +rule("SUBROUTINE: ZEN - RESPAWN") +{ + event + { + Subroutine; + BotZenyattaRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WRECKING BALL ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BALL - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + disabled Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Set Ammo(Event Player, 0, 0); + Wait(1, Ignore Condition); + Set Ultimate Charge(Event Player, 100); + Start Holding Button(Event Player, Button(Ultimate)); + Wait Until(Is Using Ultimate(Event Player), 0.600); + Abort If(Is Dead(Event Player)); + Kill(Event Player, Null); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Effect, Color(Orange), Eye Position(Event Player), 6); + Play Effect(All Players(All Teams), DVa Self Destruct Explosion Sound, Color(White), Eye Position(Event Player), 250); + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 300; + Else; + Global.GateHealth -= 150; + End; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Damage(Players Within Radius(Eye Position(Event Player), 7, Team 1, Surfaces And All Barriers), Event Player, 200); + } +} + +rule("BOT: BALL - ALTERNATIVE FORM") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is In Alternate Form(Event Player) == False; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is In Alternate Form(Event Player), 10); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: BALL - DEATH") +{ + event + { + Player Died; + Team 2; + Wrecking Ball; + } + + actions + { + Stop Holding Button(Event Player, Button(Ability 1)); + Stop Holding Button(Event Player, Button(Ultimate)); + } +} + +rule("SUBROUTINE: BALL - RESPAWN") +{ + event + { + Subroutine; + BotBallRespawn; + } + + actions + { + "RESPAWN IN AIR" + Teleport(Event Player, Random Value In Array(Global.BallSpawnPositions) + Vector(0, 20, 0)); + Stop Holding Button(Event Player, Button(Ultimate)); + Wait(0.250, Ignore Condition); + "LANDING" + Start Holding Button(Event Player, Button(Crouch)); + Wait Until(Is On Ground(Event Player), 9999); + Stop Holding Button(Event Player, Button(Crouch)); + "LANDING IMPACT EFFECT" + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(White), Event Player, 150); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Effect, Color(Gray), Position Of(Event Player), 10); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Eye Position(Event Player), 1.500, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + "PATH FINDING TO GATE" + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +disabled rule("=== ECHO ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ECHO - FLY ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is Using Ability 1(Event Player) == False; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), 0); + Press Button(Event Player, Button(Ability 1)); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - BEAM ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Using Ability 1(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == True; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - BAD STATUS - RESET BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.HasBadStatus == True; + disabled (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + Wait Until(Event Player.HasBadStatus, 7); + } +} + +rule("BOT: ECHO - CAN'T SEE PORTAL - APPLY IMPULSE") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == True; + Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Wait(0.300, Abort When False); + Apply Impulse(Event Player, Vector(Random Integer(-1, 1), 1, Random Integer(-1, 1)), 20, To World, Incorporate Contrary Motion); + Wait(1, Ignore Condition); + If(!Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + Event Player.BotTargetPosition = Global.BotEchoRespawnPosition; + Start Rule(BotStartPathFinding, Restart Rule); + Else; + Call Subroutine(BotResetPathFinding); + End; + Loop If Condition Is True; + } +} + +disabled rule("BOT: ECHO - MAIN LOGIC - BACKUP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(!Event Player.BotIsPathFinding); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Is In Line of Sight(Eye Position(Event Player), + Eye Position(Current Array Element), Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), + Position Of(Current Array Element)))[0]; + End; + "NO PLAYERS IN VIEW RANGE" + disabled If(Event Player.BotSeePlayer == Null); + disabled Stop Throttle In Direction(Event Player); + disabled End; + "FLY TO PLAYER" + If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + > 4 && Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + "ACTIVATE FOCUS BEAM" + Else If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + < 4 && Event Player.BotDoesUniqueBehaviour == False && Event Player.HasBadStatus == False); + Event Player.BotDoesUniqueBehaviour = True; + Set Status(Event Player.BotSeePlayer, Event Player, Stunned, 1); + Set Status(Event Player.BotSeePlayer, Event Player, Hacked, 99999); + Attach Players(Event Player.BotSeePlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + "TELEPORT PLAYER TO AWAY" + Else If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotSeePlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotSeePlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotSeePlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + "BEGIN TO FLY TO THE PORTAL" + Else If(Event Player.BotDoesUniqueBehaviour == True); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + End; + "TELEPORT PLAYER SO FAR" + If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotEchoCapturedPlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotEchoCapturedPlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + End; + "BEGIN TO FLY TO THE PORTAL WITH A PLAYER" + If(Event Player.BotDoesUniqueBehaviour); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotEchoCapturedPlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - DEFEND PORTAL") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + } + + actions + { + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPlayer); + } +} + +rule("BOT: ECHO - PATH FINDING TO PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Call Subroutine(BotStartPathFinding); + } +} + +rule("BOT: ECHO - ATTACH PLAYER BY BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotEchoCapturedPlayer == Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 3; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Event Player.BotEchoCapturedPlayer = Event Player.BotSeePlayer; + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Stunned, 0.700); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Hacked, 10); + Attach Players(Event Player.BotEchoCapturedPlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - PLAYER DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Dead(Event Player.BotEchoCapturedPlayer) != Null; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - DEATH") +{ + event + { + Player Died; + Team 2; + Echo; + } + + actions + { + Call Subroutine(BotEchoDetachPlayer); + Stop Holding Button(Event Player, Button(Jump)); + Wait(5, Ignore Condition); + Teleport(Event Player, Vector(0, 999, 0)); + Start Forcing Player To Be Hero(Event Player, Hero(Orisa)); + } +} + +rule("SUBROUTINE: ECHO - RESPAWN") +{ + event + { + Subroutine; + BotEchoRespawn; + } + + actions + { + Event Player.BotCounter = 0; + Event Player.BotEffects = Empty Array; + Create Effect(All Players(All Teams), Good Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Energy Sound, Color(White), Global.BotEchoRespawnPosition, 200, Visible To); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Chase Player Variable Over Time(Event Player, BotCounter, 3, 0.800, Destination and Duration); + Play Effect(All Players(All Teams), Sombra EMP Explosion Effect, Color(Sky Blue), Global.BotEchoRespawnPosition, 12); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Null, Global.BotEchoRespawnPosition, 100); + Wait(3, Ignore Condition); + Teleport(Event Player, Global.BotEchoRespawnPosition); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Global.BotEchoRespawnPosition, 2.500); + Play Effect(All Players(All Teams), Debuff Impact Sound, Null, Global.BotEchoRespawnPosition, 100); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PLAYER") +{ + event + { + Subroutine; + BotEchoFlyToPlayer; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Stop Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PORTAL") +{ + event + { + Subroutine; + BotEchoFlyToPortal; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - DETACH PLAYER") +{ + event + { + Subroutine; + BotEchoDetachPlayer; + } + + actions + { + Detach Players(Event Player.BotEchoCapturedPlayer); + Clear Status(Event Player.BotEchoCapturedPlayer, Hacked); + "IF PLAYER INSIDE THE WALL" + If(Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotEchoCapturedPlayer), Barriers Do Not Block LOS)); + Teleport(Event Player.BotEchoCapturedPlayer, Position Of(Event Player)); + End; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEchoCapturedPlayer = Null; + } +} + +disabled rule("=== REINHARDT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: REIN - SET PLAYER AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + disabled Event Player.BotIsPathFinding == False; + "BOT IS FAR FROM GATES" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Global.GatePosition), 0, Z Component Of(Global.GatePosition))) > 20; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET CLOSEST PLAYER TO BOT AS TARGET AND FOLLOW HIM" + Event Player.BotTargetPlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - SET GATE AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "BOT DOESN'T FOLLOW PLAYER" + Event Player.BotTargetPlayer == -1; + "CAN'T SEE ANY PLAYER" + disabled Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), !Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET GATE AS TARGET" + Event Player.BotTargetPosition = Global.GatePosition; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - TARGET DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer != -1; + Is Dead(Event Player.BotTargetPlayer) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + } +} + +rule("BOT: REIN - ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) < 4; + "CAN ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) < 4; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + "TARGET IS PLAYER" + Abort If(Event Player.BotTargetPlayer != -1); + If(Event Player.isBoss == 1); + "TARGET IS GATE" + Global.GateHealth -= 25; + Else; + Global.GateHealth -= 5; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: REIN - STOP ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) > 4; + "CAN'T ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) > 4; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + } +} + +rule("BOT: REIN - USE SHIELD") +{ + event + { + Player Took Damage; + Team 2; + Reinhardt; + } + + conditions + { + Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) > 3; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Attacker)), 200, To World, + Direction and Turn Rate); + Start Holding Button(Event Player, Button(Secondary Fire)); + Wait Until(Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) < 3, 3); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("BOT: REIN - CHARGE IN GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer == -1; + Is Using Ability 1(Event Player) == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == True; + Is In View Angle(Event Player, Global.GatePosition, 7.500) == True; + } + + actions + { + disabled Wait(0.800, Abort When False); + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is Using Ability 1(Event Player), 1); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: REIN - DEATH") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("SUBROUTINE: REIN - RESPAWN") +{ + event + { + Subroutine; + BotReinRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WIDOW ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: WIDOW - SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer == Null; + Event Player.HasBadStatus == False; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Event Player.BotWidowShotTime = Total Time Elapsed + (Global.TimeMin >= 9 ? Random Real(2, 5) : Random Real(5, 10)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 9999, To World, + Direction and Turn Rate); + } +} + +rule("BOT: WIDOW - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer != Null; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowShotTime; + } + + actions + { + Press Button(Event Player, Button(Primary Fire)); + Stop Facing(Event Player); + Event Player.BotSeePlayer = Null; + } +} + +rule("BOT: WIDOW - Aim Sound") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Alive(Event Player) == True; + Is In Line of Sight(Eye Position(Players On Hero(Hero(Widowmaker), Team 2)), Eye Position(Event Player), Barriers Do Not Block LOS) + == True; + Is Alive(Players On Hero(Hero(Widowmaker), Team 2)) == True; + Players On Hero(Hero(Widowmaker), Team 2).BotSeePlayer == True; + } + + actions + { + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 100); + Wait(1, Abort When False); + Loop If Condition Is True; + } +} + +rule("BOT: WIDOW - TELEPORT TO NEW POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowTeleportTime; + } + + actions + { + Event Player.BotWidowTeleportTime = Total Time Elapsed + 28; + Event Player.BotWidowShotTime = Total Time Elapsed + (Global.TimeMin >= 9 ? Random Real(1, 3) : Random Real(3, 6)); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Event Player, 1); + Wait(0.016, Ignore Condition); + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + } +} + +rule("BOT: WIDOW - DEATH") +{ + event + { + Player Died; + Team 2; + Widowmaker; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + Wait(0.250, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - RESPAWN") +{ + event + { + Subroutine; + BotWidowRespawn; + } + + actions + { + "RESPAWN ON RANDOM SNIPER POSITION" + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Wait(0.700, Ignore Condition); + Start Holding Button(Event Player, Button(Secondary Fire)); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait Until(Is Dead(Event Player), 99999); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - BAD STATUS") +{ + event + { + Subroutine; + BotWidowBadStatus; + } + + actions + { + Stop Facing(Event Player); + Destroy Effect(Event Player.BotEffects); + Wait Until(!Event Player.HasBadStatus, 15); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + } +} + +disabled rule("=== BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("BOT: BASTION - FLAME GUN") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 50) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 8; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Stop Holding Button(Event Player, Button(Primary Fire)); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Update Every Frame(Eye Position(Event Player) + World Vector Of( + Vector(-1, -1.200, 1.800), Event Player, Rotation)), 1, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Start Rule(BotBastionFlameGunDamage, Do Nothing); + Wait(1.100, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(4, Ignore Condition); + Loop If Condition Is True; + } +} + +disabled rule("BOT: BASTION - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + disabled Event Player.BotSeePlayer == Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - CAN'T SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == False; + } + + actions + { + Event Player.BotSeePlayer = Null; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - MOVE TO BASTION'S TARGET (POSITION)") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotTargetPosition = Random Value In Array(Filtered Array(Global.BastionTargetPositions, Distance Between(Position Of( + Event Player), Current Array Element) > 3.500)); + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("BOT: BASTION - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + "SEE THE PLAYER" + If(Event Player.BotSeePlayer != Null); + Stop Holding Button(Event Player, Button(Secondary Fire)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer) - Vector(0, 0.500, + 0)), 100, To World, Direction and Turn Rate); + "SELF REPAIRING" + Else If(!Is Firing Secondary(Event Player) && Health(Event Player) < Max Health(Event Player)); + Start Holding Button(Event Player, Button(Secondary Fire)); + End; + "START FOLLOW PATH" + disabled If(!Event Player.BotIsPathFinding && !Event Player.BotDoesUniqueBehaviour); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled Wait(0.050, Ignore Condition); + disabled Event Player.BotTargetPosition = Random Value In Array(Global.BastionTargetPositions); + disabled Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Event Player.BotTargetPosition + Vector(0, 2, 0)), 100, + To World, Direction and Turn Rate); + disabled Start Rule(BotStartPathFinding, Do Nothing); + "REACHED PATH TARGET" + disabled Else If(Distance Between(Position Of(Event Player), Event Player.BotTargetPosition) <= 3); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled End; + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - ARTILLERY") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 30) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) > 18; + Distance Between(Eye Position(Event Player), Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Up * 99, Null, Event Player, False)) >= 35; + } + + actions + { + "TRYING TO CAPTURE TARGET" + Wait(0.800, Abort When False); + "CAPTURE TARGET" + Event Player.BotDoesUniqueBehaviour = True; + Stop Throttle In Direction(Event Player); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Update Every Frame(Eye Position(Event Player)), + Update Every Frame(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 1000, All Living Players(Team 1), Event Player, True)), Color(Sky Blue), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait(1.400, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Event Player.BotEventPosition = Position Of(Event Player.BotSeePlayer); + "SHOOT FROM ARTILLERY" + Event Player.BotBastionArtilleryDidShotsCount = 0; + For Player Variable(Event Player, BotLoopIterator1, 0, 4, 1); + Event Player.BotBastionArtilleryDidShotsCount += 1; + Play Effect(All Players(All Teams), Wrecking Ball Minefield Explosion Sound, Color(White), Eye Position(Event Player), 250); + Play Effect(All Players(All Teams), Pharah Barrage Explosion Effect, Color(Orange), Eye Position(Event Player) + World Vector Of( + Vector(0, 1.400, -0.700), Event Player, Rotation), 2); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) + World Vector Of(Vector(0, 1.400, + -0.700), Event Player, Rotation), Eye Position(Event Player) + World Vector Of(Vector(Random Real(-1, 1), Random Integer(40, + 80), Random Real(0.500, 1.500)), Event Player, Rotation), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + If(Is Dead(Event Player)); + Break; + End; + End; + disabled Call Subroutine(BotResetPathFinding); + disabled Start Rule(BotStartPathFinding, Do Nothing); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Wait(1.500, Ignore Condition); + Start Rule(BotBastionArtilleryDamage, Do Nothing); + Wait(4, Ignore Condition); + } +} + +rule("BOT: BASTION - PRIMARY FIRE") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 40) == True; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Stop Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Bastion; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + For Player Variable(Event Player, BotLoopIterator1, 0, 3, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Effect, Color(White), Event Player, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player, 100); + Wait(0.250, Ignore Condition); + End; + } +} + +rule("SUBROUTINE: BASTION - RESPAWN") +{ + event + { + Subroutine; + BotBastionRespawn; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + Call Subroutine(BotLandingFromSky); + Set Ammo(Event Player, 0, 0); + Wait Until(!Is Reloading(Event Player), 99999); + Event Player.BotTargetPosition = Objective Position(2); + } +} + +rule("SUBROUTINE: BASTION - ARTILLERY DAMAGE") +{ + event + { + Subroutine; + BotBastionArtilleryDamage; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = False; + "EXPLOSIONS OF ARTILLERY" + For Player Variable(Event Player, BotLoopIterator2, 0, Event Player.BotBastionArtilleryDidShotsCount, 1); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotEventPosition + Vector(0, 50, 0), + Event Player.BotEventPosition + Vector(Random Integer(-4, 4), -15, Random Integer(-4, 4)), Null, Event Player, True); + Damage(Players Within Radius(Event Player.BotEventPosition, 8, Team 1, Surfaces And Enemy Barriers), Event Player, 50); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Pharah Rocket Launcher Explosion Effect, Color(Orange), Event Player.BotEventPosition, 5); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Event Player.BotEventPosition, + Event Player.BotEventPosition + Vector(0, 60, 0), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + End; + } +} + +disabled rule("SUBROUTINE: BASTION - FLAME GUN DAMAGE") +{ + event + { + Subroutine; + BotBastionFlameGunDamage; + } + + actions + { + Event Player.BotRayCastHitPosition = Eye Position(Event Player) + World Vector Of(Vector(-1, -1.200, 1.800), Event Player, + Rotation); + "FIRE PARTICLES OF FLAME GUN" + For Player Variable(Event Player, BotLoopIterator1, 1, 13, 3); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotRayCastHitPosition, + Event Player.BotRayCastHitPosition + Facing Direction Of(Event Player) * Event Player.BotLoopIterator1, Null, Event Player, + True); + Damage(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Surfaces And Enemy Barriers), Event Player, 20); + Set Status(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Off), Event Player, Burning, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.BotEventPosition, 2.500); + Wait(0.200, Ignore Condition); + End; + Event Player.BotDoesUniqueBehaviour = False; + } +} + +disabled rule("=== ORISA + BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ORISA-BASTION - REACHED TARGET POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotIsPathFinding == True; + Distance Between(Position Of(Event Player), Global.BotOrisaTargetPosition) < 1.500; + } + + actions + { + Call Subroutine(BotResetPathFinding); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Vector(X Component Of(Global.GatePosition), -999, + Z Component Of(Global.GatePosition))), 80, To World, Direction and Turn Rate); + Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + disabled Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element) && Is In Line of Sight(Eye Position(Event Player), Position Of(Current Array Element), + Barriers Do Not Block LOS)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + Press Button(Event Player, Button(Ability 1)); + Wait Until(Y Component Of(Facing Direction Of(Event Player)) < -0.300, 99999); + Press Button(Event Player, Button(Ability 2)); + Wait(0.800, Ignore Condition); + Global.BotOrisaChild.BotDoesUniqueBehaviour = False; + Disallow Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ORISA-BASTION - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + While(Is Alive(Event Player)); + disabled Create Effect(All Players(All Teams), Bad Aura, Color(Purple), Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3.200, 1, Visible To Position and Radius); + disabled Event Player.BotEffects = Last Created Entity; + Wait(1.500, Ignore Condition); + disabled Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Press Button(Event Player, Button(Primary Fire)); + Press Button(Event Player, Button(Reload)); + Event Player.BotRayCastHitPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Facing Direction Of(Event Player) * 999, All Players(Team 1), All Players(Team 2), True); + "ANTI-SHIELD BUG" + Event Player.BotRayCastHitPosition = Event Player.BotRayCastHitPosition + Direction Towards(Event Player.BotRayCastHitPosition, + Eye Position(Event Player)) * 0.200; + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3, Event Player.BotRayCastHitPosition, Color(Purple), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Damage(Players Within Radius(Event Player.BotRayCastHitPosition, 4, Team 1, Surfaces And All Barriers), Event Player, 0.040); + Play Effect(All Players(All Teams), Pharah Concussive Blast Effect, Color(Purple), Event Player.BotRayCastHitPosition, 4); + Play Effect(All Players(All Teams), Pharah Concussive Blast Sound, Color(Purple), Event Player.BotRayCastHitPosition, 250); + Play Effect(All Players(All Teams), Bad Explosion, Color(Purple), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 3.300, 2); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Color(Purple), Eye Position(Event Player), 170); + If(Distance Between(Event Player.BotRayCastHitPosition, Global.GatePosition) < 4 && Is In Line of Sight( + Event Player.BotRayCastHitPosition, Global.GatePosition, Enemy Barriers Block LOS)); + Global.GateHealth -= 80; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Wait(0.150, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.060, Ignore Condition); + Wait Until(!Is Reloading(Event Player), 2.500); + End; + } +} + +rule("BOT: ORISA-BASTION - CAN'T SEE THE TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: ORISA-BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Orisa; + } + + actions + { + Allow Button(Event Player, Button(Ability 2)); + Kill(Global.BotOrisaChild, Null); + Detach Players(Global.BotOrisaChild); + Clear Status(Global.BotOrisaChild, Phased Out); + Set Damage Dealt(Global.BotOrisaChild, 100); + Global.BotOrisaChild.BotIsOrisaChild = False; + Global.BotOrisaChild = Null; + Global.BotOrisaParent = Null; + Start Forcing Player To Be Hero(Event Player, Hero(Widowmaker)); + } +} + +rule("SUBROUTINE: ORISA - RESPAWN") +{ + event + { + Subroutine; + BotOrisaRespawn; + } + + actions + { + Global.BotOrisaParent = Event Player; + "WAITING FOR ANY BASTION TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero(Bastion)), + 99999); + "SETUP BASTION AS CHILD" + Global.BotOrisaChild = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Bastion))[0]; + Global.BotOrisaChild.BotIsOrisaChild = True; + Global.BotOrisaChild.BotDoesUniqueBehaviour = True; + Wait(2, Ignore Condition); + Respawn(Global.BotOrisaChild); + Start Scaling Player(Global.BotOrisaChild, 1.800, False); + Set Damage Dealt(Global.BotOrisaChild, 2000); + Set Status(Global.BotOrisaChild, Null, Phased Out, 9999); + Disable Nameplates(Global.BotOrisaChild, All Players(All Teams)); + Set Facing(Global.BotOrisaChild, Vector(X Component Of(Facing Direction Of(Event Player)), 9999, Z Component Of( + Facing Direction Of(Event Player))), To World); + Start Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Wait Until(Is In Alternate Form(Global.BotOrisaChild), 5); + Stop Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Teleport(Global.BotOrisaChild, Position Of(Event Player)); + Attach Players(Global.BotOrisaChild, Global.BotOrisaParent, Vector(0, 1.800, 0.230)); + disabled Wait(1, Ignore Condition); + disabled Stop Holding Button(Global.BotOrisaChild, Button(Primary Fire)); + disabled Wait(0.250, Ignore Condition); + Call Subroutine(BotLandingFromSky); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 0 - ZENS, REINS, BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 0; + } + + actions + { + "CREATE BOTS - ZEN" + While(Count Of(All Players(Team 2)) < 13); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "BALL" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "REPLACE DEAD ZEN TO REIN" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) != 3); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 1 - WIDOW") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 1; + } + + actions + { + Global.IsNewWaveGameLogicProcessing = True; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Global.IsNewWaveGameLogicProcessing = False; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 3 - BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 3; + } + + actions + { + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 5 - REINS WAVE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 5; + } + + actions + { + "PREPARE WAVE - DESTROY WIDOW AND BALLS" + Destroy Dummy Bot(Team 2, Slot Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))[0])); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))[0]; + Kill(Global.DefaultCurrentBot, Null); + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + "BOSS WAVE" + Big Message(All Players(All Teams), Custom String("BOSS WAVE - {1} {0}", Hero Icon String(Hero(Reinhardt)), Hero(Reinhardt))); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) < 6); + Wait Until(Is True For Any(All Players(Team 2), Distance Between(Position Of(Current Array Element), Global.GatePosition) + > 13 && Hero Of(Current Array Element) == Hero(Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + disabled Wait(0.200, Ignore Condition); + disabled Set Max Health(Global.DefaultCurrentBot, 50); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) > 3); + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Reinhardt)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Reinhardt))[0]; + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(All Players(Team 2)) < 13); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Big Message(All Players(All Teams), Custom String("BOSS WAVE FINISHED!")); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 7 - BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 7; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 9 - ECHO, +1 BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 9; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Echo))) == 0); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + "FILL EMPTY SLOTS BY ZENS" + While(Count Of(All Players(Team 2)) < 12); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("Ana Nano Variable") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + } + + actions + { + Player Closest To Reticle(Event Player, Team 1).IsNanoed = 1; + } +} + +rule("IsNanoed") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.IsNanoed == True; + } + + actions + { + If(Is Dead(Event Player)); + Event Player.IsNanoed = 0; + End; + Wait(8, Ignore Condition); + Event Player.IsNanoed = 0; + } +} + +rule("money on kill") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + actions + { + If(Hero Of(Victim) == Hero(Zenyatta)); + All Players(Team 1).Money[0] += 5 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 10 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Reinhardt)); + All Players(Team 1).Money[0] += 15 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 20 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Wrecking Ball)); + All Players(Team 1).Money[0] += 25 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 25 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Widowmaker)); + All Players(Team 1).Money[0] += 30 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 30 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Bastion)); + All Players(Team 1).Money[0] += 50 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 50 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Echo)); + All Players(Team 1).Money[0] += 75 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 75 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Orisa)); + All Players(Team 1).Money[0] += 100 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 100 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + } +} + +rule("Abilities and Hero Talents by Shingen and LemonAid") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.DamageDealt = 100; + Event Player.PlayerHealth = 100; + Event Player.Money[0] = 2400 + Global.StartMoney; + If(Custom String("{0}", Event Player) == Custom String("ShuriZma")); + Create HUD Text(Event Player, Custom String("Serverload: {0}, AVG {1}, Peak {2}", Server Load, Server Load Average, + Server Load Peak), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create HUD Text(Event Player, Custom String("Last SW: {0}, SW Active {1}", Event Player.lastSecondWind, + Event Player.secondWindActive), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + Create HUD Text(Event Player, Custom String("Death position: {0}", Event Player.deathPosition), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + End; + } +} + +rule("Team 1 (Ability): Headhunter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[1] == True; + Event Was Critical Hit == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[1] * 40 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Ambush") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[2] == True; + Event Ability != Null; + (Y Component Of(Position Of(Event Player)) - Y Component Of(Position Of(Victim)) >= 3 || Absolute Value(Horizontal Angle Towards( + Victim, Event Player)) >= 90) == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[2] * 30 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Quick Fix") +{ + event + { + Player Earned Elimination; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[3] == True; + } + + actions + { + Heal(Event Player, Null, Event Player.Abilities[3] * 50); + Set Move Speed(Event Player, 100 + Event Player.Abilities[3] * 20); + Wait(5, Restart When True); + Set Move Speed(Event Player, 100); + } +} + +rule("Team 1 (Ability): Heavyweight") +{ + event + { + Player Dealt Knockback; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[4] == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[4] * 25 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Charged") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[5] == True; + Ultimate Charge Percent(Event Player) < Event Player.Abilities[5] * 20; + } + + actions + { + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + If(Is Duplicating(Event Player)); + Wait(0.016, Ignore Condition); + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + End; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Team 1 (Ability): Haste Primary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Primary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Primary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Primary Fire))); + } +} + +rule("Team 1 (Ability): Haste Secondary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Secondary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Secondary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Secondary Fire))); + } +} + +rule("Team 1 (Ability): Haste Ability 1") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 1)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 1))); + } +} + +rule("Team 1 (Ability): Haste Ability 2") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 2)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 2))); + } +} + +rule("Team 1 (Ability): Haste Jump") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Jump)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Jump), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Jump))); + } +} + +rule("Team 1 (Ability): Haste Crouch") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Crouch)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Crouch), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Crouch))); + } +} + +rule("Team 1 (Ability): Heavy Impact") +{ + event + { + Player Took Damage; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[7] == True; + } + + actions + { + Abort If(Random Real(-0.020, 1) > Event Damage / Max Health(Event Player)); + Set Status(Event Player, Attacker, Stunned, 1 * Attacker.Abilities[7]); + Wait(5, Ignore Condition); + } +} + +rule("Team 1 (Ability): Binding Heal") +{ + event + { + Player Dealt Healing; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[10] == True; + Healee != Event Player; + } + + actions + { + Set Player Health(Event Player, Health(Event Player) + Event Player.Abilities[10] * 0.250 * Event Healing); + } +} + +rule("Team 1 (Ability): Resilience") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[11] == True; + Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300; + } + + actions + { + Set Damage Received(Event Player, 70); + Wait Until(!(Event Player.Abilities[11] && Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Auto Repair") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.AutoRepair == True; + Global.GateHealth < Global.GateMaxHealth; + } + + actions + { + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2]); + Global.GateHealth += 10 * Global.AutoRepair; + Global.UpgradeGateMaxHealthValue += 10 * Global.AutoRepair; + Else; + Global.GateHealth += 5 * Global.AutoRepair; + Global.UpgradeGateMaxHealthValue += 5 * Global.AutoRepair; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(5, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ana Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ana), Button(Ability 1)), Custom String( + "Sleep Paralysis: Slept enemies cannot be woken up by damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Ana), Button(Ability 2)), Custom String( + "Multinade: Ana throws multiple Biotic Grenades")); + } +} + +rule("Brigitte Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Brigitte), Button(Ability 1)), Custom String( + "Heavy Iron: Hitting enemies with Whip Flail will root them in pace")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Brigitte), Button(Ultimate)), Custom String( + "Endeavor: Gain a health, damage and speed boost when your barrier breaks")); + } +} + +rule("Mercy Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mercy), Button(Ability 2)), Custom String( + "Angelic blessing: Healing an ally slowly charges their ultimate")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mercy), Button(Ultimate)), Custom String( + "Holy light missiles: Unleash blasts of holy light missiles during valkyrie")); + } +} + +rule("Lúcio Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Lúcio), Button(Secondary Fire)), Custom String( + "Healing Wave: Soundwave heals allies for 30% of their max HP")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Lúcio), Button(Ability 1)), Custom String( + "Reverse Amp: Amp It Up inflicts the opposite effect of the currently played song to enemies")); + } +} + +rule("Moira Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Moira), Button(Secondary Fire)), Custom String( + "Hose: Biotic Grasp primary will damage and push enemies back")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Moira), Button(Ability 2)), Custom String( + "Flourish: Biotic Orbs are 3x more effective")); + } +} + +rule("Baptiste Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String( + "Corrode: Regenerative Burst will damage and poison enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Breakthrough: Immortality Field HP threshold increased to 100%; allies inside gain ultimate")); + } +} + +rule("Ashe Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ashe), Button(Ability 2)), Custom String( + "Wildfire: Shooting a burning enemy ignites other nearby enemies")); + Event Player.HeroTalentText[2] = Array(Icon String(Fire), Custom String( + "Flare trigger: Coach gun instantly damages all burning enemies")); + } +} + +rule("D.Va Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(D.Va), Button(Secondary Fire)), Custom String( + "Voltage Grid: Defense Matrix will damage and root enemies it's casted over")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(D.Va), Button(Ability 1)), Custom String( + "Shooting Star: Boosters set enemies on fire")); + } +} + +rule("Genji Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Genji), Button(Ability 1)), Custom String( + "Venomous Strike: Swift Strike poisons enemies; heal for poison damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Genji), Button(Ultimate)), Custom String( + "Dragon's Breath: Dragonblade fires large explosive energy charges")); + } +} + +rule("Hanzo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Hanzo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "Stormbreak: Enemies eliminated by hanzo unleash a thundercloud")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Hanzo), Button(Ability 2)), Custom String( + "Punch II: Storm Arrows deal more damage and stun and knockback enemies")); + } +} + +rule("Widowmaker Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Widowmaker; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Widowmaker), Button(Ultimate)), Custom String( + "Kiss Of Death: Scoped critical hits against enemies below 30% health explode and instantly die")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Widowmaker), Button(Ability 2)), Custom String( + "Epidemic: Enemies hurt by Venom Mine unleash toxic pulses; heal for dealt damage")); + } +} + +rule("McCree Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Cassidy), Button(Ability 2)), Custom String( + "Panic: Flashbang puts enemies in fear; deal +120% more damage to enemies in fear")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Cassidy), Button(Ultimate)), Custom String( + "Clocked: Deadeye deals more damage and knocks enemies down")); + } +} + +rule("Reinhardt Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reinhardt), Button(Ability 2)), Custom String( + "Fire Blast: Fire Strike explodes as it deals damage, setting enemies on fire")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reinhardt), Button(Ultimate)), Custom String( + "Epicenter: Earthshatter travels in all directions")); + } +} + +rule("Soldier: 76 Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ultimate)), Custom String( + "Triple Threat: 2 more rockets are fired alongside Helix Rockets")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Soldier: 76), Button(Ability 1)), Custom String( + "Shoulder Check: Sprinting into enemies will damage and tackle them to the ground")); + } +} + +rule("Torbjörn Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Torbjörn), Button(Ability 2)), Custom String( + "Melting point: Unleash heatwaves during overload and molten core")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Torbjörn), Button(Ultimate)), Custom String( + "Roots Of Magma: Enemies trapped in Molten Core blots cannot move")); + } +} + +rule("Tracer Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Tracer), Button(Ability 2)), Custom String( + "Vortex: Recall pulls and roots enemies towards the activation point")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Tracer), Button(Ultimate)), Custom String( + "Chain Reaction: Pulse Bomb creates chain explosions on enemies damaged by it")); + } +} + +rule("Winston Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Winston), Button(Ability 2)), Custom String( + "Blast Barrier: Barrier Projector damages enemies inside the area")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Winston), Button(Ultimate)), Custom String( + "Next Generation: Eliminations during Primal Rage add +15% ultimate charge towards the next")); + } +} + +rule("Pharah Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Pharah; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ability 2)), Custom String( + "Head Trauma: Concussive Blast stuns and damages enemies for 25% of their max health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Pharah), Button(Ability 1)), Custom String( + "Thunderbird: Gain 150 shields and deal 4x the damage to barriers and objects")); + } +} + +rule("Bastion Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Bomblets: Bullets shot during sentry configuration are explosive")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ability 1)), Custom String( + "Tesla: A powerful mounted laser will autmotically attack one enemy at a time")); + } +} + +rule("Doomfist Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Jump)), Custom String( + "Phase Shifter: Immune to damage while any ability is active")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Doomfist), Button(Ultimate)), Custom String( + "Fissure: Meteor Strike leaves a large fissure behind that burns enemies over it")); + } +} + +rule("Echo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Focusing Optics: Focusing Beam damage ramp starts at 90% health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Streamline: Fire many more sticky bombs per burst")); + } +} + +rule("Junkrat Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Junkrat; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Fire), Custom String("Pyromania: All explosive attacks inflict fire damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Junkrat), Button(Ability 2)), Custom String( + "Short Fused: Steel Trap sets off violent explosions once triggered")); + } +} + +rule("Mei Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mei), Button(Ultimate)), Custom String( + "Cold Snap: Instantly freeze neaerby enemies once Cryo-Freeze expires")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mei), Button(Ability 2)), Custom String( + "Icebound: While Ice Wall is up, Icicles freeze and deal much more damage")); + } +} + +rule("Orisa Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Orisa), Button(Ability 1)), Custom String( + "Immovable Object: During Fortify, become immune and convert 50% of taken damage to healing")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Orisa), Button(Secondary Fire)), Custom String( + "Unstoppable Force: Halt! is much larger and pushes enemies. When triggered, it explodes violently")); + } +} + +rule("Reaper Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reaper), Button(Ability 1)), Custom String( + "shadow streak: shadow step creates a beam that damages enemies who cross")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reaper), Button(Ultimate)), Custom String( + "Loom: Traumatize enemies in front of you when using Wraith Form")); + } +} + +rule("Roadhog Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String("Stench: Roadhog constantly damages enemies nearby")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Roadhog), Button(Ability 1)), Custom String( + "Rusted Anchor: Hook deals more damage; Eliminations will reset hook cooldown")); + } +} + +rule("Sigma Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sigma), Button(Ability 1)), Custom String( + "Gravity Well: Kinetic Grasp gives invincibility")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sigma), Button(Ultimate)), Custom String( + "Gravity Channels: Gravitic Flux damages enemies for 75% of max hp instead of 50%")); + } +} + +rule("Sombra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sombra), Button(Secondary Fire)), Custom String( + "Malware: Enemies hacked or in fear take +100% more damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sombra), Button(Ultimate)), Custom String( + "Glitch: EMP leaves behind a large hack zone ")); + } +} + +rule("Symmetra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Symmetra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "High Voltage: Enemies eliminated by Symmetra explode and damage other enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ultimate)), Custom String( + "Energy Source: While Photon Barrier is active, all players regenerate health and gain ultimate")); + } +} + +rule("Wrecking Ball Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ultimate)), Custom String( + "Mirror Ball: Reflect 100% of taken damage to nearby enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ability 2)), Custom String( + "Distort: Adaptive Shields damages and hacks nearby enemies")); + } +} + +rule("Zarya Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zarya; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Zarya), Button(Ability 1)), Custom String( + "Augment: Health and barrier hp increased by 50%; barrier sized doubled")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Perpetual Energy: secondary inflicts burn damage that continues to last until the enemy dies")); + } +} + +rule("Zenyatta Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Vigor: The ally under the effect of Harmony Orb is immune to damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Zenyatta), Button(Ultimate)), Custom String( + "Perfect Balance: Transcendence damages enemies in a large proximity")); + } +} + +rule("Ana: Sleep Paralysis") +{ + event + { + Player Dealt Damage; + Team 1; + Ana; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Black), Victim, 1); + Wait(0.250, Ignore Condition); + Set Status(Victim, Null, Knocked Down, 5); + } +} + +rule("Ana: Multinade") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.AbilityCountdown = 4; + While(Event Player.AbilityCountdown > 0); + Wait(0.030, Ignore Condition); + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Cancel Primary Action(Event Player); + Wait(0.050, Ignore Condition); + Press Button(Event Player, Button(Ability 2)); + Event Player.AbilityCountdown -= 1; + End; + Wait(2, Ignore Condition); + } +} + +rule("Brigitte: Heavy Iron") +{ + event + { + Player Dealt Damage; + Team 1; + Brigitte; + } + + conditions + { + (Event Ability == Button(Primary Fire) || Event Ability == Button(Ability 1)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Victim, 1.500); + Set Status(Victim, Null, Rooted, 0.500); + Set Environment Credit Player(Victim, Event Player); + } +} + +rule("Brigitte: Endeavor") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Ability Cooldown(Event Player, Button(Secondary Fire)) >= 0.100; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Eye Position(Event Player), 15); + Heal(Players Within Radius(Event Player, 15, Team Of(Event Player), Off), Event Player, 200); + Event Player.DamageDealt *= 2.500; + Set Move Speed(Event Player, 100 * 1.750); + Add Health Pool To Player(Event Player, Armor, Max Health(Event Player) / 2, False, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(Is Dead(Event Player), 6); + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Move Speed(Event Player, 100); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Mercy: Angelic Blessing") +{ + event + { + Player Dealt Healing; + All; + Mercy; + } + + conditions + { + Event Player.Abilities[8] == True; + Healee != Event Player; + Normalized Health(Healee) < True; + } + + actions + { + Set Ultimate Charge(Healee, Ultimate Charge Percent(Healee) + 1); + Wait(0.400, Ignore Condition); + } +} + +rule("Mercy: Aurora") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ultimate(Event Player) == True; + } + + actions + { + Wait(1.500, Ignore Condition); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(All Teams), Event Player, True); + Create Beam Effect(All Players(All Teams), Mercy Heal Beam, Event Player, Event Player.Ability_Projectile1, Color(White), + Visible To Position and Radius); + Event Player.Effects_[3] = Last Created Entity; + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 70, Destination and Rate); + While(Event Player.Ability_End != Event Player.Ability_Projectile1); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Event Player.Ability_Projectile1, 1); + Wait(0.032, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[3]); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 120); + Loop If Condition Is True; + } +} + +rule("Lucio: Healing Wave") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4); + Heal(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 4, 4, Team Of(Event Player), Surfaces), + Event Player, Max Health(Filtered Array(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4, Team Of(Event Player), Surfaces), Is Alive(Current Array Element))) * 0.300); + } +} + +rule("Lucio: Reverse Amp") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + If(Is Using Ability 1(Event Player)); + Set Status(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Rooted, 4); + Else; + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 16.250); + End; + Play Effect(All Players(All Teams), Ring Explosion, Is Using Ability 1(Event Player) ? Color(Green) : Color(Yellow), Event Player, + 1); + Wait(0.400, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Hose") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Event Player.Abilities[8] == True; + Ability Resource(Event Player, Button(Primary Fire)) > False; + } + + actions + { + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Facing Direction Of(Event Player), 15, To World, + Cancel Contrary Motion); + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && !Is In Line of Sight(Current Array Element, Event Player, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Up, 8, To World, Cancel Contrary Motion); + Start Damage Over Time(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), + Distance Between(Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS)), Event Player, 1, 15); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Flourish - Damage") +{ + event + { + Player Dealt Damage; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("[Moira] Flourish - Healing") +{ + event + { + Player Dealt Healing; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Heal(Healee, Event Player, Event Healing * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Healee, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("Baptiste: Corrode") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 20); + Wait(0.200, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 12); + } +} + +rule("Baptiste: Breakthrough") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Status(Event Player, Unkillable) == True; + (Event Player.Abilities[12] ? Players On Hero(Hero(Baptiste), Team Of(Event Player)) : Empty Array).Abilities[12] == True; + } + + actions + { + Heal(Event Player, Event Player, 10000); + Set Status(Event Player, Null, Invincible, 0.800); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ashe: Firebourne") +{ + event + { + Player Dealt Damage; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability == Button(Primary Fire); + Has Status(Victim, Burning) == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Null, Burning, 10); + Start Damage Over Time(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Event Player, 10, 15); + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 5); + Wait(0.250, Ignore Condition); + } +} + +rule("Ashe: Taunt") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Damage(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, Burning)), + Event Player, 125); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Frozen, + 0.016); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Stunned, + 2); + } +} + +rule("D.Va: Voltage Grid") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 2, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 5, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 8, 0.500); + Wait(0.300, Ignore Condition); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Wait(0.016, Ignore Condition); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Loop If Condition Is True; + } +} + +rule("D.Va: Shooting Star") +{ + event + { + Player Dealt Knockback; + Team 1; + D.Va; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, 40); + Set Status(Victim, Null, Burning, 3); + Start Damage Over Time(Victim, Event Player, 3, 35); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 1); + } +} + +rule("Genji: Venomous Strike") +{ + event + { + Player Dealt Damage; + Team 1; + Genji; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 3, 25); + Start Damage Over Time(Victim, Event Player, 3, 25); + Damage(Victim, Event Player, 25); + Heal(Event Player, Event Player, 25); + } +} + +rule("Genji: Dragon's Breath") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is Firing Primary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Good Aura, Color(Lime Green), Event Player.Ability_Projectile1, 1, + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 80, Destination and Rate); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True); + Wait Until(Event Player.Ability_End == Event Player.Ability_Projectile1, 1); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Green), Event Player.Ability_Projectile1, 100); + Play Effect(All Players(All Teams), Bad Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Green), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 100); + } +} + +rule("[Hanzo] Stormbreak (Storm_Effects6)") +{ + event + { + Player Died; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[8] == True; + Hero Of(Attacker) == Hero(Hanzo); + } + + actions + { + Event Player.Storm_Projectile = Eye Position(Event Player); + Event Player.Storm_EndPoint = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Up * 12, Null, + All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Storm_Projectile, Event Player.Storm_EndPoint, 4, Destination and Rate); + Create Effect(All Players(All Teams), Cloud, Color(White), Vector(False, -0.500, False) + Event Player.Storm_Projectile, 4, + Visible To Position and Radius); + Event Player.Storm_Effects[3] = Last Created Entity; + Create Effect(All Players(All Teams), Bad Aura, Color(White), Event Player.Storm_Projectile, 3, Visible To Position and Radius); + Event Player.Storm_Effects[4] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(White), Event Player.Storm_Projectile, 3.500, Visible To Position and Radius); + Event Player.Storm_Effects[5] = Last Created Entity; + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Storm_Projectile, Ray Cast Hit Position( + Event Player.Storm_Projectile, Vector(0.100, 0, 0) + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), + False), Color(Aqua), Visible To Position and Radius); + Event Player.Storm_Effects[6] = Last Created Entity; + While(Distance Between(Event Player.Storm_Projectile, Event Player.Storm_EndPoint) > 1); + Wait(0.600, Ignore Condition); + Damage(Players Within Radius(Ray Cast Hit Position(Event Player.Storm_Projectile, Event Player.Storm_Projectile + Down * 1000, + Null, All Players(All Teams), False), 3, Team Of(Event Player), Surfaces), Attacker, 50); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + End; + Destroy Effect(Event Player.Storm_Effects[3]); + Destroy Effect(Event Player.Storm_Effects[4]); + Destroy Effect(Event Player.Storm_Effects[5]); + Destroy Effect(Event Player.Storm_Effects[6]); + } +} + +rule("Hanzo: Punch II") +{ + event + { + Player Dealt Damage; + Team 1; + Hanzo; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + Hero Of(Victim) != Hero(Torbjörn); + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.800); + Apply Impulse(Victim, Facing Direction Of(Event Player), 12, To World, Cancel Contrary Motion); + Apply Impulse(Victim, Up, 5, To World, Cancel Contrary Motion); + Set Environment Credit Player(Victim, Event Player); + Set Status(Victim, Null, Stunned, 1); + } +} + +rule("Widowmaker: Kiss Of Death") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + (Normalized Health(Victim) <= 0.300 || Event Damage >= Normalized Health(Victim) + Event Damage) == True; + Is Firing Secondary(Event Player) == True; + Event Ability == Button(Primary Fire); + Event Player.Abilities[8] == True; + Event Damage >= 40; + Event Was Critical Hit == True; + } + + actions + { + Kill(Victim, Event Player); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 2), Victim, 3); + Damage(Players Within Radius(Victim, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage * 1.500); + } +} + +rule("Widowmaker: Epidemic") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 8); + Play Effect(All Players(All Teams), Good Explosion, Color(Purple), Victim, 4); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Victim, 16); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Victim, 3); + Start Damage Over Time(Players Within Radius(Victim, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, 50); + Start Heal Over Time(Event Player, Event Player, 3, 50); + Wait(0.500, Ignore Condition); + } +} + +rule("McCree: Panic") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Victim.Feared_until = Total Time Elapsed + 3.500; + } +} + +rule("McCree: Panic - Damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), + Event Player.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 220, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("McCree: Clocked") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Damage(Victim, Event Player, Event Damage * 1.500); + Set Status(Victim, Null, Knocked Down, 3); + } +} + +rule("Reinhardt: Fire Blast") +{ + event + { + Player Dealt Damage; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Start Damage Over Time(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, 20); + Set Status(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Burning, 5); + } +} + +rule("Reinhardt: Epicenter") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is On Ground(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, Knocked Down, 2.500); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 10); + Damage(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, 50); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 20); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 30); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 40); + Wait(5, Ignore Condition); + } +} + +rule("[Soldier: 76] Rocket Assault Rifle") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile2 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(-2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Projectile1 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Position = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, + 0), Event Player, Rotation); + Event Player.Ability_End = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, 0), + Event Player, Rotation); + Chase Player Variable At Rate(Event Player, Ability_Position, Event Player.Ability_Projectile1, 60, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_End, Event Player.Ability_Projectile2, 60, Destination and Rate); + Wait Until(Event Player.Ability_Position == 0 && Event Player.Ability_End == 0, 2.500); + } +} + +rule("[Soldier: 76] First Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile1 != Event Player.Ability_Position; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_Position, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_Position, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_Position, 2.500); + Stop Chasing Player Variable(Event Player, Ability_Position); + Wait(0.016, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 80); + Stop Chasing Player Variable(Event Player, Ability_Position); + Event Player.Ability_Position = 0; + Event Player.Ability_Projectile1 = 0; + Wait(0.016, Ignore Condition); + } +} + +rule("[Soldier: 76] Second Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile2 != Event Player.Ability_End; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_End, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_End, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_End, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_End, 2.500); + Stop Chasing Player Variable(Event Player, Ability_End); + Damage(Players Within Radius(Event Player.Ability_End, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Event Player.Ability_End = 0; + Event Player.Ability_Projectile2 = 0; + } +} + +rule("Soldier: 76 - Init rockets") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile1 = Event Player.Ability_Position; + Event Player.Ability_Projectile2 = Event Player.Ability_End; + } +} + +rule("[Soldier: 76] Shoulder Check") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 3; + Is Alive(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) == True; + } + + actions + { + Damage(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Event Player, 55); + Set Status(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Null, Knocked Down, 1.500); + Apply Impulse(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Facing Direction Of(Event Player), 15, + To World, Cancel Contrary Motion); + Apply Impulse(Event Player, Vector(0, 8, 15), 15, To Player, Cancel Contrary Motion); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Closest Player To(Event Player, Opposite Team Of(Team Of( + Event Player))), 1); + Set Ability Cooldown(Event Player, Button(Melee), 0); + Press Button(Event Player, Button(Melee)); + Wait(1, Ignore Condition); + } +} + +rule("Torbjorn: Melting Point") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Event Player.Abilities[8] == True; + (Is Using Ability 2(Event Player) || Is Using Ultimate(Event Player)) == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Event Player, 8); + Play Effect(All Players(All Teams), Bad Explosion, Color(Yellow), Event Player, 8); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 16); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, + 25); + Set Status(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Off), Null, Burning, 3); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player, 100); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Torbjorn: Roots of Magma") +{ + event + { + Player Dealt Damage; + Team 1; + Torbjörn; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Set Status(Victim, Null, Rooted, 1); + Wait(1, Ignore Condition); + } +} + +rule("Tracer: Vortex") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, 0); + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 10); + Play Effect(All Players(All Teams), Ring Explosion, Color(Red), Position Of(Event Player), 24); + Play Effect(All Players(All Teams), Ring Explosion, Color(Yellow), Position Of(Event Player), 18); + Play Effect(All Players(All Teams), Ring Explosion, Color(Green), Position Of(Event Player), 12); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player), 6); + Set Environment Credit Player(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player); + } +} + +rule("Tracer: Vortex 2") +{ + event + { + Player Received Healing; + Team 2; + All; + } + + conditions + { + Healer.Abilities[8] == True; + Hero Of(Healer) == Hero(Tracer); + Is Using Ability 2(Healer) == True; + Event Ability == Null; + Event Damage <= 20; + } + + actions + { + Apply Impulse(Event Player, Up, 5, To World, Cancel Contrary Motion); + Wait(0.100, Ignore Condition); + Apply Impulse(Event Player, Direction Towards(Event Player, Healer), Distance Between(Event Player, Healer) * 3.500, To World, + Cancel Contrary Motion); + Set Status(Event Player, Null, Rooted, 1.300); + } +} + +rule("Tracer: Chain Reaction") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is True For Any(Filtered Array(All Players(Team Of(Event Player)), Current Array Element.Chain_Reaction_On), Distance Between( + Event Player, Current Array Element) <= 8 && True) == True; + Event Player.Chain_Reaction_Immune == False; + Event Player.Chain_Reaction_On == False; + Is Alive(Event Player) == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Event Player.Chain_Reaction_On = True; + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player, 3); + } +} + +rule("Tracer: Chain Reaction 2") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Event Player.Chain_Reaction_On == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Aqua), Event Player, 3); + Damage(Event Player, Players On Hero(Hero(Tracer), Opposite Team Of(Team Of(Event Player))), 200); + Wait(0.500, Ignore Condition); + Event Player.Chain_Reaction_Immune = True; + Event Player.Chain_Reaction_On = False; + Wait(2, Ignore Condition); + Event Player.Chain_Reaction_Immune = False; + } +} + +rule("Tracer: Chain Reaction 3") +{ + event + { + Player Dealt Damage; + Team 1; + Tracer; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Damage > 20; + Event Player.Abilities[12] == True; + } + + actions + { + Victim.Chain_Reaction_On = True; + } +} + +rule("[Winston] Electric Field") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 65); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Orb, Color(White), Event Player.Ability_Projectile1, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Stop Chasing Player Variable(Event Player, Ability_Resource); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Down * 1000, Null, + All Players(All Teams), False); + Wait(0.100, Ignore Condition); + Event Player.Ability_Resource = 5; + Wait(0.250, Ignore Condition); + Chase Player Variable At Rate(Event Player, Ability_Resource, 20, 7, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, Event Player.Ability_Resource, + Destination and Rate); + Wait(8.650, Restart When True); + Event Player.Ability_Active = False; + } +} + +rule("[Winston] Electric Field 2") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 33); + Play Effect(All Players(All Teams), Ring Explosion, Color(Blue), Event Player.Ability_Projectile1, 10); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 80); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Event Player.Ability_Projectile1, 12); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player.Ability_Projectile1, 125); + } +} + +rule("Winston: Next Generation") +{ + event + { + Player Earned Elimination; + Team 1; + Winston; + } + + conditions + { + Ultimate Charge Percent(Event Player) <= 80; + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 15); + } +} + +rule("Pharah: Head Trauma") +{ + event + { + Player Dealt Knockback; + Team 1; + Pharah; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Victim != Event Player; + } + + actions + { + Damage(Victim, Event Player, Max Health(Victim) * 0.300); + Set Status(Victim, Event Player, Knocked Down, 1); + Play Effect(All Players(All Teams), Good Explosion, Color(Team 1), Victim, 1); + } +} + +rule("Pharah: Thunderbird") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[12] == True; + Hero Of(Event Player) == Hero(Pharah); + } + + actions + { + Event Player.DamageDealt *= 4; + Start Damage Modification(All Players(All Teams), Event Player, 25, Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Add Health Pool To Player(Event Player, Shields, 150, True, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(!Event Player.Abilities[12] || Hero Of(Event Player) != Hero(Pharah), 99999); + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Stop Damage Modification(Event Player.Modification_Damage[1]); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + } +} + +rule("Orisa: Unstoppable Force") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Direction = Facing Direction Of(Event Player); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Sphere, Color(Green), Event Player.Ability_Projectile1, 4, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player) + Facing Direction Of(Event Player) * 0.500; + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 100, Null, All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 25, Destination and Rate); + Wait(0.250, Ignore Condition); + Wait Until((!Event Player.Gen_Available && Is Button Held(Event Player, Button(Secondary Fire))) || ( + Event Player.Ability_Projectile1 == Event Player.Ability_End), 99999); + Stop Chasing Player Variable(Event Player, Ability_Projectile1); + Wait(0.500, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, + 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Orisa: Availability for Halt!") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Available = True; + Wait Until(!Is Button Held(Event Player, Button(Secondary Fire)), 99999); + Event Player.Gen_Available = False; + } +} + +rule("Orisa: Drag effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Player.Ability_Active == True; + } + + actions + { + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Is Alive(Event Player) ? Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of( + Event Player)), Surfaces) : Empty Array, Event Player.Ability_Projectile1), 8, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Event Player.Ability_Projectile1, Event Player.Ability_End), 20, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Up, 5, + To Player, Cancel Contrary Motion); + Wait(0.200, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Orisa: Immoveable Object - Reduce dmg") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Damage Received(Event Player, 100 * 0.003); + Wait Until(!Is Using Ability 1(Event Player), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Orisa: Immovable Object - Healing") +{ + event + { + Player Took Damage; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Event Player, Null, Event Damage * 3); + } +} + +rule("[Reaper] Shadow Streak (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Event Player.Ability_Position = Position Of(Event Player) + Vector(0, 1, 0); + Wait(2, Abort When False); + Event Player.Ability_End = Position Of(Event Player) + Vector(0, 1, 0); + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Ability_End, Event Player.Ability_Position, Color(Black), + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player) || Is Using Ability 2(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage start to end (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players(Opposite Team Of(Team Of( + Event Player))), Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_Position, + Event Player.Ability_End, All Living Players(All Teams), Event Player, True), 1); + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage end to start (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Players(Opposite Team Of(Team Of(Event Player))), + Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_End, + Event Player.Ability_Position, All Living Players(All Teams), Event Player, True), 1); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Reaper: Loom") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Hacked, 1.500); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Rooted, 1.500); + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Event Player, 45); + } +} + +rule("Sigma: Gravity Well") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, 25); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Null, Rooted, 2); + Set Status(Event Player, Null, Invincible, 1); + Play Effect(Event Player, Ring Explosion, Color(Blue), Eye Position(Event Player), 50); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Sigma: Gravity Channels") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ultimate(Event Player)), Event Player, 150, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[12], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Echo: Focusing Optics") +{ + event + { + Player Dealt Damage; + Team 1; + Echo; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Normalized Health(Victim) > 0.500; + Normalized Health(Victim) <= 0.900; + Is Duplicating(Event Player) == False; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 3); + Play Effect(All Players(All Teams), Bad Explosion, Color(Violet), Victim, 0.500); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Wait(0.700, Abort When False); + Cancel Primary Action(Event Player); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Set Projectile Speed(Event Player, 100); + Wait(0.150, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Bomblets") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Is In Alternate Form(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Orange), Null + Ray Cast Hit Position(Eye Position(Event Player), + Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, All Living Players(Opposite Team Of(Team Of( + Event Player))), All Players(Team Of(Event Player)), True), 2); + Damage(Players Within Radius(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 2, + Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 12); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Taser - Loop damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is True For Any(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive(Current Array Element) + && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status(Current Array Element, + Phased Out) && Distance Between(Event Player, Current Array Element) <= 25) == True; + Is Alive(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Explosion Sound, Color(White), Event Player.Ability_Player, 80); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Event Player.Ability_Player, 1); + Event Player.Ability_Player = Filtered Array(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive( + Current Array Element) && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status( + Current Array Element, Phased Out) && Distance Between(Event Player, Current Array Element) <= 25); + Damage(Players Within Radius(Event Player.Ability_Player, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 30); + Wait(0.450, Ignore Condition); + Loop If Condition Is True; + Event Player.Ability_Player = Null; + } +} + +rule("Bastion: Taser - Visual beam") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player + Vector(False, 1, False), + Event Player.Ability_Player != Null ? Event Player.Ability_Player : Event Player, Color(Aqua), + Visible To Position Radius and Color); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[12], 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Sombra: Malware") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, + Hacked) || Current Array Element.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 200, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Sombra: Glitch") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Ability_Active = True; + Event Player.Ability_Position = Position Of(Event Player); + Create Effect(All Players(All Teams), Sphere, Color(Purple), Event Player.Ability_Position, 15, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait(8, Ignore Condition); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Sombra: Glitch - Loop") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Ability_Active == True; + } + + actions + { + Set Status(Players Within Radius(Event Player.Ability_Position, 15, Opposite Team Of(Team Of(Event Player)), Off), Null, Hacked, + 0.750); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Mei: Cold Snap") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Event Player, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Is Using Ability 1(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Damage(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Frozen, 2); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Rooted, 2); + Play Effect(All Players(All Teams), Ring Explosion, Color(White), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Sky Blue), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player) + Vector(0, 1, 0), 20); + } +} + +rule("Mei: Icebound") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Aqua), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Set Projectile Speed(Event Player, 200); + Wait Until(!Is Firing Secondary(Event Player), 99999); + Destroy Effect(Event Player.Effects_[2]); + Set Projectile Speed(Event Player, 100); + } +} + +rule("Mei: Icebound - Icicles hit") +{ + event + { + Player Dealt Damage; + Team 1; + Mei; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 1.250); + Set Status(Victim, Null, Frozen, 1); + Set Status(Victim, Null, Rooted, 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Victim, 1); + } +} + +rule("Wrecking Ball: Mirror Ball") +{ + event + { + Player Took Damage; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 4.500, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage); + Wait(0.100, Ignore Condition); + } +} + +rule("Wrecking Ball: Distort") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Set Status(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Hacked, Count Of( + Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces)) * 1.500); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Violet), Position Of(Event Player), 125); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Sound, Color(Purple), Position Of(Event Player), 16); + Play Effect(All Players(All Teams), Explosion Sound, Color(Violet), Position Of(Event Player), 80); + } +} + +rule("Symmetra: High voltage") +{ + event + { + Player Dealt Final Blow; + Team 1; + Symmetra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Victim, 10); + Play Effect(All Players(All Teams), Bad Explosion, Color(Aqua), Victim, 8); + Damage(Players Within Radius(Victim, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 150); + } +} + +rule("Symmetra: Energy Source") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is True For Any(Players On Hero(Hero(Symmetra), Team Of(Event Player)), Is Using Ultimate(Current Array Element) + && Current Array Element.Abilities[12]) == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 1, 40); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Event Player, 0.100); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Junkrat: Pyromania") +{ + event + { + Player Dealt Knockback; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability != Button(Melee); + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 2, 30); + Set Status(Victim, Null, Burning, 2); + } +} + +rule("Junkrat: Short Fused") +{ + event + { + Player Dealt Damage; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + } + + actions + { + Event Player.Ability_Countdown = 4; + While(Event Player.Ability_Countdown > 0); + Event Player.Ability_Countdown -= 1; + Event Player.Ability_Position = Position Of(Victim) + Vector(Random Real(-2, 2), Random Real(-2, 2), Random Real(-2, 2)); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 4); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Position, 4); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 35); + Set Status(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player, Stunned, 0.800); + Wait(0.200, Ignore Condition); + End; + } +} + +rule("Zenyatta: Vigor") +{ + event + { + Player Dealt Healing; + Team 1; + Zenyatta; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Healee, Null, Invincible, 1); + Wait(0.800, Ignore Condition); + } +} + +rule("Zenyatta: Perfect Balance") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Over Time(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 0.750, 200); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player, 24); + Wait(0.600, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Stench") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Violet), Event Player, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Roadhog: Stench effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 8; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 9); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Rusted Anchor") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ability 1(Event Player)), Event Player, 400, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Roadhog: Rusted Anchor - Reset cooldown") +{ + event + { + Player Earned Elimination; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ability 1(Event Player), 3); + Set Ability Cooldown(Event Player, Button(Ability 1), False); + } +} + +rule("Zarya: Augment") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Scaling Barriers(Event Player, 2, True); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5 + 50; + Set Max Health(Event Player, Event Player.PlayerHealth); + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Zarya), 99999); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Stop Scaling Barriers(Event Player); + } +} + +rule("Zarya: Perpetual Energy") +{ + event + { + Player Dealt Knockback; + Team 1; + Zarya; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Event Player.Abilities[12] == True; + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 9999, 15); + Set Status(Victim, Null, Burning, 9999); + } +} + +rule("Doomfist: Phase Shifter") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + (Is Firing Secondary(Event Player) || Is Using Ability 1(Event Player) || Is Using Ability 2(Event Player)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Event Player, Null, Phased Out, 1); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ultimate(Event Player), 99999); + Event Player.Ability_Position = Position Of(Event Player); + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player), 8); + Event Player.Ability_Active = False; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player.Ability_Position, 16); + While(Event Player.Ability_Active == True); + Damage(Players Within Radius(Event Player.Ability_Position, 8, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 34); + Wait(0.235, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[1]); + Destroy Effect(Event Player.Effects_[2]); + } +} + +rule("Team 1 (Perk): Sharpshooter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Global.Perk[0] == True; + Event Ability != Null; + Distance Between(Event Player, Victim) >= 10; + } + + actions + { + Damage(Victim, Event Player, 50 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Perk): Bulletstorm") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.Perk[1] == True; + (Ammo(Event Player, 0) < Max Ammo(Event Player, 0) || Ammo(Event Player, 1) < Max Ammo(Event Player, 1)) == True; + } + + actions + { + Set Ammo(Event Player, 0, 1000); + Set Ammo(Event Player, 1, 1000); + } +} + +rule("Team 1 Challenges") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + If(Global.Perk[2] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[17] = Last Text ID; + End; + If(Global.Perk[0] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[18] = Last Text ID; + End; + If(Global.Perk[1] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[19] = Last Text ID; + End; + If(Global.MaxHealthDone == 50); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + End; + } +} + +rule("Remove Auto Repair when Player leaves") +{ + event + { + Player Left Match; + Team 1; + All; + } + + actions + { + Global.AutoRepair -= Event Player.Abilities[16]; + } +} + +rule("Refund") +{ + event + { + Subroutine; + Refund; + } + + actions + { + "Refund Money" + Event Player.Money[0] += Event Player.Money[1]; + Event Player.Money[1] = 0; + "Reset Headhunter" + Event Player.Abilities[1] = 0; + "Reset Ambush" + Event Player.Abilities[2] = 0; + "Reset QuickFix" + Event Player.Abilities[3] = 0; + "Reset HeavyWeight" + Event Player.Abilities[4] = 0; + "Reset Charged" + Event Player.Abilities[5] = 0; + "Reset Haste" + Event Player.Abilities[6] = 0; + "Reset HeavyImpact" + Event Player.Abilities[7] = 0; + "Reset HeroTalent1" + Event Player.Abilities[8] = 0; + "Reset SecondWind" + Event Player.Abilities[9] = 0; + "Reset BindingHeal" + Event Player.Abilities[10] = 0; + "Reset Resilience" + Event Player.Abilities[11] = 0; + "Reset HeroTalent2" + Event Player.Abilities[12] = 0; + "Reset Damage" + Event Player.Abilities[13] = 0; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + "Reset Health" + Event Player.Abilities[14] = 0; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + If(Global.MaxHealthDone == 0); + End; + "Reset Healing" + Event Player.Abilities[15] = 0; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + "Reset AutoRepair" + Global.AutoRepair -= Event Player.Abilities[16]; + Event Player.Abilities[16] = 0; + } +} + +rule("Lucio Dash HUD Creation") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + } + + actions + { + If(Event Player.Lucio_Dash_Active == False); + Event Player.Lucio_Dash_Active = True; + Create HUD Text(Event Player, Null, Null, Custom String("{0} Slam on ground - Press: {1}", Ability Icon String(Hero(Wrecking Ball), + Button(Crouch)), Input Binding String(Button(Crouch))), Left, 1000, Color(White), Color(White), Color(White), + Visible To and String, Default Visibility); + Event Player.Lucio_Dash_Icon = Last Text ID; + End; + } +} + +rule("Lucio Dash Remove HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) != Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + } + + actions + { + Destroy HUD Text(Event Player.Lucio_Dash_Icon); + Event Player.Lucio_Dash_Active = False; + } +} + +rule("Lucio Dash") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + Is On Ground(Event Player) == False; + Is Button Held(Event Player, Button(Crouch)) == True; + } + + actions + { + Apply Impulse(Event Player, Down, 20, To World, Cancel Contrary Motion); + } +} + +rule("Ana Self-Nano") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + Ultimate Charge Percent(Event Player) == 100; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Abort If(Global.SelfNanoWorkshopSetting == False && Number Of Players(Team 1) > 1); + Wait(0.100, Ignore Condition); + If(Is Using Ultimate(Event Player) == False); + Create Dummy Bot(Hero(Ana), Team Of(Event Player), -1, Position Of(Event Player) + Backward, Eye Position(Event Player)); + Event Player.AnaEntityID = Last Created Entity; + Wait(0.100, Ignore Condition); + Set Ultimate Charge(Event Player.AnaEntityID, 100); + Start Facing(Event Player.AnaEntityID, Direction Towards(Eye Position(Event Player.AnaEntityID), Position Of(Event Player) + Up), + 1000, To World, Direction and Turn Rate); + Set Invisible(Event Player.AnaEntityID, All); + Set Status(Event Player.AnaEntityID, Null, Phased Out, 9999); + Wait(0.150, Ignore Condition); + Press Button(Event Player.AnaEntityID, Button(Ultimate)); + Set Ultimate Charge(Event Player, 0); + Wait(0.150, Ignore Condition); + Teleport(Event Player.AnaEntityID, Position Of(First Of(Spawn Points(Team Of(Event Player))))); + Wait(10, Ignore Condition); + Destroy Dummy Bot(Team Of(Event Player), Slot Of(Event Player.AnaEntityID)); + End; + } +} + +rule("Reinhard Charge Cancel") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + } + + actions + { + Wait(0.600, Ignore Condition); + Wait Until(Is Button Held(Event Player, Button(Ability 1)), 5); + Set Status(Event Player, Null, Rooted, 0.001); + Wait Until(Event Player.ReinPin, 1); + If(Event Player.ReinPin != 0); + Apply Impulse(Event Player.ReinPin, Facing Direction Of(Event Player), 15, To World, Cancel Contrary Motion); + End; + } +} + +disabled rule("Map Editor Walls") +{ + event + { + Ongoing - Global; + } +} + +rule("Initial Global") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Empty Array; + Global.AllDir = Empty Array; + Global.firstpos = Empty Array; + Global.secondpos = Empty Array; + Global.firstpoint2 = Empty Array; + Global.secondpoint2 = Empty Array; + Global.second = Empty Array; + Global.z = Empty Array; + Global.Wall_ID = Empty Array; + Global.g_beamType = Empty Array; + } +} + +rule("Initial Player") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.filterpos = 0; + Event Player.lastsavedpos = 0; + Event Player.closestbodypos = 0; + Event Player.fullbodypos = 0; + Event Player.prevpos_intersection = 0; + Event Player.active_wall = Empty Array; + Event Player.closestwall = Empty Array; + } +} + +rule("Collision Logic") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Event Player.lastsavedpos = (Eye Position(Event Player) + Position Of(Event Player)) / 2; + Wait(0.016, Ignore Condition); + Event Player.closestwall = Filtered Array(Global.AllPos, Distance Between(Global.AllPos[Current Array Index], Event Player) + <= Distance Between(Global.AllPos[Current Array Index], Global.firstpos[Current Array Index]) + || Event Player.active_wall[Current Array Index] == 1 || (Dot Product(Direction Towards(Current Array Element, + Event Player.lastsavedpos), Global.AllDir[Current Array Index]) > 0) != (Dot Product(Direction Towards(Current Array Element, + Event Player), Global.AllDir[Current Array Index]) > 0)); + For Player Variable(Event Player, x, 0, Count Of(Event Player.closestwall), 1); + Global.z = Index Of Array Value(Global.AllPos, Event Player.closestwall[Event Player.x]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3 || Global.Wall_ID[Global.z] == 5); + If(Y Component Of(Global.firstpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.firstpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.firstpos[Global.z]; + Else If(Y Component Of(Global.secondpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.secondpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.secondpos[Global.z]; + Else; + Event Player.closestbodypos = Position Of(Event Player); + End; + Event Player.fullbodypos = Vector(X Component Of(Eye Position(Event Player)), Y Component Of(Event Player.closestbodypos), + Z Component Of(Eye Position(Event Player))); + Event Player.filterpos = Event Player.fullbodypos + Global.AllDir[Global.z] * Dot Product( + Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) / Dot Product(Global.AllDir[Global.z], + Global.AllDir[Global.z]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3); + If((Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.lastsavedpos), Global.AllDir[Global.z]) > 0) != ( + Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.fullbodypos), Global.AllDir[Global.z]) > 0)); + Event Player.intersection_length = Dot Product(Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) + / Dot Product(Direction Towards(Event Player.lastsavedpos, Event Player.fullbodypos), Global.AllDir[Global.z]); + Event Player.prevpos_intersection = Event Player.fullbodypos + Direction Towards(Event Player.lastsavedpos, + Event Player.fullbodypos) * Vector(1, Empty Array, 1) * Event Player.intersection_length; + If(Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of( + Global.firstpos[Global.z]), Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], + Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of( + Global.firstpos[Global.z]), Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), + Direction Towards(Global.firstpos[Global.z], Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards( + Global.secondpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.prevpos_intersection)) + >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.secondpos[Global.z], Event Player.prevpos_intersection)) >= 0); + Cancel Primary Action(Event Player); + Teleport(Event Player, Event Player.prevpos_intersection + Direction Towards(Event Player.prevpos_intersection, + Event Player.lastsavedpos) * Vector(1, Empty Array, 1) * 2); + End; + End; + End; + Event Player.thickness = 0; + If(Global.Wall_ID[Global.z] == 5); + Event Player.thickness = 4; + Else; + Event Player.thickness = 1; + End; + If(Distance Between(Event Player.fullbodypos, Event Player.filterpos) <= Event Player.thickness && Dot Product(Direction Towards( + Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], Event Player.filterpos)) + >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.firstpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector( + X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), Z Component Of( + Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product( + Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), Y Component Of( + Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], + Event Player.filterpos)) >= 0); + If(!Global.is_Grounded); + Set Gravity(Event Player, 100); + End; + If(Event Player.active_wall[Global.z] == False); + Event Player.active_wall[Global.z] = 1; + If((Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3) && Global.is_Grounded == False); + Set Gravity(Event Player, 100); + Else If(Global.Wall_ID[Global.z] == 5); + Disable Movement Collision With Environment(Event Player, False); + End; + End; + If(Global.Wall_ID[Global.z] == 1); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos) * Vector(1, Empty Array, 1), 0.001, + To World, Cancel Contrary Motion); + Set Move Speed(Event Player, 100 - Dot Product(Direction Towards(Eye Position(Event Player), Eye Position(Event Player) + + World Vector Of(Throttle Of(Event Player), Event Player, Rotation)), Direction Towards(Event Player.filterpos, + Event Player.fullbodypos) * -1) * 100); + Else If(Global.Wall_ID[Global.z] == 3); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos), Speed Of(Event Player), To World, + Cancel Contrary Motion); + End; + Else; + Event Player.active_wall[Global.z] = 0; + Set Move Speed(Event Player, 100); + End; + End; + End; + Loop; + } +} + +rule("Reset") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Count Of(Filtered Array(Event Player.active_wall, Current Array Element != 0)) == 0; + } + + actions + { + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("Effect Creation") +{ + event + { + Ongoing - Global; + } + + actions + { + Wait(5, Ignore Condition); + If(Global.showwalls); + For Global Variable(x, 0, Count Of(Global.AllPos), 1); + If(Global.Wall_ID[Global.x] == 5); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Else; + Skip(Array(14, 0, 5, 10)[Index Of Array Value(Array(1, 2, 3), Global.g_beamType[Global.x]) + 1]); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(9); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(4); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + End; + Wait(0.016, Ignore Condition); + End; + End; + } +} + +rule("Wall Data") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Array(Vector(155.968, 12.470, -30.507), Vector(155.962, 12.472, -62.500), Vector(81.153, 6.453, -103.851), Vector( + 69.148, 6.474, -104.548)); + Global.AllDir = Array(Vector(-1, 0, -0.002), Vector(1, 0, -0.001), Vector(0, 0, 1), Vector(0.001, 0, 1)); + Global.firstpos = Array(Vector(155.971, 11.047, -31.771), Vector(155.964, 11.050, -61.229), Vector(79.761, 5.030, -103.852), + Vector(67.738, 5.022, -104.547)); + Global.secondpos = Array(Vector(155.965, 13.894, -29.242), Vector(155.960, 13.894, -63.771), Vector(82.544, 7.876, -103.851), + Vector(70.558, 7.925, -104.550)); + Global.firstpoint2 = Array(Vector(155.971, 13.894, -31.771), Vector(155.964, 13.894, -61.229), Vector(79.761, 7.876, -103.852), + Vector(67.738, 7.925, -104.547)); + Global.secondpoint2 = Array(Vector(155.965, 11.047, -29.242), Vector(155.960, 11.050, -63.771), Vector(82.544, 5.030, -103.851), + Vector(70.558, 5.022, -104.550)); + Global.z = 3; + Global.g_beamType = Array(1, 1, 1, 1); + Global.showwalls = True; + Global.Wall_ID = Array(5, 5, 5, 5); + } +} + +disabled rule("NEW SHOP") +{ + event + { + Ongoing - Global; + } +} + +rule("Setting Shop Position") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.ShopCamPos = 900 * Up; + Global.ShopPosAngle[1] = Direction From Angles(Horizontal Angle From Direction(Forward), Vertical Angle From Direction(Forward) + - 90); + Global.ShopPosAngle[0] = Cross Product(Global.ShopPosAngle[1], Forward); + Global.ShopBasePos = Global.ShopCamPos - 9 * Global.ShopPosAngle[1] + 142 * Forward; + } +} + +rule("Create Shop Buttons") +{ + event + { + Ongoing - Global; + } + + actions + { + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] + 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] - 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Refund"), + Global.ShopBasePos + 45 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 3, Do Not Clip, Visible To, Color(Green), + Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("[{0}] Leave", + Input Binding String(Button(Reload))), Global.ShopBasePos + 45 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 3, + Do Not Clip, Visible To and String, Color(Green), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("{0}$\n", Local Player.Money[0]), + Global.ShopBasePos + 36.500 * Global.ShopPosAngle[1], 3, Do Not Clip, Visible To and String, Color(White), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("▲"), Update Every Frame( + Global.ShopBasePos - (4 + Vertical Facing Angle Of(Local Player)) * Global.ShopPosAngle[1] + Horizontal Facing Angle Of( + Local Player) * Global.ShopPosAngle[0]), 4, Do Not Clip, Visible To Position and Color, Custom Color( + 245 + 10 * Sine From Radians(4 * Total Time Elapsed), 205 + 50 * Sine From Radians(4 * Total Time Elapsed), + 200 * Sine From Radians(4 * Total Time Elapsed), 255), Default Visibility); + "Headhunter" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[1] ? Custom String("Headhunter II\n  800$") : Custom String("Headhunter I\n  800$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[1] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Ambush" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[2] ? Custom String("Ambush II\n 800$") : Custom String("Ambush I\n 800$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[2] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Quick Fix" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[3] ? Custom String("Quick Fix II\n  700$") : Custom String("Quick Fix I\n  700$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[3] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavyweight" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[4] ? Custom String("Heavyweight II\n  1000$") : Custom String("Heavyweight I\n  1000$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[4] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Charged" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[5] ? Custom String("Charged II\n  700$") : Custom String("Charged I\n  700$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[5] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Haste" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[6] ? Custom String("Haste II\n 700$") : Custom String("Haste I\n 700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[6] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavy Impact" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[7] ? Custom String("Heavy Impact II\n  1000$") : Custom String("Heavy Impact I\n  1000$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[7] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 1" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 1\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[8] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "Second Wind" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[9] ? Custom String("Second Wind II\n   900$") : Custom String("Second Wind I\n   900$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[9] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Binding Heal" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[10] ? Custom String("Binding Heal II\n   700$") : Custom String("Binding Heal I\n   700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[10] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Resilience" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[11] ? Custom String("Resilience II\n  800$") : Custom String("Resilience I\n  800$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[11] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 2" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 2\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[12] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "PlusDamage" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Damage\n  400$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealth" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Health\n 400$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Healing\n  400$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, Visible To and String, + Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "+{0} Auto-Repair\n    400$", Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Global.AutoRepair < 5 ? Color(Green) : Color(Gray), Default Visibility); + "Use Update Every Frame to avoid showing the String when the cursor is out of bounds, resulting in 0\r\n ROW 0" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -33.750 ? Array(Custom String("Leave Buy Menu\n"), Custom String( + ""), Custom String(""), Custom String("Refund your money\n"))[Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) + / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, + Color(White), Default Visibility); + "ROW 1" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 22.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -11.250 ? Array(Custom String("Increase your damage by 5%\n"), + Local Player.Abilities[9] ? Custom String( + "Second Wind II: 60% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds") + : Custom String( + "Second Wind I: 30% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds"), + Local Player.Abilities[5] ? Custom String("Charged II: Ultimates cost 40% less\n") : Custom String( + "Charged I: Ultimates cost 20% less\n"), Local Player.Abilities[1] ? Custom String( + "Headhunter II: Critical hits deal 80% more damage\n") : Custom String("Headhunter I: Critical hits deal 40% more damage\n")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 2" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 36.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 11.250 ? Array(Custom String("Increase your health by 5%\n"), + Local Player.Abilities[10] ? Custom String("Binding Heal II: Heal yourself for 50% the amount when healing allies\n") + : Custom String("Binding Heal I: Heal yourself for 25% the amount when healing allies\n"), + Local Player.Abilities[6] ? Custom String( + " Haste II: Ability cooldown is reduced by 50%\nDoes not affect abilities with multiple charges") : Custom String( + " Haste I: Ability cooldown is reduced by 25%\nDoes not affect abilities with multiple charges"), + Local Player.Abilities[2] ? Custom String("Ambush II: Deal 60% more damage when attacking enemies from behind or above\n") + : Custom String("Ambush I: Deal 30% more damage when attacking enemies from behind or above\n"))[Round To Integer(( + Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 3" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 83.750) < 72.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 33.750 ? Array(Custom String("Increase your healing by 5%\n"), + Local Player.Abilities[11] ? Custom String("Resilience II: Take 30% less damage while below 60% health\n") : Custom String( + "Resilience I: Take 30% less damage while below 30% health\n"), Local Player.Abilities[7] ? Custom String( + "Heavy Impact II: Every hit has a chance to stun the enemy for 2 seconds\n") : Custom String( + "Heavy Impact I: Every hit has a chance to stun the enemy for 1 second\n"), Local Player.Abilities[3] ? Custom String( + "Quick Fix II: Eliminations restore 100 HP and shortly increase speed by 40%\n") : Custom String( + "Quick Fix I: Eliminations restore 50 HP and shortly increase speed by 20%\n"))[Round To Integer((Horizontal Facing Angle Of( + Local Player) + 90) / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, + Visible To and String, Color(White), Default Visibility); + "ROW 4" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 133) < 99.250 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 56.250 ? Array(Custom String( + "Increase your auto-repair by {0}/5s\n", Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Custom String("{0}", Local Player.HeroTalentText[2][1]), Custom String("{0}", Local Player.HeroTalentText[1][1]), + Local Player.Abilities[4] ? Custom String( + "Heavyweight II: Your knock back attacks deal 50% more damage and knock back\n            You receive 33% less knock back") + : Custom String( + "Heavyweight I: Your knock back attacks deal 25% more damage and knock back\n            You receive 20% less knock back")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + } +} + +rule("Toggle Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + !Is Dummy Bot(Event Player) == True; + Is Button Held(Event Player, Button(Reload)) == True; + !Is Communicating Any Emote(Event Player) == True; + } + + actions + { + If(Event Player.isInMenu == False); + Wait Until(!Is Button Held(Event Player, Button(Reload)), 0.500); + If(!Is Button Held(Event Player, Button(Reload))); + Abort; + End; + End; + Event Player.isInMenu = !Event Player.isInMenu; + } +} + +rule("Open Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == True; + } + + actions + { + Event Player.PlayerFacing = Facing Direction Of(Event Player); + Start Camera(Event Player, Global.ShopCamPos, Global.ShopCamPos + Forward, 0); + Disable Hero HUD(Event Player); + Call Subroutine(DisablePlayer); + Set Aim Speed(Event Player, 200); + } +} + +rule("Close Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == False; + } + + actions + { + Stop Camera(Event Player); + Enable Hero HUD(Event Player); + Call Subroutine(EnablePlayer); + Set Aim Speed(Event Player, 100); + Set Facing(Event Player, Event Player.PlayerFacing, To World); + } +} + +rule("Subroutine: Disable Player") +{ + event + { + Subroutine; + DisablePlayer; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + Set Primary Fire Enabled(Event Player, False); + Set Secondary Fire Enabled(Event Player, False); + Set Ability 1 Enabled(Event Player, False); + Set Ability 2 Enabled(Event Player, False); + Set Melee Enabled(Event Player, False); + Set Jump Enabled(Event Player, False); + Set Crouch Enabled(Event Player, False); + Disallow Button(Event Player, Button(Ultimate)); + } +} + +rule("Subroutine: Enable Player") +{ + event + { + Subroutine; + EnablePlayer; + } + + actions + { + Stop Forcing Throttle(Event Player); + Set Primary Fire Enabled(Event Player, True); + Set Secondary Fire Enabled(Event Player, True); + Set Ability 1 Enabled(Event Player, True); + Set Ability 2 Enabled(Event Player, True); + Set Melee Enabled(Event Player, True); + Set Jump Enabled(Event Player, True); + Set Crouch Enabled(Event Player, True); + Allow Button(Event Player, Button(Ultimate)); + } +} + +rule("Buy Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Primary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + Event Player.isInMenu = !Event Player.isInMenu; + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Money[1] != 0); + Call Subroutine(Refund); + Else; + Small Message(Local Player, Custom String("You don't have anything to refund!")); + End; + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[13] += 1; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 2); + If(Event Player.Money[0] >= 900); + Event Player.Money[0] -= 900; + Event Player.Money[1] += 900; + Event Player.Abilities[9] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[5] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[1] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[14] += 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[10] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[6] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[2] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[15] += 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[11] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[7] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[3] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Global.AutoRepair != 5); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Global.AutoRepair += 1; + Event Player.Abilities[16] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[12] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[8] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[4] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + End; + } +} + +rule("Refund Single Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Secondary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[13] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[13] -= 1; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 0); + Event Player.Money[0] += 900; + Event Player.Money[1] -= 900; + Event Player.Abilities[9] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[5] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[1] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[14] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[14] -= 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[10] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[6] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[2] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[15] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[15] -= 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[11] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[7] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[3] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[16] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Global.AutoRepair -= 1; + Event Player.Abilities[16] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[12] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[8] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[4] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + End; + } +} + +rule("Create Player HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Custom String("{0}{1}", + Event Player, Event Player.isInMenu ? Custom String("(In Shop)") : Custom String("")), Custom String("{0}{1}", Is Alive( + Event Player) ? Custom String("{0} HP", Round To Integer(Health(Event Player), Up)) : Custom String("Dead"), Custom String( + ", {0}$", Event Player.Money)), Left, Local Player == Event Player ? -1 : Slot Of(Event Player), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), + Visible To Sort Order String and Color, Default Visibility); + Create HUD Text(Event Player.Abilities[13] || Global.DamageDone ? Event Player : Null, Null, Null, Custom String("+{0}% Damage", + Global.DamageDone + Event Player.Abilities[13] * 5), Left, 913, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[9] ? Event Player : Null, Null, Null, Custom String("Second Wind {0}", + Event Player.Abilities[9] == 1 ? Custom String("I") : Custom String("II")), Left, 908, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[5] ? Event Player : Null, Null, Null, Custom String("Charged {0}", + Event Player.Abilities[5] == 1 ? Custom String("I") : Custom String("II")), Left, 905, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[1] ? Event Player : Null, Null, Null, Custom String("Headhunter {0}", + Event Player.Abilities[1] == 1 ? Custom String("I") : Custom String("II")), Left, 901, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[14] || Global.MaxHealthDone ? Event Player : Null, Null, Null, Custom String("+{0}% Health", + Global.MaxHealthDone + Event Player.Abilities[14] * 5), Left, 914, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[10] ? Event Player : Null, Null, Null, Custom String("Binding Heal {0}", + Event Player.Abilities[10] == 1 ? Custom String("I") : Custom String("II")), Left, 909, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[6] ? Event Player : Null, Null, Null, Custom String("Haste {0}", + Event Player.Abilities[6] == 1 ? Custom String("I") : Custom String("II")), Left, 906, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[2] ? Event Player : Null, Null, Null, Custom String("Ambush {0}", + Event Player.Abilities[2] == 1 ? Custom String("I") : Custom String("II")), Left, 902, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[15] ? Event Player : Null, Null, Null, Custom String("+{0}% Healing", + Event Player.Abilities[15] * 5), Left, 915, Color(White), Color(White), Color(Turquoise), Visible To and String, + Default Visibility); + Create HUD Text(Event Player.Abilities[11] ? Event Player : Null, Null, Null, Custom String("Resilience {0}", + Event Player.Abilities[11] == 1 ? Custom String("I") : Custom String("II")), Left, 910, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[7] ? Event Player : Null, Null, Null, Custom String("Heavy Impact {0}", + Event Player.Abilities[7] == 1 ? Custom String("I") : Custom String("II")), Left, 907, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[3] ? Event Player : Null, Null, Null, Custom String("Quick Fix {0}", + Event Player.Abilities[3] == 1 ? Custom String("I") : Custom String("II")), Left, 903, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Global.AutoRepair ? Event Player : Null, Null, Null, Custom String("{0} total Auto-Repair/5s", + Global.AutoRepair * (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5)), Left, 916, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[2][0], Event Player.HeroTalentText[2][1]), Top, 902, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("Hero Talent 2"), Left, 912, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[1][0], Event Player.HeroTalentText[1][1]), Top, 901, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("Hero Talent 1"), Left, 911, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[4] ? Event Player : Null, Null, Null, Custom String("Heavyweight {0}", + Event Player.Abilities[4] == 1 ? Custom String("I") : Custom String("II")), Left, 904, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + } +} + +rule("Rein Pin detect") +{ + event + { + Player Dealt Knockback; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 1); + Has Status(Victim, Stunned) == True; + } + + actions + { + Event Player.ReinPin = Victim; + Wait(1, Ignore Condition); + Event Player.ReinPin = Null; + } +} + +rule("Boss Rotation") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.activeBoss == True; + } + + actions + { + If(Global.bossRotation == 0 || Global.bossRotation == 3); + Global.bossRotation = 1; + Global.lastBoss[1] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 1); + Global.bossRotation = 2; + Global.lastBoss[2] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 2); + Global.bossRotation = 3; + Global.lastBoss[3] = Hero Of(Global.activeBoss); + End; + } +} + +rule("15 minutes hud") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 10; + } + + actions + { + Create HUD Text(All Players(Team 1), Global.activeBoss ? Custom String("Boss: {0}, HP: {1}/{2}", Hero Of(Global.activeBoss), + Health(Global.activeBoss), Max Health(Global.activeBoss)) : Custom String(""), Null, Null, Top, 900, Color(Red), Color(White), + Color(White), Visible To and String, Default Visibility); + } +} + +rule("debug") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + (Is Button Held(Event Player, Button(Primary Fire)) && Is Button Held(Event Player, Button(Crouch))) == True; + } + + actions + { + Global.TimeSec = 59; + } +} + +disabled rule("debug") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + } + + actions + { + Create HUD Text(Local Player, Custom String("{0}", Position Of(Local Player)), Null, Null, Left, 0, Color(Yellow), Color(White), + Color(White), Visible To and String, Default Visibility); + Set Status(Event Player, Null, Invincible, 9999); + Set Status(Event Player, Null, Phased Out, 9999); + } +} + +rule("ending 1 part 1") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + } + + actions + { + Big Message(All Players(Team 1), Custom String("Exfiltration available! (optional - ends the mode)")); + Create In-World Text(All Players(Team 1), Custom String( + "Exfiltration available! Gather here!\n{0}/{1} Players ready to exfiltrate!", Count Of(Filtered Array(All Players(Team 1), + Distance Between(Vector(186, 11, -46.500), Current Array Element) <= 9)), Count Of(All Players(Team 1))), Vector(186, 15, + -46.500), 1.200, Do Not Clip, Visible To and String, Color(Green), Default Visibility); + } +} + +rule("ending 1 part 2") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + Distance Between(Vector(186, 11, -46.500), All Players(Team 1)) <= 9; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GG! YOU DID IT!")); + Destroy All Dummy Bots; + Disable Movement Collision With Environment(All Players(Team 1), True); + Start Accelerating(All Players(Team 1), Up, 100, 5, To World, Direction Rate and Max Speed); + Wait(5, Ignore Condition); + Declare Team Victory(Team 1); + } +} + +rule("Team 1 (Ability): Second Wind save life") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[9] == True; + Event Player.secondWindActive == True; + Health(Event Player) == 1; + } + + actions + { + Small Message(All Players(All Teams), Custom String("{0} received a second wind!", Event Player)); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Green), Event Player, 1); + Clear Status(Event Player, Unkillable); + Set Player Health(Event Player, Max Health(Event Player)); + Event Player.lastSecondWind = 30; + Event Player.secondWindActive = 0; + } +} + +rule("Team 1 (Ability): Second Wind after buying") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[9] == True; + Event Player.secondWindActive == False; + Event Player.lastSecondWind == 0; + } + + actions + { + If(Random Integer(1, 100) > Event Player.Abilities[9] * 30); + Wait(30, Ignore Condition); + Loop; + End; + Set Status(Event Player, Null, Unkillable, 9999); + Event Player.secondWindActive = 1; + } +} + +rule("Team 1 (Ability): Second Wind counter") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Player.lastSecondWind > 0; + } + + actions + { + Wait(1, Ignore Condition); + Event Player.lastSecondWind -= 1; + Loop If Condition Is True; + } +} + +rule("Team 1: Change Hero") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Distance Between(Vector(153.300, 10, -61.700), All Players(Team 1)) <= 3; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + Set Player Allowed Heroes(Event Player, Hero(Pharah)); + Set Player Allowed Heroes(Event Player, Hero(Ana)); + If(Global.IsStoryHeroes); + Reset Player Hero Availability(Event Player); + Set Player Allowed Heroes(Event Player, Array(Hero(Ana), Hero(Brigitte), Hero(Mercy), Hero(Lúcio), Hero(Moira), Hero(Baptiste), + Hero(Ashe), Hero(D.Va), Hero(Genji), Hero(Hanzo), Hero(Widowmaker), Hero(Cassidy), Hero(Reinhardt), Hero(Soldier: 76), Hero( + Torbjörn), Hero(Tracer), Hero(Winston), Hero(Pharah))); + Else; + Reset Player Hero Availability(Event Player); + End; + } +} \ No newline at end of file diff --git a/defendTheCastleExtended/old_versions/c126.ow b/defendTheCastleExtended/old_versions/c126.ow new file mode 100644 index 0000000..a4ada1d --- /dev/null +++ b/defendTheCastleExtended/old_versions/c126.ow @@ -0,0 +1,9355 @@ +settings +{ + main + { + Description: "Defend The Castle Extended v0.6.c126\nby ShuriZma#2349\nJ1K6F (Code Version: c126)\nOriginal mode by HuKuTa94#2589\n\nDefend the gate, kill enemies and don't allow them to damage the gate!\n\nSpecial Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents\n& Josbird for teaching me about Menus!\n\nFind this mode on: workshop.codes/defend-the-castle\nFind the Original Mode on: workshop.codes/BQEGS\nTell me what you think on Discord: discord.shurizma.de\n\nPS: SHINGEN PLS COME BACK" + Mode Name: "Defend The Castle Extended" + } + + lobby + { + Max Spectators: 0 + Max Team 1 Players: 4 + Max Team 2 Players: 0 + Return To Lobby: Never + Swap Teams After Match: No + } + + modes + { + Escort + { + enabled maps + { + Havana + } + } + + Team Deathmatch + { + enabled maps + { + } + } + + General + { + Game Mode Start: Immediately + Spawn Health Packs: Disabled + } + } + + workshop + { + Ana can nano herself even if there are other players only if no player targeted: On + Story Heroes: Off + } + + extensions + { + Beam Effects + Kinetic Explosion Effects + Explosion Sounds + Play More Effects + Spawn More Dummy Bots + } +} + +variables +{ + global: + 0: GatePosition + 1: ZenSpawnPositions + 2: SpawnPositionMaxId + 3: LoopIterator1 + 4: BigBossSpawnPositions + 5: PlayerSpawnPositions + 6: GateHealthChase + 7: GateHealth + 8: GateMaxHealth + 9: GateProgressBarColorCurrent + 10: GateProgressBarColorComponent + 11: GateHealthEvent + 12: BastionTargetPositions + 13: SniperPositions + 14: BallSpawnPositions + 15: ZenRespawnTime + 16: TimeMin + 17: TimeSec + 18: DefaultCurrentBot + 19: DefaultHeroBotsPool + 20: DefaultHeroBotsPoolCurrentId + 21: IsDebug + 22: BotOrisaParent + 23: IsStoryHeroes + 24: BotOrisaChild + 25: GateRepairPosition + 26: BotOrisaTargetPosition + 27: BotEchoRespawnPosition + 28: BotEchoTeleportPositions + 29: UpgradeGateMaxHealthValue + 30: UpgradeGateMaxHealthHudId + 31: UpgradePlayerMaxHealthValue + 32: UpgradePlayerMaxHealthHudId + 33: UpgradeCriticalDamageValue + 34: UpgradeCriticalDamageHudId + 35: UpgradeMaxAmmoValue + 36: UpgradeMaxAmmoHudId + 37: UpgradeMaxAmmoMaxValue + 38: UpgradePlayerMaxHealthMaxValue + 39: UpgradeCriticalDamageMaxValue + 40: UpgradeGateMaxHealthMaxValue + 41: DamageDone + 42: IsDebugAINavigation + 43: GameLogicCountOfUniqueHeroes + 44: IsNewWaveGameLogicProcessing + 45: AutoRepair + 46: UpgradePerkSharpshooterValue + 47: Perk + 48: MaxHealthDone + 49: StartMoney + 50: Time5Min + 51: SelfNanoWorkshopSetting + 52: ShopCamPos + 53: ShopBasePos + 54: ShopPosAngle + 55: activeBoss + 56: bossTrigger + 57: bossRotation + 58: lastBoss + 59: Time10Min + 60: MoneyMult + 61: challengeCount + 62: UpgradeBossHealthValue + 63: GlobalHuds + 112: AllPos + 113: AllDir + 114: firstpos + 115: secondpos + 116: firstpoint2 + 117: secondpoint2 + 118: second + 119: z + 120: Wall_ID + 121: showwalls + 122: is_Grounded + 123: g_beamType + 124: x + 125: NodePositions + 126: NodeConnections + 127: DistanceMatrix + + player: + 0: BotSeePlayer + 1: BotDoesUniqueBehaviour + 2: BotEffects + 3: BotRayCastHitPosition + 4: BotEventPosition + 5: CurrentHero + 6: IsDead + 7: IsRespawning + 8: BotBastionArtilleryDidShotsCount + 9: BotCounter + 10: HasBadStatus + 11: EventHealth + 12: HealOverTimeId + 13: BotIsOrisaChild + 14: BotEchoCapturedPlayer + 15: BotPlayersInRadius + 16: BotLoopIterator2 + 17: BotWidowShotTime + 18: BotWidowTeleportTime + 19: IsNanoed + 20: AbilityHUD + 21: Lucio_Dash_Active + 22: Lucio_Dash_Icon + 23: AnaEntityID + 24: Abilities + 25: Money + 26: HeroTalentText + 27: DamageDealt + 28: PlayerHealth + 29: AbilityCountdown + 30: HP_Pool + 31: Effects_ + 32: Ability_Projectile1 + 33: Ability_End + 34: Storm_Projectile + 35: Storm_EndPoint + 36: Storm_Effects + 37: Feared_until + 38: Modification_Damage + 39: Ability_Projectile2 + 40: Ability_Position + 41: Chain_Reaction_On + 42: Chain_Reaction_Immune + 43: Ability_Active + 44: Ability_Resource + 45: secondWindActive + 46: isInMenu + 47: ReinPin + 48: PlayerFacing + 49: isBoss + 50: Gen_Direction + 51: Gen_Available + 52: Ability_Player + 53: Ability_Countdown + 54: lastSecondWind + 55: deathPosition + 105: filterpos + 106: lastsavedpos + 107: closestbodypos + 108: fullbodypos + 109: prevpos_intersection + 110: active_wall + 111: closestwall + 112: x + 113: intersection_length + 114: thickness + 115: BotCancelPathFinding + 116: BotLoopIterator1 + 117: BotTempArray + 118: BotTargetPlayer + 119: BotTargetPosition + 120: BotClosestNodeIdToTarget + 121: BotClosestNodeIdToBot + 122: BotPrevNodeId + 123: BotNextNodeId + 124: BotNextNodePosition + 125: BotCurrentDistanceToTarget + 126: BotShortestDistanceToTarget + 127: BotIsPathFinding +} + +subroutines +{ + 0: BotBastionArtilleryDamage + 1: BotBastionFlameGunDamage + 2: BotBastionRespawn + 3: GateProgressBarColor + 4: BotZenyattaRespawn + 5: BotWidowRespawn + 6: BotBallRespawn + 7: GameLogicAddNextHeroInGame + 8: BotOrisaRespawn + 9: BotLandingFromSky + 10: BotEchoRespawn + 11: BotEchoDetachPlayer + 12: BotEchoFlyToPlayer + 13: BotEchoFlyToPortal + 14: GameLogicSetBotProperties + 15: DisablePlayer + 16: BotApearFromUnderground + 17: BotReinRespawn + 18: PlayerInit + 19: BotInit + 20: PlayerRespawn + 21: BotRespawn + 22: BotWidowBadStatus + 23: GameLogicWave0 + 24: Refund + 25: EnablePlayer + 26: GateRepair + 124: BotStartPathFinding + 125: BotGetClosestNodeIdToTarget + 126: BotGetNextNodeIdAndPosition + 127: BotResetPathFinding +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("MAP: HAVANA") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Havana); + } + + actions + { + Global.NodePositions = Array(Vector(147.588, 6.425, -46.749), Vector(136.181, 6.425, -57.159), Vector(130.189, 6.425, -63.781), + Vector(123.305, 6.425, -57.983), Vector(125.678, 6.504, -46.633), Vector(114.485, 7.471, -46.699), Vector(138.743, 6.425, + -32.974), Vector(126.498, 6.425, -39.920), Vector(124.572, 10.434, -34.300), Vector(138.605, 5.359, -18.647), Vector(119.009, + 2.331, -31.024), Vector(121.138, 5.228, -19.933), Vector(126.722, 6.425, -29.505), Vector(102.762, 3.157, -33.609), Vector( + 76.030, 7.418, -74.087), Vector(83.720, 9.425, -33.744), Vector(97.439, 7.238, -42.379), Vector(86.252, 12.416, -47.261), + Vector(65.178, 11.425, -73.187), Vector(97.466, 7.269, -50.596), Vector(113.039, 7.424, -37.337), Vector(106.179, 7.450, + -46.143), Vector(90.086, 7.411, -44.653), Vector(78.752, 7.418, -62.140), Vector(82.124, 7.428, -44.229), Vector(90.675, 7.231, + -51.234), Vector(85.717, 4.692, -63.446), Vector(90.830, 4.330, -70.697), Vector(102.425, 2.387, -72.817), Vector(81.443, + 4.425, -81.648), Vector(70.743, 6.418, -81.495), Vector(69.738, 6.419, -96.344), Vector(127.586, 12.643, -63.344), Vector( + 118.911, 13.468, -58.008), Vector(102.885, 1.092, -56.579), Vector(100.009, 2.967, -67.139), Vector(106.703, 0.465, -44.628), + Vector(81.695, 7.418, -52.140), Vector(126.979, 12.393, -55.079), Vector(153.720, 18.578, -21.745), Vector(155.301, 18.619, + -17.595), Vector(133.043, 10.425, -26.625), Vector(114.646, 7.278, -57.336), Vector(95.160, 3.688, -81.194), Vector(78.456, + 5.418, -93.581), Vector(75.455, 5.418, -101.492), Vector(148.071, 9.432, -32.123), Vector(146.706, 9.425, -27.858), Vector( + 144.273, 9.445, -63.119), Vector(144.278, 9.454, -58.447)); + Global.NodeConnections = Array(Array(1, 6, 4, 7), Array(2, 1, 4, 6, 7, 0, 49), Array(1, 3), Array(2, 4, 42), Array(3, 1, 5, 7, 6, + 1, 0), Array(4, 7, 20, 21, 19, 16, 42), Array(7, 1, 4, 1, 9, 12, 0, 46), Array(4, 5, 6, 1, 1, 12, 0), Array(7, 41), Array(6, + 11), Array(11, 13), Array(9, 10, 13), Array(6, 7, 10), Array(10, 16, 36), Array(18, 23, 30), Array(17, 24), Array(13, 19, 22, + 21, 25, 5), Array(15, 22, 25, 23), Array(14), Array(16, 21, 22, 26, 27, 35, 25, 5), Array(5, 13, 10), Array(19, 16, 5, 13, 22, + 34), Array(16, 19, 21, 24, 25), Array(14, 25, 26, 37), Array(22, 15, 37), Array(23, 22, 19, 16, 26, 27, 35, 37), Array(25, 19, + 27, 35, 29), Array(19, 26, 25, 29, 35, 43), Array(35, 34, 43), Array(27, 26, 30, 43, 44), Array(29, 14, 31), Array(30, 29, 45), + Array(33, 38, 1, 48), Array(32, 38, 42), Array(35, 36, 28), Array(28, 19, 25, 27, 26, 34), Array(13, 34), Array(25, 23, 24), + Array(5, 4, 1, 6, 1, 32, 33, 0), Array(40), Array(39), Array(6, 8, 47, 46), Array(3, 5, 34), Array(28, 27, 29, 44), Array(29, + 43, 45), Array(44, 31), Array(6, 47), Array(46, 41), Array(49, 32), Array(1, 0, 6, 48)); + Global.DistanceMatrix = Array(Array(0, 1, 2, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, + 4, 5, 4, 4, 5, 5, 5, 0, 0, 4, 3, 5, 6, 7, 2, 3, 3, 2), Array(1, 0, 1, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, + 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 3, 4, 4, 4, 5, 5, 4, 0, 0, 4, 3, 5, 6, 7, 2, 3, 2, 1), Array(2, 1, 0, 1, 2, 3, 2, 2, 6, 3, 4, 4, + 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 4, 6, 7, 8, 4, 5, 3, 4, 4, 6, 5, 0, 0, 5, 2, 5, 6, 7, 3, 4, 3, 2), Array(2, 2, + 1, 0, 1, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, 5, 6, 2, 3, 3, 5, 6, 0, 0, 5, 1, 4, + 5, 6, 3, 4, 4, 3), Array(1, 1, 2, 1, 0, 1, 1, 1, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, + 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, 2, 3, 3, 2), Array(2, 2, 3, 2, 1, 0, 2, 1, 6, 3, 2, 3, 2, 2, 4, 4, 1, 5, 5, 1, 1, 1, 2, 3, + 3, 2, 2, 2, 3, 3, 4, 5, 5, 6, 2, 2, 3, 3, 6, 0, 0, 5, 1, 3, 4, 5, 3, 4, 4, 3), Array(1, 1, 2, 2, 1, 2, 0, 1, 4, 1, 2, 2, 1, 3, + 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 4, 5, 4, 4, 4, 5, 5, 0, 0, 3, 3, 5, 6, 7, 1, 2, 3, 2), Array(1, 1, 2, 2, + 1, 1, 1, 0, 5, 2, 2, 3, 1, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, + 2, 3, 3, 2), Array(2, 2, 3, 3, 2, 2, 2, 1, 0, 3, 3, 4, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, + 5, 5, 6, 0, 0, 1, 3, 5, 6, 7, 2, 2, 4, 3), Array(2, 2, 3, 3, 2, 3, 1, 2, 5, 0, 2, 1, 2, 2, 6, 6, 3, 7, 7, 4, 4, 4, 4, 5, 5, 4, + 5, 5, 5, 6, 7, 8, 5, 6, 4, 5, 3, 5, 6, 0, 0, 4, 4, 6, 7, 8, 2, 3, 4, 3), Array(4, 4, 5, 5, 4, 3, 3, 4, 7, 2, 0, 1, 4, 1, 5, 5, + 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 7, 8, 3, 4, 2, 4, 8, 0, 0, 6, 4, 5, 6, 7, 4, 5, 6, 5), Array(3, 3, 4, 4, 3, 3, + 2, 3, 6, 1, 1, 0, 3, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 6, 7, 3, 4, 2, 4, 7, 0, 0, 5, 4, 5, 6, 7, 3, 4, + 5, 4), Array(2, 2, 3, 3, 2, 2, 1, 1, 5, 2, 1, 2, 0, 2, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, 3, 5, + 6, 0, 0, 4, 3, 5, 6, 7, 2, 3, 4, 3), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 3, 1, 2, 4, 0, 4, 4, 1, 5, 5, 2, 3, 2, 2, 3, 3, 2, 3, 3, + 3, 4, 5, 6, 7, 8, 2, 3, 1, 3, 8, 0, 0, 7, 3, 4, 5, 6, 5, 6, 6, 5), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 5, 6, 6, 4, 0, 4, 3, 5, + 1, 3, 5, 4, 3, 1, 3, 2, 2, 3, 4, 2, 1, 2, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 3, 3, 3, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, + 5, 10, 7, 5, 6, 6, 4, 3, 0, 3, 1, 4, 3, 5, 3, 2, 2, 1, 2, 3, 3, 4, 4, 4, 5, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 4, 5, 6, 7, 8, + 8, 7), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 3, 3, 0, 4, 4, 1, 2, 1, 1, 2, 2, 1, 2, 2, 3, 3, 4, 5, 6, 7, 2, 2, 2, 2, + 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 1, 2, 0, 3, 2, 4, 2, 1, 1, 2, 1, 2, 2, + 3, 3, 3, 4, 8, 9, 3, 2, 4, 2, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 6, 7, 7, 5, 1, 5, 4, 6, + 0, 4, 6, 5, 4, 2, 4, 3, 3, 4, 5, 3, 2, 3, 10, 11, 5, 4, 6, 3, 11, 0, 0, 10, 6, 4, 4, 4, 8, 9, 9, 8), Array(3, 3, 4, 3, 2, 1, 3, + 2, 7, 4, 3, 4, 3, 2, 3, 3, 1, 4, 4, 0, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 3, 4, 6, 7, 2, 1, 3, 2, 7, 0, 0, 6, 2, 2, 3, 4, 4, 5, 5, + 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 3, 1, 2, 3, 1, 5, 5, 2, 6, 6, 2, 0, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 6, 7, 3, 3, 2, 4, 7, + 0, 0, 6, 2, 4, 5, 6, 4, 5, 5, 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 4, 3, 1, 4, 5, 1, 2, 0, 1, 3, 2, 2, 2, 2, 2, + 3, 4, 5, 6, 7, 1, 2, 2, 3, 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 3, 2, 1, 3, 4, + 1, 3, 1, 0, 2, 1, 1, 2, 2, 3, 3, 4, 5, 7, 8, 2, 2, 3, 2, 8, 0, 0, 7, 3, 3, 4, 5, 5, 6, 6, 5), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, + 6, 4, 5, 5, 3, 1, 3, 2, 4, 2, 2, 4, 3, 2, 0, 2, 1, 1, 2, 3, 2, 2, 3, 8, 9, 3, 2, 4, 1, 9, 0, 0, 8, 4, 3, 3, 4, 6, 7, 7, 6), + Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 3, 1, 2, 2, 4, 2, 4, 2, 1, 2, 0, 2, 3, 3, 4, 4, 4, 5, 8, 9, 3, 3, 4, 1, 9, 0, + 0, 8, 4, 4, 5, 6, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 2, 3, 1, 4, 3, 1, 3, 2, 1, 1, 2, 0, 1, 1, 2, 2, + 3, 4, 7, 8, 2, 1, 3, 1, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, + 3, 2, 2, 2, 3, 1, 0, 1, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 2, 2, 3, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, + 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 0, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 1, 2, 3, 5, 6, 6, 5), Array( + 5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 4, 5, 3, 6, 5, 2, 4, 3, 3, 3, 4, 2, 2, 2, 0, 2, 3, 4, 8, 9, 1, 1, 2, 3, 9, 0, 0, 8, + 4, 1, 2, 3, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 2, 5, 3, 6, 3, 2, 4, 3, 3, 3, 4, 2, 1, 1, 2, 0, 1, 2, + 8, 9, 3, 2, 4, 3, 9, 0, 0, 8, 4, 1, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 1, 5, 4, 6, 2, 3, 5, 4, + 4, 2, 4, 3, 2, 2, 3, 1, 0, 1, 9, 10, 4, 3, 5, 3, 10, 0, 0, 9, 5, 2, 2, 2, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, + 7, 6, 5, 2, 6, 4, 7, 3, 3, 5, 4, 4, 3, 5, 3, 2, 2, 3, 1, 1, 0, 9, 10, 4, 3, 5, 4, 10, 0, 0, 9, 5, 2, 2, 1, 7, 8, 8, 7), Array( + 2, 1, 2, 3, 2, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 4, 5, 6, 7, 0, 1, 3, 4, 4, 5, 1, 0, 0, 5, + 2, 5, 6, 7, 3, 4, 1, 2), Array(2, 2, 3, 2, 2, 2, 2, 3, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, + 1, 0, 2, 3, 3, 5, 1, 0, 0, 5, 1, 4, 5, 6, 3, 4, 2, 3), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 5, 3, 4, 5, 2, 4, 5, 3, 6, 5, 2, 4, 3, + 3, 3, 4, 2, 2, 2, 1, 3, 4, 5, 8, 9, 0, 1, 1, 3, 9, 0, 0, 8, 4, 2, 3, 4, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, + 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 1, 1, 2, 3, 4, 7, 8, 1, 0, 2, 2, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(5, 5, + 6, 5, 4, 3, 5, 4, 9, 4, 2, 3, 5, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 8, 9, 1, 2, 0, 4, 9, 0, 0, 8, 4, 3, + 4, 5, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 2, 2, 3, 3, 2, 4, 3, 2, 1, 1, 1, 2, 2, 3, 3, 3, 4, 8, 9, + 3, 2, 4, 0, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(1, 1, 2, 2, 1, 1, 1, 2, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, + 4, 3, 3, 3, 4, 4, 5, 6, 1, 1, 3, 3, 4, 4, 0, 0, 0, 4, 2, 4, 5, 6, 2, 3, 2, 2), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(2, 2, 3, 3, 2, 3, 1, 2, 1, 2, 3, 3, 2, + 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 0, 4, 6, 7, 8, 1, 1, 4, 3), Array(3, 3, 2, + 1, 2, 1, 3, 2, 7, 4, 3, 4, 3, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 6, 7, 1, 2, 2, 4, 7, 0, 0, 6, 0, 3, 4, + 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 3, 5, 3, 6, 4, 2, 4, 3, 3, 3, 4, 2, 2, 1, 1, 1, 2, 3, 8, 9, 2, + 2, 3, 3, 9, 0, 0, 8, 4, 0, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 3, 6, 4, 7, 4, 3, 5, 4, 4, 4, 5, + 3, 2, 2, 2, 1, 2, 2, 9, 10, 3, 3, 4, 4, 10, 0, 0, 9, 5, 1, 0, 1, 7, 8, 8, 7), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 7, 8, 7, 6, + 3, 7, 5, 8, 4, 4, 6, 5, 5, 4, 6, 4, 3, 3, 3, 2, 2, 1, 10, 11, 4, 4, 5, 5, 11, 0, 0, 10, 6, 2, 1, 0, 8, 9, 9, 8), Array(2, 2, 3, + 3, 2, 3, 1, 2, 3, 2, 3, 3, 2, 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 2, 4, 6, 7, + 8, 0, 1, 4, 3), Array(3, 3, 4, 4, 3, 4, 2, 3, 2, 3, 4, 4, 3, 5, 8, 8, 5, 9, 9, 5, 5, 5, 6, 7, 7, 6, 6, 6, 7, 7, 8, 9, 6, 7, 6, + 6, 6, 7, 7, 0, 0, 1, 5, 7, 8, 9, 1, 0, 5, 4), Array(2, 2, 3, 4, 3, 3, 2, 3, 6, 3, 4, 4, 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, + 5, 5, 5, 5, 6, 7, 8, 1, 2, 4, 5, 5, 6, 2, 0, 0, 5, 3, 6, 7, 8, 3, 4, 0, 1), Array(1, 1, 2, 3, 2, 3, 1, 2, 5, 2, 3, 3, 2, 4, 7, + 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 2, 3, 5, 5, 5, 6, 3, 0, 0, 4, 4, 6, 7, 8, 2, 3, 1)); + } +} + +rule("SUBROUTINE: BOT - RESET PATH FINDING") +{ + event + { + Subroutine; + BotResetPathFinding; + } + + actions + { + Event Player.BotTargetPlayer = -1; + Event Player.BotTargetPosition = -1; + Event Player.BotPrevNodeId = -1; + Event Player.BotClosestNodeIdToTarget = -1; + Event Player.BotNextNodeId = -1; + Event Player.BotNextNodePosition = -1; + Event Player.BotIsPathFinding = False; + Event Player.BotCancelPathFinding = False; + Stop Throttle In Direction(Event Player); + disabled Stop Facing(Event Player); + } +} + +rule("SUBROUTINE: BOT - START PATH FINDING") +{ + event + { + Subroutine; + BotStartPathFinding; + } + + actions + { + disabled Abort If(Event Player.BotIsPathFinding == True); + Call Subroutine(BotGetNextNodeIdAndPosition); + disabled Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Event Player.BotIsPathFinding = True; + } +} + +rule("SUBROUTINE: BOT - GET NEXT NODE ID AND POSITION") +{ + event + { + Subroutine; + BotGetNextNodeIdAndPosition; + } + + actions + { + "BOT JUST START FOLLOW PATH OR LOST NEXT NODE" + If(Event Player.BotPrevNodeId == -1); + Event Player.BotClosestNodeIdToBot = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array(Global.NodePositions, + Is In Line of Sight(Position Of(Event Player) + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS) == True), + Distance Between(Position Of(Event Player), Current Array Element))[0]); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + "NEXT NODE IS TARGET (DISTANCE TO TARGET NODE = 1)" + If(Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1); + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToTarget; + "CHECK CONNECTIONS OF REACHED NODE" + Else; + Event Player.BotShortestDistanceToTarget = 999; + Event Player.BotCurrentDistanceToTarget = Event Player.BotShortestDistanceToTarget; + Event Player.BotTempArray = Global.NodeConnections[Event Player.BotClosestNodeIdToBot]; + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotTempArray), 1); + Event Player.BotCurrentDistanceToTarget = Global.DistanceMatrix[Event Player.BotTempArray[Event Player.BotLoopIterator1]][Event Player.BotClosestNodeIdToTarget]; + If(Event Player.BotCurrentDistanceToTarget < Event Player.BotShortestDistanceToTarget); + Event Player.BotShortestDistanceToTarget = Event Player.BotCurrentDistanceToTarget; + Event Player.BotNextNodeId = Event Player.BotTempArray[Event Player.BotLoopIterator1]; + End; + End; + End; + "NEXT NODE IS HIGHER THAN BOT AND BOT DIDN'T REACH CLOSEST NODE" + If(Y Component Of(Position Of(Event Player)) - Y Component Of(Global.NodePositions[Event Player.BotNextNodeId]) + < -3 && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + "BOT CAN SEE TARGET POSITION AND NEXT NODE IS TARGET" + Else If( + Global.DistanceMatrix[Event Player.BotClosestNodeIdToBot][Event Player.BotClosestNodeIdToTarget] == 1 && Is In Line of Sight( + Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotTargetPosition + Vector(0, 2, 0), Barriers Do Not Block LOS)); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Abort; + "BOT CAN'T SEE NEXT NODE AND PREV NODE != REACHED NODE" + Else If(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), + Global.NodePositions[Event Player.BotNextNodeId] + Vector(0, 2, 0), Barriers Do Not Block LOS) + == False && Event Player.BotPrevNodeId != Event Player.BotClosestNodeIdToBot); + Event Player.BotPrevNodeId = Event Player.BotClosestNodeIdToBot; + Event Player.BotNextNodeId = Event Player.BotClosestNodeIdToBot; + End; + Event Player.BotNextNodePosition = Global.NodePositions[Event Player.BotNextNodeId]; + } +} + +rule("SUBROUTINE: BOT - GET CLOSEST NODE ID AND POSITION TO TARGET") +{ + event + { + Subroutine; + BotGetClosestNodeIdToTarget; + } + + actions + { + Event Player.BotTargetPosition = Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Event Player.BotTargetPosition; + Event Player.BotClosestNodeIdToTarget = Index Of Array Value(Global.NodePositions, Sorted Array(Filtered Array( + Global.NodePositions, Is In Line of Sight(Event Player.BotTargetPosition + Vector(0, 2, 0), Current Array Element, + Barriers Do Not Block LOS) == True), Distance Between(Event Player.BotTargetPosition, Current Array Element))[0]); + } +} + +rule("BOT: PATH FINDING - START") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + (Event Player.BotTargetPosition != -1 || Event Player.BotTargetPlayer != -1) == True; + } + + actions + { + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - CANCEL") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotCancelPathFinding == True; + } + + actions + { + Start Rule(BotResetPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - LOST THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + (Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.BotNextNodePosition + Vector(0, 2.500, 0), + Barriers Do Not Block LOS) == False && Speed Of In Direction(Event Player, Throttle Of(Event Player)) < 2) == True; + } + + actions + { + Wait(0.500, Abort When False); + "RESET PREV NODE ID TO INFORM BOT THAT IT LOST NEXT NODE" + Event Player.BotPrevNodeId = -1; + "TRY FIND NEW NEXT NODE" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodeId), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +rule("BOT: PATH FINDING - REACHED THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.BotIsPathFinding == True; + Event Player.BotClosestNodeIdToTarget >= 0; + (Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotNextNodePosition), 0, Z Component Of(Event Player.BotNextNodePosition))) < 0.850) == True; + } + + actions + { + Event Player.BotPrevNodeId = Event Player.BotNextNodeId; + Event Player.BotClosestNodeIdToBot = Event Player.BotNextNodeId; + "BOT'S TARGET IS PLAYER" + If(Event Player.BotTargetPlayer != -1); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + Event Player.BotCurrentDistanceToTarget = Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of( + Position Of(Event Player))), Vector(X Component Of(Event Player.BotTargetPosition), 0, Z Component Of( + Event Player.BotTargetPosition))); + "BOT REACHED THE TARGET NODE OR TARGET POSITION" + If(Event Player.BotNextNodeId == Event Player.BotClosestNodeIdToTarget || Event Player.BotCurrentDistanceToTarget <= 0.850); + "BOT DIDN'T REACH TARGET POSITION" + If(Event Player.BotCurrentDistanceToTarget > 0.850); + Event Player.BotNextNodePosition = Event Player.BotTargetPosition; + Skip(6); + "BOT REACHED TARGET" + Else; + Call Subroutine(BotResetPathFinding); + Abort; + End; + End; + "CONTINUE FOLLOW PATH" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: GAME MODE INIT - WORKSHOP SETTINGS") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.IsDebug = False; + Global.IsDebugAINavigation = False; + Global.GateMaxHealth = Workshop Setting Integer(Custom String("Defend The Castle Extended"), Custom String("GATE MAX HEALTH"), 500, 100, 1000, + 0); + Global.MoneyMult = Workshop Setting Real(Custom String("Defend The Castle Extended"), Custom String("Money Multiplicator"), 1, 0.500, 2, 0); + Global.IsStoryHeroes = Workshop Setting Toggle(Custom String("Defend The Castle Extended"), Custom String("Story Heroes"), True, 0); + Global.SelfNanoWorkshopSetting = Workshop Setting Toggle(Custom String("Ana Self Nano"), Custom String( + "Ana can nano herself even if there are other players (only if no player targeted)"), False, 0); + } +} + +rule("GLOBAL: GAME MODE INIT - COMMON PROPERTIES") +{ + event + { + Ongoing - Global; + } + + actions + { + Create HUD Text(All Players(All Teams), Null, Null, Custom String( + "Defend The Castle Extended v0.6.c126 BY ShuriZma#2349\r\nOriginal mode by HUKUTA94#2589\r\nDiscord: discord.shurizma.de\r\n{0}", Custom String( + "Special Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents &\nJosbird for teaching me about Menus{0}", + Custom String(" \nPS: SHINGEN PLS COME BACK"))), Right, -1000, Null, Null, Color(White), Visible To, + Default Visibility); + Global.GateRepairPosition = Vector(153, 8, -46.500); + Global.GatePosition = Vector(148.800, 6, -46.400); + Global.BallSpawnPositions = Array(Vector(104, 7, -46), Vector(106, 2, -31)); + Global.SniperPositions = Array(Vector(154, 18, -22.600), Vector(86, 12, -46.600), Vector(80.880, 11.300, -71.600), Vector(98, 9, + -19)); + Global.ZenSpawnPositions = Array(Vector(79.500, 5, -100), Vector(90, 4, -88), Vector(65, 11, -70), Vector(85, 4, -68), Vector(96, + 2, -73), Vector(84, 7, -47), Vector(95, 9, -34), Vector(108, 1.700, -28), Vector(113, 7, -37), Vector(123, 5, -19), Vector(144, + 5, -19), Vector(123, 6, -39), Vector(123, 6, -61), Vector(129, 6, -30.500), Vector(135, 6, -63)); + Global.PlayerSpawnPositions = Array(Vector(153.300, 10, -63.800), Vector(153.300, 10, -61.700), Vector(153.300, 10, -31.700), + Vector(153.300, 10, -29.600)); + Global.BigBossSpawnPositions = Array(Vector(78, 4, -84), Vector(95, 4, -82)); + Global.BastionTargetPositions = Array(Vector(131, 12, -62), Vector(115, 7, -46), Objective Position(2), Vector(136, 10, -27)); + Global.SpawnPositionMaxId = 2; + Global.BotOrisaTargetPosition = Vector(104, 7, -46); + Global.BotEchoRespawnPosition = Vector(130, 23, -44); + Global.BotEchoTeleportPositions = Array(Vector(88, 23, -79), Vector(108, 18, -27)); + Global.DefaultHeroBotsPool = Array(Hero(Zenyatta), Hero(Widowmaker), Null, Hero(Bastion), Hero(Echo), Hero(Bastion)); + Global.ZenRespawnTime = 10; + Global.GameLogicCountOfUniqueHeroes = 5; + Global.lastBoss = Array(Null, Null, Null, Null); + Create Effect(All Players(Team 1), Ring, Color(Sky Blue), Vector(186, 11, -46.500), 9, Visible To Position and Radius); + Create Effect(All Players(Team 1), Ring, Color(Yellow), Vector(149.000, 10, -62.000), 2, Visible To Position and Radius); + } +} + +disabled rule("PLAYER: DEBUG - PRESS INTERACT") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Host Player == True; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + disabled Modify Player Score(Event Player, 10); + disabled Global.GateHealth -= 5; + disabled Start Rule(GateProgressBarColor, Restart Rule); + Global.TimeSec = 59; + Set Status(Event Player, Null, Phased Out, 9999); + disabled Set Ultimate Charge(Event Player, 100); + disabled Kill(Event Player, Null); + disabled Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: DEBUG - AI NAVIGATION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.IsDebugAINavigation == True; + } + + actions + { + For Global Variable(LoopIterator1, 0, Count Of(Global.NodePositions), 1); + Create Effect(All Players(All Teams), Sphere, Color(Red), Global.NodePositions[Global.LoopIterator1], 0.850, Visible To); + Create In-World Text(All Players(All Teams), Custom String("NODE {0}", Global.LoopIterator1), + Global.NodePositions[Global.LoopIterator1], 1.200, Clip Against Surfaces, Visible To, Color(White), Default Visibility); + End; + } +} + +disabled rule("GLOBAL: DEBUG - CREATE BOTS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + Create Dummy Bot(Hero(Bastion), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + Create Dummy Bot(Hero(Orisa), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +disabled rule("PLAYER: DEBUG - INFOS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + Host Player == Event Player; + Has Spawned(Event Player) == True; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Create HUD Text(Event Player, Custom String("POS {0}\r\nFACING {1}", Position Of(Event Player), Facing Direction Of(Event Player)), + Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + Create HUD Text(Event Player, Custom String("SERVER PERFORMANCE\r\nLOAD {0}%\r\nPEAK {1}%\r\nAVG {2}%", Server Load, + Server Load Peak, Server Load Average), Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create Progress Bar HUD Text(Event Player, 45, Custom String("45 / 100 KILLS"), Left, -99, Color(Blue), Color(White), + Visible To Values and Color, Default Visibility); + disabled Create HUD Text(Event Player, Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Null, Custom String( + "LEVEL 1 - 50 AMMO CLIP"), Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + "ЭФФЕКТ С ОФФСЕТОМ ОТ ПОЗИЦИИ ГЛАЗ" + disabled Create Beam Effect(All Players(All Teams), Bad Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + Facing Direction Of( + Event Player) * 3, Eye Position(Event Player) + Facing Direction Of(Event Player) * 50, Color(Purple), + Visible To Position and Radius); + } +} + +disabled rule("=== TEAM UPGRADES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: TEAM UPGRADES - INIT") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.UpgradeMaxAmmoMaxValue[0] = 250; + Global.UpgradeMaxAmmoMaxValue[1] = 500; + Global.UpgradeMaxAmmoMaxValue[2] = 1000; + Global.UpgradeCriticalDamageMaxValue[0] = 10; + Global.UpgradeCriticalDamageMaxValue[1] = 5; + Global.UpgradeCriticalDamageMaxValue[2] = 5; + Global.UpgradePlayerMaxHealthMaxValue[0] = 2500; + Global.UpgradePlayerMaxHealthMaxValue[1] = 5000; + Global.UpgradePlayerMaxHealthMaxValue[2] = 10000; + Global.UpgradeGateMaxHealthMaxValue[0] = Round To Integer(Global.GateMaxHealth + Global.GateMaxHealth * 0.500, Up); + Global.UpgradeGateMaxHealthMaxValue[1] = Global.UpgradeGateMaxHealthMaxValue[0] + Global.UpgradeGateMaxHealthMaxValue[0]; + Global.UpgradeGateMaxHealthMaxValue[2] = Global.UpgradeGateMaxHealthMaxValue[1] + Global.UpgradeGateMaxHealthMaxValue[1]; + Abort If(Global.IsDebug == False); + Global.UpgradeMaxAmmoMaxValue[0] = 1; + Global.UpgradeCriticalDamageMaxValue[0] = 1; + Global.UpgradePlayerMaxHealthMaxValue[0] = 1; + Global.UpgradeGateMaxHealthMaxValue[0] = 1; + Global.UpgradeMaxAmmoMaxValue[1] = 1; + Global.UpgradeCriticalDamageMaxValue[1] = 1; + Global.UpgradePlayerMaxHealthMaxValue[1] = 1; + Global.UpgradeGateMaxHealthMaxValue[1] = 1; + Global.UpgradeMaxAmmoMaxValue[2] = 1; + Global.UpgradeCriticalDamageMaxValue[2] = 1; + Global.UpgradePlayerMaxHealthMaxValue[2] = 1; + Global.UpgradeGateMaxHealthMaxValue[2] = 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GATE'S MAX HEALTH UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Global.GateMaxHealth = Global.UpgradeGateMaxHealthMaxValue[0]; + Global.GateHealth = Global.GateMaxHealth; + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Right, 1, Color( + Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X GATE REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[1]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X GATE REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X GATE REPAIR"), Right, 2, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.UpgradeGateMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X AUTO-REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[2]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[2] = Last Text ID; + Global.GateHealth = Global.GateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 3 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X AUTO-REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.GatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.GatePosition, 100); + Destroy HUD Text(Global.UpgradeGateMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X AUTO-REPAIR"), Right, 3, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.UpgradeGateMaxHealthHudId[2] = Last Text ID; + Global.GateHealth = Global.GateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - PLAYER'S MAX HEALTH - DEALT HEALING") +{ + event + { + Player Received Healing; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + disabled Healer != Event Player; + Global.UpgradePlayerMaxHealthValue < Global.UpgradePlayerMaxHealthMaxValue[2]; + } + + actions + { + Global.UpgradePlayerMaxHealthValue += Event Healing; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +50%"), Right, 4, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("Up You Go: You respawn twice as fast"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[1]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.MaxHealthDone = 50; + All Players(Team 1).PlayerHealth = 100 + Global.MaxHealthDone + All Players(Team 1).Abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).PlayerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK UP YOU GO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("UP YOU GO UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String("Up You Go"), + Right, 5, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +100%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[2]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[2] = Last Text ID; + Set Respawn Max Time(All Players(Team 1), 5); + Heal(All Players(Team 1), Null, 9999); + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.Perk[2] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[17] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH 2 UNLOCKED!")); + Destroy HUD Text(Global.UpgradePlayerMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +100%"), Right, 6, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradePlayerMaxHealthHudId[2] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.LoopIterator1]), 100); + End; + Global.MaxHealthDone = 150; + All Players(Team 1).PlayerHealth = 100 + Global.MaxHealthDone + All Players(Team 1).Abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).PlayerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Hero Of(Victim) == Hero(Widowmaker); + Global.UpgradeCriticalDamageValue < Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradeCriticalDamageValue += 1; + Small Message(All Players(Team 1), Custom String("CRITICAL DAMAGE CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - CRITICAL DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("CRITICAL DAMAGE 150% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "CRITICAL DAMAGE 150%"), Right, 7, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String( + "Sharpshooter: Deal 40% more damage to enemies that are further than 15 meters away"), Custom String("KILL ECHO {0}/{1}", + Global.UpgradePerkSharpshooterValue, Global.UpgradeCriticalDamageMaxValue[1]), Left, 14, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - UNLOCKED") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.500); + } +} + +rule("PLAYER: UPGRADE - PERK SHARPSHOOTER - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Echo); + Global.UpgradePerkSharpshooterValue < Global.UpgradeCriticalDamageMaxValue[1]; + Global.UpgradeCriticalDamageValue >= Global.UpgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.UpgradePerkSharpshooterValue += 1; + Small Message(All Players(Team 1), Custom String("SHARPSHOOTER CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - PERK SHARPSHOOTER - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("SHARPSHOOTER UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Sharpshooter"), Right, 8, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("-10% BOSS HEALTH"), Custom String("KILL Bosses {0}/{1}", + Global.UpgradeBossHealthValue, Global.UpgradeCriticalDamageMaxValue[2]), Left, 14, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[2] = Last Text ID; + Global.Perk[0] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[18] = Last Text ID; + Global.challengeCount += 1; + } +} + +disabled rule("PLAYER: UPGRADE - -10% BOSS HEALTH - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]; + Global.UpgradeBossHealthValue < Global.UpgradeCriticalDamageMaxValue[2]; + Victim.isBoss == 1; + } + + actions + { + Global.UpgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - -10% BOSS HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("-10% BOSS HEALTH UNLOCKED!")); + Destroy HUD Text(Global.UpgradeCriticalDamageHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "-10% BOSS HEALTH"), Right, 9, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeCriticalDamageHudId[2] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - MAX AMMO - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Zenyatta); + Global.UpgradeMaxAmmoValue < Global.UpgradeMaxAmmoMaxValue[2]; + } + + actions + { + If(Event Player.isBoss == 1); + Global.UpgradeMaxAmmoValue += 10; + Else; + Global.UpgradeMaxAmmoValue += 1; + End; + } +} + +rule("GLOBAL: UPGRADE - MAX AMMO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("MAX AMMO 200% UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "MAX AMMO 200%"), Right, 10, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("Bulletstorm: Your weapon can hold unlimited ammo"), + Custom String("KILL {2}: {0}/{1}", Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[1], Hero(Zenyatta)), Left, 15, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + For Global Variable(LoopIterator1, 0, Count Of(All Players(Team 1)), 1); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0) * 2); + Set Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1) * 2); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 0, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 0)); + Set Ammo(All Players(Team 1)[Global.LoopIterator1], 1, Max Ammo(All Players(Team 1)[Global.LoopIterator1], 1)); + End; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK BULLETSTORM - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("BULLETSTORM UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Bulletstorm"), Right, 11, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("+50% DAMAGE"), Custom String("KILL {2}: {0}/{1}", + Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[2], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[2] = Last Text ID; + Global.Perk[1] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).AbilityHUD[19] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - +50% DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("+50% DAMAGE UNLOCKED!")); + Destroy HUD Text(Global.UpgradeMaxAmmoHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "+50% DAMAGE"), Right, 12, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.UpgradeMaxAmmoHudId[2] = Last Text ID; + Global.DamageDone = 50; + All Players(Team 1).DamageDealt = 100 + Global.DamageDone + All Players(Team 1).Abilities[13] * 5; + Set Damage Dealt(All Players(Team 1), All Players(Team 1).DamageDealt); + Global.challengeCount += 1; + } +} + +disabled rule("=== GAME PHASES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: ASEMBLING PHASE - MAKE CHALLENGES HUDS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Assembling Heroes == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Disable Inspector Recording; + Set Match Time(20); + End; + Create In-World Text(All Players(Team 1), Custom String(" {0}\r\nREPAIR\r\n {1}", Hero Icon String(Hero(Torbjörn)), + Ability Icon String(Hero(Bastion), Button(Secondary Fire))), Global.GatePosition + Vector(0, 1.400, 0), 1.200, Do Not Clip, + Visible To, Color(White), Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("TEAM CHALLENGES"), Left, 11, Color(White), Color(Blue), Color( + White), Visible To, Default Visibility); + "UPGRADE - GATE'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String( + "GATE'S MAX HEALTH: {0} HP", Global.UpgradeGateMaxHealthMaxValue[0]), Custom String("REPAIR GATE {0}/{1} HP", + Global.UpgradeGateMaxHealthValue, Global.UpgradeGateMaxHealthMaxValue[0]), Left, 12, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.UpgradeGateMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 2, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - PLAYER'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +50%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.UpgradePlayerMaxHealthValue, Down), + Global.UpgradePlayerMaxHealthMaxValue[0]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.UpgradePlayerMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 4, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - CRITICAL DAMAGE" + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("CRITICAL DAMAGE 150%"), Custom String( + "KILL WIDOW WITH HEADSHOT: {0}/{1}", Global.UpgradeCriticalDamageValue, Global.UpgradeCriticalDamageMaxValue[0]), Left, 14, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.UpgradeCriticalDamageHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 6, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - MAX AMMO" + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("MAX AMMO 200%"), Custom String("KILL {2}: {0}/{1}", + Global.UpgradeMaxAmmoValue, Global.UpgradeMaxAmmoMaxValue[0], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.UpgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Custom String("HOLD {0} - Reload to open the shop", Input Binding String(Button(Reload))), + Null, Null, Top, 1000, Color(Yellow), Color(White), Color(White), Visible To and String, Default Visibility); + } +} + +rule("GLOBAL: SETUP PHASE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + If(Global.IsDebug); + Set Match Time(1); + Else; + Pause Match Time; + Create HUD Text(All Players(Team 1), Custom String("PRESS {0} TO START", Button(Interact)), Null, Null, Top, 50, Color(Red), Color( + White), Color(White), Visible To and String, Default Visibility); + Global.GlobalHuds[0] = Last Text ID; + Set Match Time(20); + Wait Until(Is True For Any(All Players(Team 1), Is Button Held(Current Array Element, Button(Interact))), 99999); + Destroy HUD Text(Global.GlobalHuds[0]); + Unpause Match Time; + End; + Set Objective Description(All Players(All Teams), Custom String("DEFEND GATE"), Visible To and String); + } +} + +rule("GLOBAL: GAME IN PROGRESS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + } + + actions + { + Set Match Time(3599); + Pause Match Time; + Disable Built-In Game Mode Scoring; + Disable Built-In Game Mode Announcer; + Disable Built-In Game Mode Completion; + Disable Game Mode HUD(All Players(All Teams)); + Disable Game Mode In-World UI(All Players(All Teams)); + Global.GateHealth = Global.GateMaxHealth; + Global.GateHealthChase = Global.GateHealth; + Global.GateProgressBarColorComponent = 255; + Global.GateProgressBarColorCurrent = Color(White); + Create Progress Bar HUD Text(All Players(Team 1), Global.GateHealthChase * 100 / Global.GateMaxHealth, Custom String( + "GATE {0}/{1}", Global.GateHealth, Global.GateMaxHealth), Top, 1, Global.GateProgressBarColorCurrent, Color(White), + Visible To Values and Color, Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("SURVIVED TIME: {0}:{1}", Global.TimeMin, + Global.TimeSec < 10 ? Custom String("0{0}", Global.TimeSec) : Global.TimeSec), Top, 2, Color(White), Color(White), Color( + White), Visible To and String, Default Visibility); + Start Rule(GameLogicWave0, Do Nothing); + } +} + +disabled rule("=== GAME - MAIN LOGIC ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: DEFEAT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.IsDebug == False; + Global.GateHealth <= 0; + } + + actions + { + Declare Team Victory(Team 2); + } +} + +rule("GLOBAL: TIMER - MAIN GAME LOOP") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + disabled Global.GateHealth > 0; + } + + actions + { + Wait(1, Ignore Condition); + Global.TimeSec += 1; + If(Global.TimeSec == 60); + Global.TimeSec = 0; + Global.TimeMin += 1; + Global.Time5Min = Round To Integer(Global.TimeMin / 5, Down); + Global.Time10Min = Round To Integer(Global.TimeMin / 10, Down); + Global.SpawnPositionMaxId += 1; + disabled Start Rule(GameLogicAddNextHeroInGame, Restart Rule); + Else If(Global.TimeSec == 30); + Global.SpawnPositionMaxId += 1; + End; + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GAME LOGIC - ADD NEXT HERO IN GAME") +{ + event + { + Subroutine; + GameLogicAddNextHeroInGame; + } + + actions + { + "REDUCE RESPAWN TIME FOR ZENS" + disabled Global.ZenRespawnTime -= 1.500; + disabled Global.ZenRespawnTime = Max(1, Global.ZenRespawnTime); + disabled Set Respawn Max Time(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Global.DefaultHeroBotsPool[0]), + Global.ZenRespawnTime); + "ALL HEROES WAS ADDED IN GAME" + Abort If(Global.DefaultHeroBotsPoolCurrentId == Count Of(Global.DefaultHeroBotsPool) - 1); + Global.DefaultHeroBotsPoolCurrentId += 1; + "ВРЕМЕННЫЙ КОСТЫЛЬ ЧТОБЫ ЭХО ЗАМЕНИЛА ХАМСТЕРА" + If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Hero(Echo)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Abort; + End; + "ABORT IF NEXT HERO IN ARRAY ORDER IS NULL" + Abort If(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId] == Null); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Global.DefaultHeroBotsPool[Global.DefaultHeroBotsPoolCurrentId], Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("SUBROUTINE: GAME LOGIC - SET BOT PROPERTIES") +{ + event + { + Subroutine; + GameLogicSetBotProperties; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + If(Global.TimeMin >= 10); + If(Filtered Array(Global.lastBoss, Current Array Element == Hero Of(Event Player)) == False); + If(Global.activeBoss == False); + If(Global.bossTrigger < Global.TimeMin); + Global.bossTrigger = Global.TimeMin; + Global.activeBoss = Event Player; + Event Player.isBoss = 1; + Big Message(All Players(Team 1), Custom String("BOSS SPAWNED - {0}", Hero Of(Event Player))); + End; + End; + End; + End; + "PROPERTIES BY DEFAULT" + Set Gravity(Event Player, 100); + Set Damage Dealt(Event Player, 100); + Set Respawn Max Time(Event Player, 10); + Start Scaling Player(Event Player, 1, False); + "INDIVIDUAL HERO'S PROPERTIES" + If(Hero Of(Event Player) == Hero(Zenyatta)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 30); + Set Max Health(Event Player, 10 * (100 + 10 * Global.TimeMin + 25 * Global.Time5Min + 50 * Global.Time10Min) * ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 1.500, False); + Else; + If(20 + 3 * Number Of Players(Team 1) + 3 * Global.TimeMin > 75); + Set Move Speed(Event Player, 75); + Else; + Set Move Speed(Event Player, 20 + 3 * Count Of(All Players(Team 1)) + 3 * Global.TimeMin); + End; + Set Max Health(Event Player, 100 + 10 * Global.TimeMin + 25 * Global.Time5Min + 50 * Global.Time10Min); + End; + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 20); + Set Max Health(Event Player, 5 * (70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin + 25 * Global.Time5Min + 50 * Global.Time10Min) * ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + If(30 + Global.TimeMin + 2.500 * Global.Time5Min > 40); + Set Move Speed(Event Player, 40); + Else; + Set Move Speed(Event Player, 30 + Global.TimeMin + 2.500 * Global.Time5Min); + End; + Set Ultimate Charge(Event Player, 0); + Set Max Health(Event Player, 70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.TimeMin + 25 * Global.Time5Min + 50 * Global.Time10Min); + End; + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + If(Event Player.isBoss == 1); + Set Damage Dealt(Event Player, 2 * (85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min + 50 * Global.Time10Min)); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 5 * (100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin + 15 * Global.Time5Min + 40 * Global.Time10Min) * ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Event Player.BotCounter = 0; + Set Damage Dealt(Event Player, 85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.Time5Min + 50 * Global.Time10Min); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.TimeMin + 15 * Global.Time5Min + 40 * Global.Time10Min); + End; + Else If(Hero Of(Event Player) == Hero(Bastion)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 50); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min + 10 * Global.Time10Min); + Start Scaling Player(Event Player, 3, False); + Set Max Health(Event Player, 5 * (155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin + 40 * Global.Time5Min + 65 * Global.Time10Min) * ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Else; + Set Move Speed(Event Player, 80); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min + 10 * Global.Time10Min); + Start Scaling Player(Event Player, 2, False); + Set Max Health(Event Player, 155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.TimeMin + 40 * Global.Time5Min + 65 * Global.Time10Min); + End; + Else If(Hero Of(Event Player) == Hero(Orisa)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 5 * (220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min + 100 * Global.Time10Min) * ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Set Move Speed(Event Player, 30 + 5 * Global.Time5Min); + Else; + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.Time5Min + 100 * Global.Time10Min); + Set Move Speed(Event Player, 90 + 5 * Global.Time5Min); + End; + Else If(Hero Of(Event Player) == Hero(Echo)); + If(Event Player.isBoss == 1); + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 70 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 5 * (90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin + 25 * Global.Time5Min + 50 * Global.Time10Min) * ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 130 + 5 * Global.Time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin + 25 * Global.Time5Min + 50 * Global.Time10Min); + End; + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.500, False); + Set Move Speed(Event Player, 70); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min + 10 * Global.Time10Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 5 * (55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin + 25 * Global.Time5Min + 50 * Global.Time10Min) * ( + Global.UpgradeBossHealthValue >= Global.UpgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Else; + disabled Start Scaling Player(Event Player, 0.850, False); + Set Move Speed(Event Player, 110); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.Time5Min + 10 * Global.Time10Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.TimeMin + 25 * Global.Time5Min + 50 * Global.Time10Min); + End; + End; + Wait(0.250, Ignore Condition); + "FILL HEALTH" + Heal(Event Player, Null, 100000); + } +} + +disabled rule("=== GATE ===") +{ + event + { + Ongoing - Global; + } +} + +rule("Subroutine: GATE REPAIR") +{ + event + { + Subroutine; + GateRepair; + } + + actions + { + Small Message(Event Player, Custom String("REPAIR +2% ULTIMATE")); + "UPGRADE - GATE'S MAX HEALTH" + If(Global.UpgradeGateMaxHealthValue < Global.UpgradeGateMaxHealthMaxValue[2]); + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.UpgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.UpgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.UpgradeGateMaxHealthValue += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + End; + End; + "HEAL GATE" + If(Event Player.IsNanoed == 1); + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.GateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[1]); + Global.GateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.GateHealth += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + "CHARGE ULTIMATE" + Else; + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + End; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + } +} + +rule("TORB: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Has Spawned(Event Player) == True; + Weapon(Event Player) == 2; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(Is Using Ability 2(Event Player) == True ? 0.350 : 0.700, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Brig: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 5; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Rein: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.GateHealth < Global.GateMaxHealth; + Is In View Angle(Event Player, Global.GateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + Is Game In Progress == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Call Subroutine(GateRepair); + Wait(0.850, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GATE PROGRESS BAR COLOR") +{ + event + { + Subroutine; + GateProgressBarColor; + } + + actions + { + Stop Chasing Global Variable(GateHealthChase); + Chase Global Variable Over Time(GateHealthChase, Global.GateHealth, 0.100, Destination and Duration); + "GATE WAS DAMAGED" + If(Global.GateHealth < Global.GateHealthEvent); + For Global Variable(LoopIterator1, 0, 3, 1); + Global.GateProgressBarColorCurrent = Color(Red); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(White); + Wait(0.030, Ignore Condition); + End; + "GATE WAS REPAIRED" + Else; + Global.GateProgressBarColorCurrent = Color(Green); + Wait(0.030, Ignore Condition); + Global.GateProgressBarColorCurrent = Color(Yellow); + Wait(0.030, Ignore Condition); + End; + Global.GateHealthEvent = Global.GateHealth; + Global.GateProgressBarColorComponent = Global.GateHealth * 255 / Global.GateMaxHealth; + Global.GateProgressBarColorCurrent = Custom Color(255, Global.GateProgressBarColorComponent, Global.GateProgressBarColorComponent, + 255); + } +} + +disabled rule("=== COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("ALL: INIT") +{ + event + { + Player Joined Match; + All; + All; + } + + actions + { + "ALL (COMMON) INIT" + Event Player.IsDead = True; + Disable Kill Feed(Event Player); + Disable Game Mode In-World UI(Event Player); + Disable Death Spectate Target HUD(Event Player); + "BOT INIT" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotInit); + "PLAYER INIT" + Else; + Call Subroutine(PlayerInit); + End; + } +} + +rule("SUBROUTINE: BOT - INIT") +{ + event + { + Subroutine; + BotInit; + } + + actions + { + "INIT VARS" + Event Player.HasBadStatus = False; + Event Player.IsRespawning = False; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEventPosition = Vector(9999, 999, 9999); + "DISABLE ALL FOR BOT" + Disable Hero HUD(Event Player); + Disable Messages(Event Player); + Disable Text Chat(Event Player); + Disable Scoreboard(Event Player); + Disable Game Mode HUD(Event Player); + Disable Death Spectate All Players(Event Player); + Disable Voice Chat(Event Player, True, True, True); + "INIT AI NAVIGATION VARS" + Call Subroutine(BotResetPathFinding); + } +} + +rule("SUBROUTINE: PLAYER - INIT") +{ + event + { + Subroutine; + PlayerInit; + } + + actions + { + "STORY HEROES" + If(Global.IsStoryHeroes); + Reset Player Hero Availability(Event Player); + Set Player Allowed Heroes(Event Player, Array(Hero(Ana), Hero(Brigitte), Hero(Mercy), Hero(Lúcio), Hero(Moira), Hero(Baptiste), + Hero(Ashe), Hero(D.Va), Hero(Genji), Hero(Hanzo), Hero(Widowmaker), Hero(Cassidy), Hero(Reinhardt), Hero(Soldier: 76), Hero( + Torbjörn), Hero(Tracer), Hero(Winston), Hero(Pharah))); + End; + "TEAM CHALLENGE - PLAYER'S MAX HEALTH" + If(Global.UpgradePlayerMaxHealthValue >= Global.UpgradePlayerMaxHealthMaxValue[0]); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + End; + If(Is Game In Progress); + Disable Game Mode HUD(Event Player); + End; + } +} + +rule("ALL: RESPAWN") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + (Hero Of(Event Player) != Event Player.CurrentHero || Event Player.IsDead == True) == True; + } + + actions + { + Event Player.IsDead = False; + "BOT RESPAWN" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotRespawn); + If(Global.IsDebugAINavigation); + Create Beam Effect(All Players(All Teams), Good Beam, Eye Position(Event Player), Event Player.BotNextNodePosition, Color(Green), + Visible To Position and Radius); + End; + "PLAYER RESPAWN" + Else; + Call Subroutine(PlayerRespawn); + End; + "MUST BE AFTER ALL RESPAWN SUBROUTINES!" + Event Player.CurrentHero = Hero Of(Event Player); + } +} + +rule("SUBROUTINE: BOT - RESPAWN") +{ + event + { + Subroutine; + BotRespawn; + } + + actions + { + "RESET COMMON PROPERTIES" + Event Player.IsRespawning = True; + Enable Nameplates(Event Player, All Players(Team 1)); + Call Subroutine(BotResetPathFinding); + disabled If(Hero Of(Event Player) != Event Player.CurrentHero); + Call Subroutine(GameLogicSetBotProperties); + disabled End; + "INDIVIDUAL HERO'S RESPAWN SCRIPTS" + If(Hero Of(Event Player) == Hero(Bastion)); + Call Subroutine(BotBastionRespawn); + Else If(Hero Of(Event Player) == Hero(Zenyatta)); + Call Subroutine(BotZenyattaRespawn); + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + Call Subroutine(BotWidowRespawn); + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Call Subroutine(BotBallRespawn); + Else If(Hero Of(Event Player) == Hero(Orisa)); + Call Subroutine(BotOrisaRespawn); + Else If(Hero Of(Event Player) == Hero(Echo)); + Call Subroutine(BotEchoRespawn); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Call Subroutine(BotReinRespawn); + End; + Event Player.IsRespawning = False; + } +} + +rule("SUBROUTINE: PLAYER - RESPAWN") +{ + event + { + Subroutine; + PlayerRespawn; + } + + actions + { + "TEAM CHALLENGE - MAX AMMO" + If(Hero Of(Event Player) != Event Player.CurrentHero && Global.UpgradeMaxAmmoValue >= Global.UpgradeMaxAmmoMaxValue[0]); + Set Max Ammo(Event Player, 0, Ammo(Event Player, 0) * 2); + Set Max Ammo(Event Player, 1, Ammo(Event Player, 1) * 2); + Set Ammo(Event Player, 0, Max Ammo(Event Player, 0)); + Set Ammo(Event Player, 1, Max Ammo(Event Player, 1)); + End; + "MUST BE AFTER TEAM CHALLENGE MAX AMMO!" + disabled Event Player.CurrentHero = Hero Of(Event Player); + "PLAYER RESPAWN" + Set Status(Event Player, Null, Phased Out, 3); + Set Facing(Event Player, Vector(-1, 0, 0), To World); + If(Ability Cooldown(Players On Hero(Hero(Mercy), Team 1), Button(Ability 2)) >= 29); + Wait(0.250, Ignore Condition); + Teleport(Event Player, Event Player.deathPosition); + Else; + Teleport(Event Player, Global.PlayerSpawnPositions[Slot Of(Event Player) == Count Of(Global.PlayerSpawnPositions) ? Random Integer( + 0, Count Of(Global.PlayerSpawnPositions) - 1) : Slot Of(Event Player)]); + End; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + } +} + +rule("PLAYER: DEATH") +{ + event + { + Player Died; + Team 1; + All; + } + + actions + { + If(Hero Of(Event Player) == Hero(Roadhog)); + Event Player.Abilities[8] -= 1; + Wait(Global.Perk[2] ? 5 : 10, Ignore Condition); + Event Player.Abilities[8] += 1; + End; + Event Player.deathPosition = Position Of(Event Player); + disabled If(Event Player.lastSecondWind > 0); + disabled Event Player.lastSecondWind = 0; + disabled End; + Event Player.IsDead = True; + } +} + +rule("BOT: DEATH") +{ + event + { + Player Died; + Team 2; + All; + } + + actions + { + If(Event Player.isBoss == 1); + If(Global.UpgradePerkSharpshooterValue >= Global.UpgradeCriticalDamageMaxValue[1]); + If(Global.UpgradeBossHealthValue < Global.UpgradeCriticalDamageMaxValue[2]); + Global.UpgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + End; + End; + Event Player.isBoss = 0; + Global.activeBoss = Null; + Big Message(All Players(Team 1), Custom String("BOSS DIED - {0}", Hero Of(Event Player))); + End; + Event Player.IsDead = True; + Event Player.HasBadStatus = False; + Event Player.BotDoesUniqueBehaviour = False; + Disable Nameplates(Event Player, All Players(Team 1)); + disabled Stop Holding Button(Event Player, Button(Ability 1)); + disabled Stop Holding Button(Event Player, Button(Primary Fire)); + disabled Stop Holding Button(Event Player, Button(Secondary Fire)); + "BOT HAS 1 EFFECT IN VAR (NOT ARRAY)" + Skip If(!Entity Exists(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects); + "BOT HAS MORE THEN 1 EFFECT IN VAR (ARRAY)" + Skip If(Count Of(Event Player.BotEffects) == 0, 3); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotEffects), 1); + Destroy Effect(Event Player.BotEffects[Event Player.BotLoopIterator1]); + End; + } +} + +disabled rule("=== BOT COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BAD STATUS") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + Event Player.HasBadStatus = True; + "PROCESS BAD STATUS" + If(Hero Of(Event Player) == Hero(Widowmaker)); + Start Rule(BotWidowBadStatus, Do Nothing); + End; + Wait Until(!Has Status(Event Player, Knocked Down) && !Has Status(Event Player, Asleep) && !Has Status(Event Player, Frozen) + && !Has Status(Event Player, Stunned), 15); + Event Player.HasBadStatus = False; + } +} + +rule("SUBROUTINE: BOT - LANDING FROM SKY") +{ + event + { + Subroutine; + BotLandingFromSky; + } + + actions + { + Stop Throttle In Direction(Event Player); + "SET RESPAWN POSITION" + Event Player.BotEventPosition = Random Value In Array(Global.BigBossSpawnPositions); + "CREATE EFFECTS" + disabled Create Effect(All Players(All Teams), Light Shaft, Color(Red), Event Player.BotEventPosition, 3, Visible To); + disabled Event Player.BotEffects = Last Created Entity; + "RESPAWN IN LIGHT SHAFT EFFECT" + Teleport(Event Player, Event Player.BotEventPosition + Vector(0, 25, 0)); + Wait(0.020, Ignore Condition); + "SLOW LANDING" + Set Gravity(Event Player, 50); + While(Is In Air(Event Player) == True); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Position Of(Event Player) + Vector(0, -2.700, 0), 2); + Wait(0.250, Ignore Condition); + End; + Set Gravity(Event Player, 100); + disabled Destroy Effect(Event Player.BotEffects); + "LANDING EFFECTS" + Play Effect(All Players(All Teams), Wrecking Ball Piledriver Impact Effect, Custom Color(105, 87, 46, 255), Position Of( + Event Player), 8); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Sound, Color(White), Position Of(Event Player), 150); + } +} + +rule("SUBROUTINE: BOT - APPEAR FROM UNDERGROUND") +{ + event + { + Subroutine; + BotApearFromUnderground; + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1); + Wait(0.200, Ignore Condition); + Set Gravity(Event Player, 20); + Disable Movement Collision With Environment(Event Player, True); + Teleport(Event Player, Global.ZenSpawnPositions[Random Integer(Min(Global.TimeMin, Count Of(Global.ZenSpawnPositions) - 10), Min( + Global.SpawnPositionMaxId, Count Of(Global.ZenSpawnPositions) - 4))] + Vector(0, -1.500, 0)); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Sigma Accretion Impact Effect, Custom Color(220, 175, 100, 255), Eye Position(Event Player), + 3); + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(Gray), Eye Position(Event Player), 50); + Apply Impulse(Event Player, Up, 3.500, To World, Cancel Contrary Motion); + Wait(0.400, Ignore Condition); + Clear Status(Event Player, Knocked Down); + Set Gravity(Event Player, 100); + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("=== PLAYER MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("PLAYER: DARKNESS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + !Entity Exists(Event Player.BotEffects) == True; + } + + actions + { + Disable Nameplates(Event Player, All Players(All Teams)); + Start Forcing Player Outlines(Event Player, All Players(All Teams), False, Color(White), Default); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 14), 25, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(-5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + } +} + +rule("PLAYER: HEALTH REGEN") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + actions + { + Stop Heal Over Time(Event Player.HealOverTimeId); + Event Player.EventHealth = Health(Event Player); + Wait(4, Ignore Condition); + "TOOK DAMAGE, RESET REGENERATION TIMER" + Loop If(Is Alive(Event Player) && Event Player.EventHealth > Health(Event Player)); + Start Heal Over Time(Event Player, Null, 3, Max Health(Event Player) / 3); + Event Player.HealOverTimeId = Last Heal Over Time ID; + } +} + +disabled rule("=== NERFS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("REINHARDT: ANTI-CHARGE FOR BASTION & ORISA") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Using Ability 1(Event Player) == True; + Hero Of(Ray Cast Hit Player(Eye Position(Event Player) + Vector(0, 2, 0), Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 2, All Living Players(Team 2), Event Player, True)) == (Hero(Bastion) == True || Hero( + Orisa) == True); + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1.500); + } +} + +rule("HOG: ANTI-HOOK FOR BASTION & ORISA") +{ + event + { + Player Dealt Damage; + Team 1; + Roadhog; + } + + conditions + { + Event Ability == Button(Ability 1); + (Hero Of(Victim) == Hero(Bastion) || Hero Of(Victim) == Hero(Orisa)) == True; + } + + actions + { + Set Status(Event Player, Null, Stunned, 0.005); + } +} + +disabled rule("=== ZENYATTA ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ZEN - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Zenyatta; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + } + + actions + { + Set Ammo(Event Player, 0, 0); + Communicate(Event Player, Hello); + disabled Call Subroutine(BotResetPathFinding); + Wait(1.500, Ignore Condition); + Abort If(Is Dead(Event Player) == True); + Kill(Event Player, Null); + } +} + +rule("BOT: ZEN - DEATH") +{ + event + { + Player Died; + Team 2; + Zenyatta; + } + + actions + { + "EFFECT" + Play Effect(All Players(All Teams), Junkrat Frag Launcher Explosion Effect, Color(Red), Eye Position(Event Player), 2.500); + Play Effect(All Players(All Teams), Ashe Dynamite Explosion Sound, Color(Red), Eye Position(Event Player), 70); + "DAMAGE AND APPLY IMPULSE TO PLAYERS" + Event Player.BotPlayersInRadius = Players Within Radius(Position Of(Event Player), 2.500, All Teams, Surfaces And Enemy Barriers); + For Player Variable(Event Player, BotLoopIterator1, 0, Count Of(Event Player.BotPlayersInRadius), 1); + Apply Impulse(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Direction Towards(Position Of(Event Player), + Eye Position(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1])), 5, To World, Incorporate Contrary Motion); + If(Team Of(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1]) == Team 1); + Damage(Event Player.BotPlayersInRadius[Event Player.BotLoopIterator1], Event Player, 50); + End; + End; + "DAMAGE GATE" + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 125; + Else; + Global.GateHealth -= 25; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Respawn(Event Player); + Abort; + End; + "KILLED BY PLAYER" + Teleport(Event Player, Vector(0, -999, 0)); + Wait(2, Ignore Condition); + Respawn(Event Player); + Wait(2, Ignore Condition); + } +} + +rule("SUBROUTINE: ZEN - RESPAWN") +{ + event + { + Subroutine; + BotZenyattaRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WRECKING BALL ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BALL - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + disabled Distance Between(Position Of(Event Player), Global.GatePosition) < 3; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Set Ammo(Event Player, 0, 0); + Wait(1, Ignore Condition); + Set Ultimate Charge(Event Player, 100); + Start Holding Button(Event Player, Button(Ultimate)); + Wait Until(Is Using Ultimate(Event Player), 0.600); + Abort If(Is Dead(Event Player)); + Kill(Event Player, Null); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Effect, Color(Orange), Eye Position(Event Player), 6); + Play Effect(All Players(All Teams), DVa Self Destruct Explosion Sound, Color(White), Eye Position(Event Player), 250); + If(Distance Between(Position Of(Event Player), Global.GatePosition) < 3.500 && Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.GateHealth -= 300; + Else; + Global.GateHealth -= 150; + End; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Damage(Players Within Radius(Eye Position(Event Player), 7, Team 1, Surfaces And All Barriers), Event Player, 200); + } +} + +rule("BOT: BALL - ALTERNATIVE FORM") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is In Alternate Form(Event Player) == False; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is In Alternate Form(Event Player), 10); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: BALL - DEATH") +{ + event + { + Player Died; + Team 2; + Wrecking Ball; + } + + actions + { + Stop Holding Button(Event Player, Button(Ability 1)); + Stop Holding Button(Event Player, Button(Ultimate)); + } +} + +rule("SUBROUTINE: BALL - RESPAWN") +{ + event + { + Subroutine; + BotBallRespawn; + } + + actions + { + "RESPAWN IN AIR" + Teleport(Event Player, Random Value In Array(Global.BallSpawnPositions) + Vector(0, 20, 0)); + Stop Holding Button(Event Player, Button(Ultimate)); + Wait(0.250, Ignore Condition); + "LANDING" + Start Holding Button(Event Player, Button(Crouch)); + Wait Until(Is On Ground(Event Player), 9999); + Stop Holding Button(Event Player, Button(Crouch)); + "LANDING IMPACT EFFECT" + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(White), Event Player, 150); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Effect, Color(Gray), Position Of(Event Player), 10); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Eye Position(Event Player), 1.500, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + "PATH FINDING TO GATE" + Event Player.BotTargetPosition = Global.GatePosition; + Event Player.BotIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +disabled rule("=== ECHO ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ECHO - FLY ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is Using Ability 1(Event Player) == False; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), 0); + Press Button(Event Player, Button(Ability 1)); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - BEAM ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Using Ability 1(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == True; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - BAD STATUS - RESET BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.HasBadStatus == True; + disabled (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + Wait Until(Event Player.HasBadStatus, 7); + } +} + +rule("BOT: ECHO - CAN'T SEE PORTAL - APPLY IMPULSE") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == True; + Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Wait(0.300, Abort When False); + Apply Impulse(Event Player, Vector(Random Integer(-1, 1), 1, Random Integer(-1, 1)), 20, To World, Incorporate Contrary Motion); + Wait(1, Ignore Condition); + If(!Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + Event Player.BotTargetPosition = Global.BotEchoRespawnPosition; + Start Rule(BotStartPathFinding, Restart Rule); + Else; + Call Subroutine(BotResetPathFinding); + End; + Loop If Condition Is True; + } +} + +disabled rule("BOT: ECHO - MAIN LOGIC - BACKUP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(!Event Player.BotIsPathFinding); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Is In Line of Sight(Eye Position(Event Player), + Eye Position(Current Array Element), Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), + Position Of(Current Array Element)))[0]; + End; + "NO PLAYERS IN VIEW RANGE" + disabled If(Event Player.BotSeePlayer == Null); + disabled Stop Throttle In Direction(Event Player); + disabled End; + "FLY TO PLAYER" + If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + > 4 && Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + "ACTIVATE FOCUS BEAM" + Else If(Event Player.BotSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) + < 4 && Event Player.BotDoesUniqueBehaviour == False && Event Player.HasBadStatus == False); + Event Player.BotDoesUniqueBehaviour = True; + Set Status(Event Player.BotSeePlayer, Event Player, Stunned, 1); + Set Status(Event Player.BotSeePlayer, Event Player, Hacked, 99999); + Attach Players(Event Player.BotSeePlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + "TELEPORT PLAYER TO AWAY" + Else If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotSeePlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotSeePlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotSeePlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + "BEGIN TO FLY TO THE PORTAL" + Else If(Event Player.BotDoesUniqueBehaviour == True); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour == False); + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + End; + "TELEPORT PLAYER SO FAR" + If(Event Player.BotDoesUniqueBehaviour && Distance Between(Position Of(Event Player.BotEchoCapturedPlayer), + Global.BotEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.BotEchoRespawnPosition, 1); + Teleport(Event Player.BotEchoCapturedPlayer, Random Value In Array(Global.BotEchoTeleportPositions)); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + End; + "BEGIN TO FLY TO THE PORTAL WITH A PLAYER" + If(Event Player.BotDoesUniqueBehaviour); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.BotEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.BotIsPathFinding); + Event Player.BotTargetPlayer = Event Player.BotEchoCapturedPlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - DEFEND PORTAL") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + } + + actions + { + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPlayer); + } +} + +rule("BOT: ECHO - PATH FINDING TO PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPlayer = Event Player.BotSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Call Subroutine(BotStartPathFinding); + } +} + +rule("BOT: ECHO - ATTACH PLAYER BY BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Event Player.BotSeePlayer != Null; + Event Player.IsRespawning == False; + Event Player.BotEchoCapturedPlayer == Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer), Barriers Do Not Block LOS) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 3; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Event Player.BotEchoCapturedPlayer = Event Player.BotSeePlayer; + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Stunned, 0.700); + Set Status(Event Player.BotEchoCapturedPlayer, Event Player, Hacked, 10); + Attach Players(Event Player.BotEchoCapturedPlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - PLAYER DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Is Dead(Event Player.BotEchoCapturedPlayer) != Null; + } + + actions + { + If(Event Player.BotDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + If(Event Player.BotIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - DEATH") +{ + event + { + Player Died; + Team 2; + Echo; + } + + actions + { + Call Subroutine(BotEchoDetachPlayer); + Stop Holding Button(Event Player, Button(Jump)); + Wait(5, Ignore Condition); + Teleport(Event Player, Vector(0, 999, 0)); + Start Forcing Player To Be Hero(Event Player, Hero(Orisa)); + } +} + +rule("SUBROUTINE: ECHO - RESPAWN") +{ + event + { + Subroutine; + BotEchoRespawn; + } + + actions + { + Event Player.BotCounter = 0; + Event Player.BotEffects = Empty Array; + Create Effect(All Players(All Teams), Good Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Global.BotEchoRespawnPosition, Event Player.BotCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Energy Sound, Color(White), Global.BotEchoRespawnPosition, 200, Visible To); + Modify Player Variable(Event Player, BotEffects, Append To Array, Last Created Entity); + Chase Player Variable Over Time(Event Player, BotCounter, 3, 0.800, Destination and Duration); + Play Effect(All Players(All Teams), Sombra EMP Explosion Effect, Color(Sky Blue), Global.BotEchoRespawnPosition, 12); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Null, Global.BotEchoRespawnPosition, 100); + Wait(3, Ignore Condition); + Teleport(Event Player, Global.BotEchoRespawnPosition); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Global.BotEchoRespawnPosition, 2.500); + Play Effect(All Players(All Teams), Debuff Impact Sound, Null, Global.BotEchoRespawnPosition, 100); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PLAYER") +{ + event + { + Subroutine; + BotEchoFlyToPlayer; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Stop Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PORTAL") +{ + event + { + Subroutine; + BotEchoFlyToPortal; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.BotEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - DETACH PLAYER") +{ + event + { + Subroutine; + BotEchoDetachPlayer; + } + + actions + { + Detach Players(Event Player.BotEchoCapturedPlayer); + Clear Status(Event Player.BotEchoCapturedPlayer, Hacked); + "IF PLAYER INSIDE THE WALL" + If(Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.BotEchoCapturedPlayer), Barriers Do Not Block LOS)); + Teleport(Event Player.BotEchoCapturedPlayer, Position Of(Event Player)); + End; + Event Player.BotDoesUniqueBehaviour = False; + Event Player.BotEchoCapturedPlayer = Null; + } +} + +disabled rule("=== REINHARDT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: REIN - SET PLAYER AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + disabled Event Player.BotIsPathFinding == False; + "BOT IS FAR FROM GATES" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Global.GatePosition), 0, Z Component Of(Global.GatePosition))) > 20; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET CLOSEST PLAYER TO BOT AS TARGET AND FOLLOW HIM" + Event Player.BotTargetPlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - SET GATE AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "BOT DOESN'T FOLLOW PLAYER" + Event Player.BotTargetPlayer == -1; + "CAN'T SEE ANY PLAYER" + disabled Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), !Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET GATE AS TARGET" + Event Player.BotTargetPosition = Global.GatePosition; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - TARGET DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer != -1; + Is Dead(Event Player.BotTargetPlayer) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + } +} + +rule("BOT: REIN - ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) < 4; + "CAN ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) < 4; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + "TARGET IS PLAYER" + Abort If(Event Player.BotTargetPlayer != -1); + If(Event Player.isBoss == 1); + "TARGET IS GATE" + Global.GateHealth -= 25; + Else; + Global.GateHealth -= 5; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: REIN - STOP ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) + : Global.GatePosition) > 4; + "CAN'T ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition), 0, + Z Component Of(Event Player.BotTargetPlayer != -1 ? Position Of(Event Player.BotTargetPlayer) : Global.GatePosition))) > 4; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + } +} + +rule("BOT: REIN - USE SHIELD") +{ + event + { + Player Took Damage; + Team 2; + Reinhardt; + } + + conditions + { + Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) > 3; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Attacker)), 200, To World, + Direction and Turn Rate); + Start Holding Button(Event Player, Button(Secondary Fire)); + Wait Until(Distance Between(Position Of(Event Player), Position Of(Event Player.BotTargetPlayer)) < 3, 3); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("BOT: REIN - CHARGE IN GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotTargetPlayer == -1; + Is Using Ability 1(Event Player) == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == True; + Is In View Angle(Event Player, Global.GatePosition, 7.500) == True; + } + + actions + { + disabled Wait(0.800, Abort When False); + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is Using Ability 1(Event Player), 1); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: REIN - DEATH") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("SUBROUTINE: REIN - RESPAWN") +{ + event + { + Subroutine; + BotReinRespawn; + } + + actions + { + Call Subroutine(BotApearFromUnderground); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WIDOW ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: WIDOW - SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer == Null; + Event Player.HasBadStatus == False; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Event Player.BotWidowShotTime = Total Time Elapsed + (Global.TimeMin >= 9 ? Random Real(2, 5) : Random Real(5, 10)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 9999, To World, + Direction and Turn Rate); + } +} + +rule("BOT: WIDOW - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.BotSeePlayer != Null; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowShotTime; + } + + actions + { + Press Button(Event Player, Button(Primary Fire)); + Stop Facing(Event Player); + Event Player.BotSeePlayer = Null; + } +} + +rule("BOT: WIDOW - Aim Sound") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Alive(Event Player) == True; + Is In Line of Sight(Eye Position(Players On Hero(Hero(Widowmaker), Team 2)), Eye Position(Event Player), Barriers Do Not Block LOS) + == True; + Is Alive(Players On Hero(Hero(Widowmaker), Team 2)) == True; + Players On Hero(Hero(Widowmaker), Team 2).BotSeePlayer == True; + } + + actions + { + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 100); + Wait(1, Abort When False); + Loop If Condition Is True; + } +} + +rule("BOT: WIDOW - TELEPORT TO NEW POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.HasBadStatus == False; + Total Time Elapsed >= Event Player.BotWidowTeleportTime; + } + + actions + { + Event Player.BotWidowTeleportTime = Total Time Elapsed + 28; + Event Player.BotWidowShotTime = Total Time Elapsed + (Global.TimeMin >= 9 ? Random Real(1, 3) : Random Real(3, 6)); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Event Player, 1); + Wait(0.016, Ignore Condition); + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + } +} + +rule("BOT: WIDOW - DEATH") +{ + event + { + Player Died; + Team 2; + Widowmaker; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + Wait(0.250, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - RESPAWN") +{ + event + { + Subroutine; + BotWidowRespawn; + } + + actions + { + "RESPAWN ON RANDOM SNIPER POSITION" + Teleport(Event Player, Filtered Array(Global.SniperPositions, Distance Between(Event Player.BotEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.SniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.BotEventPosition = Position Of(Event Player); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Wait(0.700, Ignore Condition); + Start Holding Button(Event Player, Button(Secondary Fire)); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait Until(Is Dead(Event Player), 99999); + Destroy Effect(Event Player.BotEffects); + } +} + +rule("SUBROUTINE: WIDOW - BAD STATUS") +{ + event + { + Subroutine; + BotWidowBadStatus; + } + + actions + { + Stop Facing(Event Player); + Destroy Effect(Event Player.BotEffects); + Wait Until(!Event Player.HasBadStatus, 15); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + } +} + +disabled rule("=== BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("BOT: BASTION - FLAME GUN") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 50) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) < 8; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + Stop Holding Button(Event Player, Button(Primary Fire)); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Update Every Frame(Eye Position(Event Player) + World Vector Of( + Vector(-1, -1.200, 1.800), Event Player, Rotation)), 1, Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Start Rule(BotBastionFlameGunDamage, Do Nothing); + Wait(1.100, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(4, Ignore Condition); + Loop If Condition Is True; + } +} + +disabled rule("BOT: BASTION - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + disabled Event Player.BotSeePlayer == Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer)), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - CAN'T SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == False; + } + + actions + { + Event Player.BotSeePlayer = Null; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - MOVE TO BASTION'S TARGET (POSITION)") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotTargetPosition = Random Value In Array(Filtered Array(Global.BastionTargetPositions, Distance Between(Position Of( + Event Player), Current Array Element) > 3.500)); + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("BOT: BASTION - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + "SEE THE PLAYER" + If(Event Player.BotSeePlayer != Null); + Stop Holding Button(Event Player, Button(Secondary Fire)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.BotSeePlayer) - Vector(0, 0.500, + 0)), 100, To World, Direction and Turn Rate); + "SELF REPAIRING" + Else If(!Is Firing Secondary(Event Player) && Health(Event Player) < Max Health(Event Player)); + Start Holding Button(Event Player, Button(Secondary Fire)); + End; + "START FOLLOW PATH" + disabled If(!Event Player.BotIsPathFinding && !Event Player.BotDoesUniqueBehaviour); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled Wait(0.050, Ignore Condition); + disabled Event Player.BotTargetPosition = Random Value In Array(Global.BastionTargetPositions); + disabled Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Event Player.BotTargetPosition + Vector(0, 2, 0)), 100, + To World, Direction and Turn Rate); + disabled Start Rule(BotStartPathFinding, Do Nothing); + "REACHED PATH TARGET" + disabled Else If(Distance Between(Position Of(Event Player), Event Player.BotTargetPosition) <= 3); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled End; + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - ARTILLERY") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 30) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.BotSeePlayer)) > 18; + Distance Between(Eye Position(Event Player), Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Up * 99, Null, Event Player, False)) >= 35; + } + + actions + { + "TRYING TO CAPTURE TARGET" + Wait(0.800, Abort When False); + "CAPTURE TARGET" + Event Player.BotDoesUniqueBehaviour = True; + Stop Throttle In Direction(Event Player); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Update Every Frame(Eye Position(Event Player)), + Update Every Frame(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 1000, All Living Players(Team 1), Event Player, True)), Color(Sky Blue), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Wait(1.400, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Event Player.BotEventPosition = Position Of(Event Player.BotSeePlayer); + "SHOOT FROM ARTILLERY" + Event Player.BotBastionArtilleryDidShotsCount = 0; + For Player Variable(Event Player, BotLoopIterator1, 0, 4, 1); + Event Player.BotBastionArtilleryDidShotsCount += 1; + Play Effect(All Players(All Teams), Wrecking Ball Minefield Explosion Sound, Color(White), Eye Position(Event Player), 250); + Play Effect(All Players(All Teams), Pharah Barrage Explosion Effect, Color(Orange), Eye Position(Event Player) + World Vector Of( + Vector(0, 1.400, -0.700), Event Player, Rotation), 2); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) + World Vector Of(Vector(0, 1.400, + -0.700), Event Player, Rotation), Eye Position(Event Player) + World Vector Of(Vector(Random Real(-1, 1), Random Integer(40, + 80), Random Real(0.500, 1.500)), Event Player, Rotation), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + If(Is Dead(Event Player)); + Break; + End; + End; + disabled Call Subroutine(BotResetPathFinding); + disabled Start Rule(BotStartPathFinding, Do Nothing); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Wait(1.500, Ignore Condition); + Start Rule(BotBastionArtilleryDamage, Do Nothing); + Wait(4, Ignore Condition); + } +} + +rule("BOT: BASTION - PRIMARY FIRE") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotSeePlayer != Null; + Event Player.BotDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.BotSeePlayer), 40) == True; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Stop Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Bastion; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + For Player Variable(Event Player, BotLoopIterator1, 0, 3, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Effect, Color(White), Event Player, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player, 100); + Wait(0.250, Ignore Condition); + End; + } +} + +rule("SUBROUTINE: BASTION - RESPAWN") +{ + event + { + Subroutine; + BotBastionRespawn; + } + + actions + { + Abort If(Event Player.BotIsOrisaChild == True); + Call Subroutine(BotLandingFromSky); + Set Ammo(Event Player, 0, 0); + Wait Until(!Is Reloading(Event Player), 99999); + Event Player.BotTargetPosition = Objective Position(2); + } +} + +rule("SUBROUTINE: BASTION - ARTILLERY DAMAGE") +{ + event + { + Subroutine; + BotBastionArtilleryDamage; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = False; + "EXPLOSIONS OF ARTILLERY" + For Player Variable(Event Player, BotLoopIterator2, 0, Event Player.BotBastionArtilleryDidShotsCount, 1); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotEventPosition + Vector(0, 50, 0), + Event Player.BotEventPosition + Vector(Random Integer(-4, 4), -15, Random Integer(-4, 4)), Null, Event Player, True); + Damage(Players Within Radius(Event Player.BotEventPosition, 8, Team 1, Surfaces And Enemy Barriers), Event Player, 50); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Pharah Rocket Launcher Explosion Effect, Color(Orange), Event Player.BotEventPosition, 5); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Event Player.BotEventPosition, + Event Player.BotEventPosition + Vector(0, 60, 0), Color(Orange), Visible To); + Event Player.BotEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.400, Ignore Condition); + End; + } +} + +disabled rule("SUBROUTINE: BASTION - FLAME GUN DAMAGE") +{ + event + { + Subroutine; + BotBastionFlameGunDamage; + } + + actions + { + Event Player.BotRayCastHitPosition = Eye Position(Event Player) + World Vector Of(Vector(-1, -1.200, 1.800), Event Player, + Rotation); + "FIRE PARTICLES OF FLAME GUN" + For Player Variable(Event Player, BotLoopIterator1, 1, 13, 3); + Event Player.BotEventPosition = Ray Cast Hit Position(Event Player.BotRayCastHitPosition, + Event Player.BotRayCastHitPosition + Facing Direction Of(Event Player) * Event Player.BotLoopIterator1, Null, Event Player, + True); + Damage(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Surfaces And Enemy Barriers), Event Player, 20); + Set Status(Players Within Radius(Event Player.BotEventPosition, 4, Team 1, Off), Event Player, Burning, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player.BotEventPosition, 150); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.BotEventPosition, 2.500); + Wait(0.200, Ignore Condition); + End; + Event Player.BotDoesUniqueBehaviour = False; + } +} + +disabled rule("=== ORISA + BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ORISA-BASTION - REACHED TARGET POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.BotIsPathFinding == True; + Distance Between(Position Of(Event Player), Global.BotOrisaTargetPosition) < 1.500; + } + + actions + { + Call Subroutine(BotResetPathFinding); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Vector(X Component Of(Global.GatePosition), -999, + Z Component Of(Global.GatePosition))), 80, To World, Direction and Turn Rate); + Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + disabled Start Facing(Global.BotOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.GatePosition, Barriers Do Not Block LOS) ? Global.GatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element) && Is In Line of Sight(Eye Position(Event Player), Position Of(Current Array Element), + Barriers Do Not Block LOS)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + Press Button(Event Player, Button(Ability 1)); + Wait Until(Y Component Of(Facing Direction Of(Event Player)) < -0.300, 99999); + Press Button(Event Player, Button(Ability 2)); + Wait(0.800, Ignore Condition); + Global.BotOrisaChild.BotDoesUniqueBehaviour = False; + Disallow Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ORISA-BASTION - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.BotIsOrisaChild == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotDoesUniqueBehaviour == False; + } + + actions + { + Event Player.BotDoesUniqueBehaviour = True; + While(Is Alive(Event Player)); + disabled Create Effect(All Players(All Teams), Bad Aura, Color(Purple), Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3.200, 1, Visible To Position and Radius); + disabled Event Player.BotEffects = Last Created Entity; + Wait(1.500, Ignore Condition); + disabled Destroy Effect(Event Player.BotEffects); + Abort If(Is Dead(Event Player)); + Press Button(Event Player, Button(Primary Fire)); + Press Button(Event Player, Button(Reload)); + Event Player.BotRayCastHitPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Facing Direction Of(Event Player) * 999, All Players(Team 1), All Players(Team 2), True); + "ANTI-SHIELD BUG" + Event Player.BotRayCastHitPosition = Event Player.BotRayCastHitPosition + Direction Towards(Event Player.BotRayCastHitPosition, + Eye Position(Event Player)) * 0.200; + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3, Event Player.BotRayCastHitPosition, Color(Purple), Visible To Position and Radius); + Event Player.BotEffects = Last Created Entity; + Damage(Players Within Radius(Event Player.BotRayCastHitPosition, 4, Team 1, Surfaces And All Barriers), Event Player, 0.040); + Play Effect(All Players(All Teams), Pharah Concussive Blast Effect, Color(Purple), Event Player.BotRayCastHitPosition, 4); + Play Effect(All Players(All Teams), Pharah Concussive Blast Sound, Color(Purple), Event Player.BotRayCastHitPosition, 250); + Play Effect(All Players(All Teams), Bad Explosion, Color(Purple), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 3.300, 2); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Color(Purple), Eye Position(Event Player), 170); + If(Distance Between(Event Player.BotRayCastHitPosition, Global.GatePosition) < 4 && Is In Line of Sight( + Event Player.BotRayCastHitPosition, Global.GatePosition, Enemy Barriers Block LOS)); + Global.GateHealth -= 80; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Wait(0.150, Ignore Condition); + Destroy Effect(Event Player.BotEffects); + Wait(0.060, Ignore Condition); + Wait Until(!Is Reloading(Event Player), 2.500); + End; + } +} + +rule("BOT: ORISA-BASTION - CAN'T SEE THE TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.IsRespawning == False; + Event Player.BotIsPathFinding == False; + Is In Line of Sight(Eye Position(Event Player), Global.GatePosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: ORISA-BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Orisa; + } + + actions + { + Allow Button(Event Player, Button(Ability 2)); + Kill(Global.BotOrisaChild, Null); + Detach Players(Global.BotOrisaChild); + Clear Status(Global.BotOrisaChild, Phased Out); + Set Damage Dealt(Global.BotOrisaChild, 100); + Global.BotOrisaChild.BotIsOrisaChild = False; + Global.BotOrisaChild = Null; + Global.BotOrisaParent = Null; + Start Forcing Player To Be Hero(Event Player, Hero(Widowmaker)); + } +} + +rule("SUBROUTINE: ORISA - RESPAWN") +{ + event + { + Subroutine; + BotOrisaRespawn; + } + + actions + { + Global.BotOrisaParent = Event Player; + "WAITING FOR ANY BASTION TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero(Bastion)), + 99999); + "SETUP BASTION AS CHILD" + Global.BotOrisaChild = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Bastion))[0]; + Global.BotOrisaChild.BotIsOrisaChild = True; + Global.BotOrisaChild.BotDoesUniqueBehaviour = True; + Wait(2, Ignore Condition); + Respawn(Global.BotOrisaChild); + Start Scaling Player(Global.BotOrisaChild, 1.800, False); + Set Damage Dealt(Global.BotOrisaChild, 2000); + Set Status(Global.BotOrisaChild, Null, Phased Out, 9999); + Disable Nameplates(Global.BotOrisaChild, All Players(All Teams)); + Set Facing(Global.BotOrisaChild, Vector(X Component Of(Facing Direction Of(Event Player)), 9999, Z Component Of( + Facing Direction Of(Event Player))), To World); + Start Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Wait Until(Is In Alternate Form(Global.BotOrisaChild), 5); + Stop Holding Button(Global.BotOrisaChild, Button(Ability 1)); + Teleport(Global.BotOrisaChild, Position Of(Event Player)); + Attach Players(Global.BotOrisaChild, Global.BotOrisaParent, Vector(0, 1.800, 0.230)); + disabled Wait(1, Ignore Condition); + disabled Stop Holding Button(Global.BotOrisaChild, Button(Primary Fire)); + disabled Wait(0.250, Ignore Condition); + Call Subroutine(BotLandingFromSky); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.BotNextNodePosition), 360, To World, + Direction and Turn Rate); + Event Player.BotTargetPosition = Global.BotOrisaTargetPosition; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 0 - ZENS, REINS, BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 0; + } + + actions + { + "CREATE BOTS - ZEN" + While(Count Of(All Players(Team 2)) < 13); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "BALL" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "REPLACE DEAD ZEN TO REIN" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) != 3); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 1 - WIDOW") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 1; + } + + actions + { + Global.IsNewWaveGameLogicProcessing = True; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Global.IsNewWaveGameLogicProcessing = False; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 3 - BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 3; + } + + actions + { + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 5 - REINS WAVE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 5; + } + + actions + { + "PREPARE WAVE - DESTROY WIDOW AND BALLS" + Destroy Dummy Bot(Team 2, Slot Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))[0])); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))[0]; + Kill(Global.DefaultCurrentBot, Null); + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + "BOSS WAVE" + Big Message(All Players(All Teams), Custom String("BOSS WAVE - {1} {0}", Hero Icon String(Hero(Reinhardt)), Hero(Reinhardt))); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) < 6); + Wait Until(Is True For Any(All Players(Team 2), Distance Between(Position Of(Current Array Element), Global.GatePosition) + > 13 && Hero Of(Current Array Element) == Hero(Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + disabled Wait(0.200, Ignore Condition); + disabled Set Max Health(Global.DefaultCurrentBot, 50); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) > 3); + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Reinhardt)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Reinhardt))[0]; + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(All Players(Team 2)) < 13); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Big Message(All Players(All Teams), Custom String("BOSS WAVE FINISHED!")); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 7 - BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 7; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 9 - ECHO, +1 BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 9; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Echo))) == 0); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.DefaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.DefaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + "FILL EMPTY SLOTS BY ZENS" + While(Count Of(All Players(Team 2)) < 12); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("Ana Nano Variable") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + } + + actions + { + Player Closest To Reticle(Event Player, Team 1).IsNanoed = 1; + } +} + +rule("IsNanoed") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.IsNanoed == True; + } + + actions + { + If(Is Dead(Event Player)); + Event Player.IsNanoed = 0; + End; + Wait(8, Ignore Condition); + Event Player.IsNanoed = 0; + } +} + +rule("money on kill") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + actions + { + If(Hero Of(Victim) == Hero(Zenyatta)); + All Players(Team 1).Money[0] += 5 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 10 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Reinhardt)); + All Players(Team 1).Money[0] += 15 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 20 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Wrecking Ball)); + All Players(Team 1).Money[0] += 25 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 25 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Widowmaker)); + All Players(Team 1).Money[0] += 30 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 30 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Bastion)); + All Players(Team 1).Money[0] += 50 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 50 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Echo)); + All Players(Team 1).Money[0] += 75 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 75 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Else If(Hero Of(Victim) == Hero(Orisa)); + All Players(Team 1).Money[0] += 100 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + Global.StartMoney += 100 * (Victim.isBoss ? 3 : 1) * Global.MoneyMult; + } +} + +rule("Abilities and Hero Talents by Shingen and LemonAid") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.DamageDealt = 100; + Event Player.PlayerHealth = 100; + Event Player.Money[0] = 2400 + Global.StartMoney; + If(Custom String("{0}", Event Player) == Custom String("ShuriZma")); + Create HUD Text(Event Player, Custom String("Serverload: {0}, AVG {1}, Peak {2}", Server Load, Server Load Average, + Server Load Peak), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + End; + } +} + +rule("Team 1 (Ability): Headhunter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[1] == True; + Event Was Critical Hit == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[1] * 40 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Ambush") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[2] == True; + Event Ability != Null; + (Y Component Of(Position Of(Event Player)) - Y Component Of(Position Of(Victim)) >= 3 || Absolute Value(Horizontal Angle Towards( + Victim, Event Player)) >= 90) == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[2] * 30 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Quick Fix") +{ + event + { + Player Earned Elimination; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[3] == True; + } + + actions + { + Heal(Event Player, Null, Event Player.Abilities[3] * 50); + Set Move Speed(Event Player, 100 + Event Player.Abilities[3] * 20); + Wait(5, Restart When True); + Set Move Speed(Event Player, 100); + } +} + +rule("Team 1 (Ability): Heavyweight") +{ + event + { + Player Dealt Knockback; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[4] == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.Abilities[4] * 25 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Charged") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[5] == True; + Ultimate Charge Percent(Event Player) < Event Player.Abilities[5] * 20; + } + + actions + { + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + If(Is Duplicating(Event Player)); + Wait(0.016, Ignore Condition); + Set Ultimate Charge(Event Player, Event Player.Abilities[5] * 20); + End; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Team 1 (Ability): Haste Primary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Primary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Primary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Primary Fire))); + } +} + +rule("Team 1 (Ability): Haste Secondary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Secondary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Secondary Fire), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Secondary Fire))); + } +} + +rule("Team 1 (Ability): Haste Ability 1") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 1)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 1))); + } +} + +rule("Team 1 (Ability): Haste Ability 2") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 2)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 2))); + } +} + +rule("Team 1 (Ability): Haste Jump") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Jump)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Jump), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Jump))); + } +} + +rule("Team 1 (Ability): Haste Crouch") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[6] == True; + Ability Cooldown(Event Player, Button(Crouch)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Crouch), (1 - 0.250 * Event Player.Abilities[6]) * Ability Cooldown(Event Player, Button( + Crouch))); + } +} + +rule("Team 1 (Ability): Heavy Impact") +{ + event + { + Player Took Damage; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[7] == True; + } + + actions + { + Abort If(Random Real(-0.020, 1) > Event Damage / Max Health(Event Player)); + Set Status(Event Player, Attacker, Stunned, 1 * Attacker.Abilities[7]); + Wait(5, Ignore Condition); + } +} + +rule("Team 1 (Ability): Binding Heal") +{ + event + { + Player Dealt Healing; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[10] == True; + Healee != Event Player; + } + + actions + { + Set Player Health(Event Player, Health(Event Player) + Event Player.Abilities[10] * 0.250 * Event Healing); + } +} + +rule("Team 1 (Ability): Resilience") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[11] == True; + Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300; + } + + actions + { + Set Damage Received(Event Player, 70); + Wait Until(!(Event Player.Abilities[11] && Normalized Health(Event Player) < Event Player.Abilities[11] * 0.300), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Auto Repair") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.AutoRepair == True; + Global.GateHealth < Global.GateMaxHealth; + } + + actions + { + If(Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2]); + Global.GateHealth += 10 * Global.AutoRepair; + Global.UpgradeGateMaxHealthValue += 10 * Global.AutoRepair; + Else; + Global.GateHealth += 5 * Global.AutoRepair; + Global.UpgradeGateMaxHealthValue += 5 * Global.AutoRepair; + End; + If(Global.GateHealth > Global.GateMaxHealth); + Global.GateHealth = Global.GateMaxHealth; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(5, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ana Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ana), Button(Ability 1)), Custom String( + "Sleep Paralysis: Slept enemies cannot be woken up by damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Ana), Button(Ability 2)), Custom String( + "Multinade: Ana throws multiple Biotic Grenades")); + } +} + +rule("Brigitte Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Brigitte), Button(Ability 1)), Custom String( + "Heavy Iron: Hitting enemies with Whip Flail will root them in pace")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Brigitte), Button(Ultimate)), Custom String( + "Endeavor: Gain a health, damage and speed boost when your barrier breaks")); + } +} + +rule("Mercy Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mercy), Button(Ability 2)), Custom String( + "Angelic blessing: Healing an ally slowly charges their ultimate")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mercy), Button(Ultimate)), Custom String( + "Holy light missiles: Unleash blasts of holy light missiles during valkyrie")); + } +} + +rule("Lúcio Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Lúcio), Button(Secondary Fire)), Custom String( + "Healing Wave: Soundwave heals allies for 30% of their max HP")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Lúcio), Button(Ability 1)), Custom String( + "Reverse Amp: Amp It Up inflicts the opposite effect of the currently played song to enemies")); + } +} + +rule("Moira Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Moira), Button(Secondary Fire)), Custom String( + "Hose: Biotic Grasp primary will damage and push enemies back")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Moira), Button(Ability 2)), Custom String( + "Flourish: Biotic Orbs are 3x more effective")); + } +} + +rule("Baptiste Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String( + "Corrode: Regenerative Burst will damage and poison enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Breakthrough: Immortality Field HP threshold increased to 100%; allies inside gain ultimate")); + } +} + +rule("Ashe Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Ashe), Button(Ability 2)), Custom String( + "Wildfire: Shooting a burning enemy ignites other nearby enemies")); + Event Player.HeroTalentText[2] = Array(Icon String(Fire), Custom String( + "Flare trigger: Coach gun instantly damages all burning enemies")); + } +} + +rule("D.Va Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(D.Va), Button(Secondary Fire)), Custom String( + "Voltage Grid: Defense Matrix will damage and root enemies it's casted over")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(D.Va), Button(Ability 1)), Custom String( + "Shooting Star: Boosters set enemies on fire")); + } +} + +rule("Genji Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Genji), Button(Ability 1)), Custom String( + "Venomous Strike: Swift Strike poisons enemies; heal for poison damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Genji), Button(Ultimate)), Custom String( + "Dragon's Breath: Dragonblade fires large explosive energy charges")); + } +} + +rule("Hanzo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Hanzo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "Stormbreak: Enemies eliminated by hanzo unleash a thundercloud")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Hanzo), Button(Ability 2)), Custom String( + "Punch II: Storm Arrows deal more damage and stun and knockback enemies")); + } +} + +rule("Widowmaker Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Widowmaker; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Widowmaker), Button(Ultimate)), Custom String( + "Kiss Of Death: Scoped critical hits against enemies below 30% health explode and instantly die")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Widowmaker), Button(Ability 2)), Custom String( + "Epidemic: Enemies hurt by Venom Mine unleash toxic pulses; heal for dealt damage")); + } +} + +rule("McCree Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Cassidy), Button(Ability 2)), Custom String( + "Panic: Flashbang puts enemies in fear; deal +120% more damage to enemies in fear")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Cassidy), Button(Ultimate)), Custom String( + "Clocked: Deadeye deals more damage and knocks enemies down")); + } +} + +rule("Reinhardt Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reinhardt), Button(Ability 2)), Custom String( + "Fire Blast: Fire Strike explodes as it deals damage, setting enemies on fire")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reinhardt), Button(Ultimate)), Custom String( + "Epicenter: Earthshatter travels in all directions")); + } +} + +rule("Soldier: 76 Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ultimate)), Custom String( + "Triple Threat: 2 more rockets are fired alongside Helix Rockets")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Soldier: 76), Button(Ability 1)), Custom String( + "Shoulder Check: Sprinting into enemies will damage and tackle them to the ground")); + } +} + +rule("Torbjörn Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Torbjörn), Button(Ability 2)), Custom String( + "Melting point: Unleash heatwaves during overload and molten core")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Torbjörn), Button(Ultimate)), Custom String( + "Roots Of Magma: Enemies trapped in Molten Core blots cannot move")); + } +} + +rule("Tracer Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Tracer), Button(Ability 2)), Custom String( + "Vortex: Recall pulls and roots enemies towards the activation point")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Tracer), Button(Ultimate)), Custom String( + "Chain Reaction: Pulse Bomb creates chain explosions on enemies damaged by it")); + } +} + +rule("Winston Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Winston), Button(Ability 2)), Custom String( + "Blast Barrier: Barrier Projector damages enemies inside the area")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Winston), Button(Ultimate)), Custom String( + "Next Generation: Eliminations during Primal Rage add +15% ultimate charge towards the next")); + } +} + +rule("Pharah Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Pharah; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ability 2)), Custom String( + "Head Trauma: Concussive Blast stuns and damages enemies for 25% of their max health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Pharah), Button(Ability 1)), Custom String( + "Thunderbird: Gain 150 shields and deal 4x the damage to barriers and objects")); + } +} + +rule("Bastion Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Bomblets: Bullets shot during sentry configuration are explosive")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ability 1)), Custom String( + "Tesla: A powerful mounted laser will autmotically attack one enemy at a time")); + } +} + +rule("Doomfist Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Jump)), Custom String( + "Phase Shifter: Immune to damage while any ability is active")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Doomfist), Button(Ultimate)), Custom String( + "Fissure: Meteor Strike leaves a large fissure behind that burns enemies over it")); + } +} + +rule("Echo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Focusing Optics: Focusing Beam damage ramp starts at 90% health")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Streamline: Fire many more sticky bombs per burst")); + } +} + +rule("Junkrat Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Junkrat; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Fire), Custom String("Pyromania: All explosive attacks inflict fire damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Junkrat), Button(Ability 2)), Custom String( + "Short Fused: Steel Trap sets off violent explosions once triggered")); + } +} + +rule("Mei Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Mei), Button(Ultimate)), Custom String( + "Cold Snap: Instantly freeze neaerby enemies once Cryo-Freeze expires")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Mei), Button(Ability 2)), Custom String( + "Icebound: While Ice Wall is up, Icicles freeze and deal much more damage")); + } +} + +rule("Orisa Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Orisa), Button(Ability 1)), Custom String( + "Immovable Object: During Fortify, become immune and convert 50% of taken damage to healing")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Orisa), Button(Secondary Fire)), Custom String( + "Unstoppable Force: Halt! is much larger and pushes enemies. When triggered, it explodes violently")); + } +} + +rule("Reaper Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Reaper), Button(Ability 1)), Custom String( + "shadow streak: shadow step creates a beam that damages enemies who cross")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Reaper), Button(Ultimate)), Custom String( + "Loom: Traumatize enemies in front of you when using Wraith Form")); + } +} + +rule("Roadhog Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Poison), Custom String("Stench: Roadhog constantly damages enemies nearby")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Roadhog), Button(Ability 1)), Custom String( + "Rusted Anchor: Hook deals more damage; Eliminations will reset hook cooldown")); + } +} + +rule("Sigma Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sigma), Button(Ability 1)), Custom String( + "Gravity Well: Kinetic Grasp gives invincibility")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sigma), Button(Ultimate)), Custom String( + "Gravity Channels: Gravitic Flux damages enemies for 75% of max hp instead of 50%")); + } +} + +rule("Sombra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Sombra), Button(Secondary Fire)), Custom String( + "Malware: Enemies hacked or in fear take +100% more damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Sombra), Button(Ultimate)), Custom String( + "Glitch: EMP leaves behind a large hack zone ")); + } +} + +rule("Symmetra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Symmetra; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Icon String(Bolt), Custom String( + "High Voltage: Enemies eliminated by Symmetra explode and damage other enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ultimate)), Custom String( + "Energy Source: While Photon Barrier is active, all players regenerate health and gain ultimate")); + } +} + +rule("Wrecking Ball Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ultimate)), Custom String( + "Mirror Ball: Reflect 100% of taken damage to nearby enemies")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ability 2)), Custom String( + "Distort: Adaptive Shields damages and hacks nearby enemies")); + } +} + +rule("Zarya Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zarya; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Zarya), Button(Ability 1)), Custom String( + "Augment: Health and barrier hp increased by 50%; barrier sized doubled")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Perpetual Energy: secondary inflicts burn damage that continues to last until the enemy dies")); + } +} + +rule("Zenyatta Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + actions + { + Event Player.HeroTalentText[1] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Vigor: The ally under the effect of Harmony Orb is immune to damage")); + Event Player.HeroTalentText[2] = Array(Ability Icon String(Hero(Zenyatta), Button(Ultimate)), Custom String( + "Perfect Balance: Transcendence damages enemies in a large proximity")); + } +} + +rule("Ana: Sleep Paralysis") +{ + event + { + Player Dealt Damage; + Team 1; + Ana; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Black), Victim, 1); + Wait(0.250, Ignore Condition); + Set Status(Victim, Null, Knocked Down, 5); + } +} + +rule("Ana: Multinade") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.AbilityCountdown = 4; + While(Event Player.AbilityCountdown > 0); + Wait(0.030, Ignore Condition); + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Cancel Primary Action(Event Player); + Wait(0.050, Ignore Condition); + Press Button(Event Player, Button(Ability 2)); + Event Player.AbilityCountdown -= 1; + End; + Wait(2, Ignore Condition); + } +} + +rule("Brigitte: Heavy Iron") +{ + event + { + Player Dealt Damage; + Team 1; + Brigitte; + } + + conditions + { + (Event Ability == Button(Primary Fire) || Event Ability == Button(Ability 1)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Victim, 1.500); + Set Status(Victim, Null, Rooted, 0.500); + Set Environment Credit Player(Victim, Event Player); + } +} + +rule("Brigitte: Endeavor") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Ability Cooldown(Event Player, Button(Secondary Fire)) >= 0.100; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Eye Position(Event Player), 15); + Heal(Players Within Radius(Event Player, 15, Team Of(Event Player), Off), Event Player, 200); + Event Player.DamageDealt *= 2.500; + Set Move Speed(Event Player, 100 * 1.750); + Add Health Pool To Player(Event Player, Armor, Max Health(Event Player) / 2, False, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(Is Dead(Event Player), 6); + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Move Speed(Event Player, 100); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Mercy: Angelic Blessing") +{ + event + { + Player Dealt Healing; + All; + Mercy; + } + + conditions + { + Event Player.Abilities[8] == True; + Healee != Event Player; + Normalized Health(Healee) < True; + } + + actions + { + Set Ultimate Charge(Healee, Ultimate Charge Percent(Healee) + 1); + Wait(0.400, Ignore Condition); + } +} + +rule("Mercy: Aurora") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ultimate(Event Player) == True; + } + + actions + { + Wait(1.500, Ignore Condition); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(All Teams), Event Player, True); + Create Beam Effect(All Players(All Teams), Mercy Heal Beam, Event Player, Event Player.Ability_Projectile1, Color(White), + Visible To Position and Radius); + Event Player.Effects_[3] = Last Created Entity; + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 70, Destination and Rate); + While(Event Player.Ability_End != Event Player.Ability_Projectile1); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Event Player.Ability_Projectile1, 1); + Wait(0.032, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[3]); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 120); + Loop If Condition Is True; + } +} + +rule("Lucio: Healing Wave") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4); + Heal(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 4, 4, Team Of(Event Player), Surfaces), + Event Player, Max Health(Filtered Array(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4, Team Of(Event Player), Surfaces), Is Alive(Current Array Element))) * 0.300); + } +} + +rule("Lucio: Reverse Amp") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + If(Is Using Ability 1(Event Player)); + Set Status(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Rooted, 4); + Else; + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 16.250); + End; + Play Effect(All Players(All Teams), Ring Explosion, Is Using Ability 1(Event Player) ? Color(Green) : Color(Yellow), Event Player, + 1); + Wait(0.400, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Hose") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Event Player.Abilities[8] == True; + Ability Resource(Event Player, Button(Primary Fire)) > False; + } + + actions + { + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Facing Direction Of(Event Player), 15, To World, + Cancel Contrary Motion); + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && !Is In Line of Sight(Current Array Element, Event Player, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Up, 8, To World, Cancel Contrary Motion); + Start Damage Over Time(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), + Distance Between(Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS)), Event Player, 1, 15); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Flourish - Damage") +{ + event + { + Player Dealt Damage; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("[Moira] Flourish - Healing") +{ + event + { + Player Dealt Healing; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Heal(Healee, Event Player, Event Healing * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Healee, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("Baptiste: Corrode") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 20); + Wait(0.200, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 12); + } +} + +rule("Baptiste: Breakthrough") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Status(Event Player, Unkillable) == True; + (Event Player.Abilities[12] ? Players On Hero(Hero(Baptiste), Team Of(Event Player)) : Empty Array).Abilities[12] == True; + } + + actions + { + Heal(Event Player, Event Player, 10000); + Set Status(Event Player, Null, Invincible, 0.800); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ashe: Firebourne") +{ + event + { + Player Dealt Damage; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability == Button(Primary Fire); + Has Status(Victim, Burning) == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Null, Burning, 10); + Start Damage Over Time(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Event Player, 10, 15); + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 5); + Wait(0.250, Ignore Condition); + } +} + +rule("Ashe: Taunt") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Damage(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, Burning)), + Event Player, 125); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Frozen, + 0.016); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Stunned, + 2); + } +} + +rule("D.Va: Voltage Grid") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 2, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 5, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 8, 0.500); + Wait(0.300, Ignore Condition); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Wait(0.016, Ignore Condition); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Loop If Condition Is True; + } +} + +rule("D.Va: Shooting Star") +{ + event + { + Player Dealt Knockback; + Team 1; + D.Va; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, 40); + Set Status(Victim, Null, Burning, 3); + Start Damage Over Time(Victim, Event Player, 3, 35); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 1); + } +} + +rule("Genji: Venomous Strike") +{ + event + { + Player Dealt Damage; + Team 1; + Genji; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.Abilities[8] == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 3, 25); + Start Damage Over Time(Victim, Event Player, 3, 25); + Damage(Victim, Event Player, 25); + Heal(Event Player, Event Player, 25); + } +} + +rule("Genji: Dragon's Breath") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is Firing Primary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Good Aura, Color(Lime Green), Event Player.Ability_Projectile1, 1, + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 80, Destination and Rate); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True); + Wait Until(Event Player.Ability_End == Event Player.Ability_Projectile1, 1); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Green), Event Player.Ability_Projectile1, 100); + Play Effect(All Players(All Teams), Bad Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Green), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 100); + } +} + +rule("[Hanzo] Stormbreak (Storm_Effects6)") +{ + event + { + Player Died; + Team 2; + All; + } + + conditions + { + Attacker.Abilities[8] == True; + Hero Of(Attacker) == Hero(Hanzo); + } + + actions + { + Event Player.Storm_Projectile = Eye Position(Event Player); + Event Player.Storm_EndPoint = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Up * 12, Null, + All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Storm_Projectile, Event Player.Storm_EndPoint, 4, Destination and Rate); + Create Effect(All Players(All Teams), Cloud, Color(White), Vector(False, -0.500, False) + Event Player.Storm_Projectile, 4, + Visible To Position and Radius); + Event Player.Storm_Effects[3] = Last Created Entity; + Create Effect(All Players(All Teams), Bad Aura, Color(White), Event Player.Storm_Projectile, 3, Visible To Position and Radius); + Event Player.Storm_Effects[4] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(White), Event Player.Storm_Projectile, 3.500, Visible To Position and Radius); + Event Player.Storm_Effects[5] = Last Created Entity; + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Storm_Projectile, Ray Cast Hit Position( + Event Player.Storm_Projectile, Vector(0.100, 0, 0) + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), + False), Color(Aqua), Visible To Position and Radius); + Event Player.Storm_Effects[6] = Last Created Entity; + While(Distance Between(Event Player.Storm_Projectile, Event Player.Storm_EndPoint) > 1); + Wait(0.600, Ignore Condition); + Damage(Players Within Radius(Ray Cast Hit Position(Event Player.Storm_Projectile, Event Player.Storm_Projectile + Down * 1000, + Null, All Players(All Teams), False), 3, Team Of(Event Player), Surfaces), Attacker, 50); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Ray Cast Hit Position(Event Player.Storm_Projectile, + Event Player.Storm_Projectile + Down * 1000, Null, All Players(All Teams), False), 3); + End; + Destroy Effect(Event Player.Storm_Effects[3]); + Destroy Effect(Event Player.Storm_Effects[4]); + Destroy Effect(Event Player.Storm_Effects[5]); + Destroy Effect(Event Player.Storm_Effects[6]); + } +} + +rule("Hanzo: Punch II") +{ + event + { + Player Dealt Damage; + Team 1; + Hanzo; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + Hero Of(Victim) != Hero(Torbjörn); + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.800); + Apply Impulse(Victim, Facing Direction Of(Event Player), 12, To World, Cancel Contrary Motion); + Apply Impulse(Victim, Up, 5, To World, Cancel Contrary Motion); + Set Environment Credit Player(Victim, Event Player); + Set Status(Victim, Null, Stunned, 1); + } +} + +rule("Widowmaker: Kiss Of Death") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + (Normalized Health(Victim) <= 0.300 || Event Damage >= Normalized Health(Victim) + Event Damage) == True; + Is Firing Secondary(Event Player) == True; + Event Ability == Button(Primary Fire); + Event Player.Abilities[8] == True; + Event Damage >= 40; + Event Was Critical Hit == True; + } + + actions + { + Kill(Victim, Event Player); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 2), Victim, 3); + Damage(Players Within Radius(Victim, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage * 1.500); + } +} + +rule("Widowmaker: Epidemic") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 8); + Play Effect(All Players(All Teams), Good Explosion, Color(Purple), Victim, 4); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Victim, 16); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Victim, 3); + Start Damage Over Time(Players Within Radius(Victim, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, 50); + Start Heal Over Time(Event Player, Event Player, 3, 50); + Wait(0.500, Ignore Condition); + } +} + +rule("McCree: Panic") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Victim.Feared_until = Total Time Elapsed + 3.500; + } +} + +rule("McCree: Panic - Damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), + Event Player.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 220, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("McCree: Clocked") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Damage(Victim, Event Player, Event Damage * 1.500); + Set Status(Victim, Null, Knocked Down, 3); + } +} + +rule("Reinhardt: Fire Blast") +{ + event + { + Player Dealt Damage; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Start Damage Over Time(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, 20); + Set Status(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Burning, 5); + } +} + +rule("Reinhardt: Epicenter") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is On Ground(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, Knocked Down, 2.500); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 10); + Damage(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, 50); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 20); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 30); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 40); + Wait(5, Ignore Condition); + } +} + +rule("[Soldier: 76] Rocket Assault Rifle") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile2 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(-2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Projectile1 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.Ability_Position = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, + 0), Event Player, Rotation); + Event Player.Ability_End = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, 0), + Event Player, Rotation); + Chase Player Variable At Rate(Event Player, Ability_Position, Event Player.Ability_Projectile1, 60, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_End, Event Player.Ability_Projectile2, 60, Destination and Rate); + Wait Until(Event Player.Ability_Position == 0 && Event Player.Ability_End == 0, 2.500); + } +} + +rule("[Soldier: 76] First Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile1 != Event Player.Ability_Position; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_Position, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_Position, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_Position, 2.500); + Stop Chasing Player Variable(Event Player, Ability_Position); + Wait(0.016, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 80); + Stop Chasing Player Variable(Event Player, Ability_Position); + Event Player.Ability_Position = 0; + Event Player.Ability_Projectile1 = 0; + Wait(0.016, Ignore Condition); + } +} + +rule("[Soldier: 76] Second Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.Ability_Projectile2 != Event Player.Ability_End; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.Ability_End, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.Ability_End, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_End, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.Ability_End, 2.500); + Stop Chasing Player Variable(Event Player, Ability_End); + Damage(Players Within Radius(Event Player.Ability_End, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Event Player.Ability_End = 0; + Event Player.Ability_Projectile2 = 0; + } +} + +rule("Soldier: 76 - Init rockets") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Event Player.Ability_Projectile1 = Event Player.Ability_Position; + Event Player.Ability_Projectile2 = Event Player.Ability_End; + } +} + +rule("[Soldier: 76] Shoulder Check") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 3; + Is Alive(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) == True; + } + + actions + { + Damage(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Event Player, 55); + Set Status(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Null, Knocked Down, 1.500); + Apply Impulse(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Facing Direction Of(Event Player), 15, + To World, Cancel Contrary Motion); + Apply Impulse(Event Player, Vector(0, 8, 15), 15, To Player, Cancel Contrary Motion); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Closest Player To(Event Player, Opposite Team Of(Team Of( + Event Player))), 1); + Set Ability Cooldown(Event Player, Button(Melee), 0); + Press Button(Event Player, Button(Melee)); + Wait(1, Ignore Condition); + } +} + +rule("Torbjorn: Melting Point") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Event Player.Abilities[8] == True; + (Is Using Ability 2(Event Player) || Is Using Ultimate(Event Player)) == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Event Player, 8); + Play Effect(All Players(All Teams), Bad Explosion, Color(Yellow), Event Player, 8); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 16); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, + 25); + Set Status(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Off), Null, Burning, 3); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player, 100); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Torbjorn: Roots of Magma") +{ + event + { + Player Dealt Damage; + Team 1; + Torbjörn; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Set Status(Victim, Null, Rooted, 1); + Wait(1, Ignore Condition); + } +} + +rule("Tracer: Vortex") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, 0); + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 10); + Play Effect(All Players(All Teams), Ring Explosion, Color(Red), Position Of(Event Player), 24); + Play Effect(All Players(All Teams), Ring Explosion, Color(Yellow), Position Of(Event Player), 18); + Play Effect(All Players(All Teams), Ring Explosion, Color(Green), Position Of(Event Player), 12); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player), 6); + Set Environment Credit Player(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player); + } +} + +rule("Tracer: Vortex 2") +{ + event + { + Player Received Healing; + Team 2; + All; + } + + conditions + { + Healer.Abilities[8] == True; + Hero Of(Healer) == Hero(Tracer); + Is Using Ability 2(Healer) == True; + Event Ability == Null; + Event Damage <= 20; + } + + actions + { + Apply Impulse(Event Player, Up, 5, To World, Cancel Contrary Motion); + Wait(0.100, Ignore Condition); + Apply Impulse(Event Player, Direction Towards(Event Player, Healer), Distance Between(Event Player, Healer) * 3.500, To World, + Cancel Contrary Motion); + Set Status(Event Player, Null, Rooted, 1.300); + } +} + +rule("Tracer: Chain Reaction") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is True For Any(Filtered Array(All Players(Team Of(Event Player)), Current Array Element.Chain_Reaction_On), Distance Between( + Event Player, Current Array Element) <= 8 && True) == True; + Event Player.Chain_Reaction_Immune == False; + Event Player.Chain_Reaction_On == False; + Is Alive(Event Player) == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Event Player.Chain_Reaction_On = True; + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player, 3); + } +} + +rule("Tracer: Chain Reaction 2") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Event Player.Chain_Reaction_On == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Aqua), Event Player, 3); + Damage(Event Player, Players On Hero(Hero(Tracer), Opposite Team Of(Team Of(Event Player))), 200); + Wait(0.500, Ignore Condition); + Event Player.Chain_Reaction_Immune = True; + Event Player.Chain_Reaction_On = False; + Wait(2, Ignore Condition); + Event Player.Chain_Reaction_Immune = False; + } +} + +rule("Tracer: Chain Reaction 3") +{ + event + { + Player Dealt Damage; + Team 1; + Tracer; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Damage > 20; + Event Player.Abilities[12] == True; + } + + actions + { + Victim.Chain_Reaction_On = True; + } +} + +rule("[Winston] Electric Field") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 65); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Orb, Color(White), Event Player.Ability_Projectile1, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Stop Chasing Player Variable(Event Player, Ability_Resource); + Event Player.Ability_Projectile1 = Eye Position(Event Player); + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Down * 1000, Null, + All Players(All Teams), False); + Wait(0.100, Ignore Condition); + Event Player.Ability_Resource = 5; + Wait(0.250, Ignore Condition); + Chase Player Variable At Rate(Event Player, Ability_Resource, 20, 7, Destination and Rate); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, Event Player.Ability_Resource, + Destination and Rate); + Wait(8.650, Restart When True); + Event Player.Ability_Active = False; + } +} + +rule("[Winston] Electric Field 2") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Event Player.Ability_Projectile1, 5); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 33); + Play Effect(All Players(All Teams), Ring Explosion, Color(Blue), Event Player.Ability_Projectile1, 10); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + Damage(Players Within Radius(Event Player.Ability_Projectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 80); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Event Player.Ability_Projectile1, 12); + Destroy Effect(Event Player.Effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player.Ability_Projectile1, 125); + } +} + +rule("Winston: Next Generation") +{ + event + { + Player Earned Elimination; + Team 1; + Winston; + } + + conditions + { + Ultimate Charge Percent(Event Player) <= 80; + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 15); + } +} + +rule("Pharah: Head Trauma") +{ + event + { + Player Dealt Knockback; + Team 1; + Pharah; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Victim != Event Player; + } + + actions + { + Damage(Victim, Event Player, Max Health(Victim) * 0.300); + Set Status(Victim, Event Player, Knocked Down, 1); + Play Effect(All Players(All Teams), Good Explosion, Color(Team 1), Victim, 1); + } +} + +rule("Pharah: Thunderbird") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[12] == True; + Hero Of(Event Player) == Hero(Pharah); + } + + actions + { + Event Player.DamageDealt *= 4; + Start Damage Modification(All Players(All Teams), Event Player, 25, Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Add Health Pool To Player(Event Player, Shields, 150, True, True); + Event Player.HP_Pool[1] = Last Created Health Pool; + Wait Until(!Event Player.Abilities[12] || Hero Of(Event Player) != Hero(Pharah), 99999); + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Stop Damage Modification(Event Player.Modification_Damage[1]); + Remove Health Pool From Player(Event Player.HP_Pool[1]); + } +} + +rule("Orisa: Unstoppable Force") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Direction = Facing Direction Of(Event Player); + Event Player.Ability_Active = True; + Create Effect(All Players(All Teams), Sphere, Color(Green), Event Player.Ability_Projectile1, 4, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Projectile1 = Eye Position(Event Player) + Facing Direction Of(Event Player) * 0.500; + Event Player.Ability_End = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 100, Null, All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, Ability_Projectile1, Event Player.Ability_End, 25, Destination and Rate); + Wait(0.250, Ignore Condition); + Wait Until((!Event Player.Gen_Available && Is Button Held(Event Player, Button(Secondary Fire))) || ( + Event Player.Ability_Projectile1 == Event Player.Ability_End), 99999); + Stop Chasing Player Variable(Event Player, Ability_Projectile1); + Wait(0.500, Ignore Condition); + Damage(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, + 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Lime Green), Event Player.Ability_Projectile1, 5); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Orisa: Availability for Halt!") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Gen_Available = True; + Wait Until(!Is Button Held(Event Player, Button(Secondary Fire)), 99999); + Event Player.Gen_Available = False; + } +} + +rule("Orisa: Drag effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Player.Ability_Active == True; + } + + actions + { + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Is Alive(Event Player) ? Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of( + Event Player)), Surfaces) : Empty Array, Event Player.Ability_Projectile1), 8, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Event Player.Ability_Projectile1, Event Player.Ability_End), 20, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.Ability_Projectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Up, 5, + To Player, Cancel Contrary Motion); + Wait(0.200, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Orisa: Immoveable Object - Reduce dmg") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Damage Received(Event Player, 100 * 0.003); + Wait Until(!Is Using Ability 1(Event Player), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Orisa: Immovable Object - Healing") +{ + event + { + Player Took Damage; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Heal(Event Player, Null, Event Damage * 3); + } +} + +rule("[Reaper] Shadow Streak (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Event Player.Ability_Position = Position Of(Event Player) + Vector(0, 1, 0); + Wait(2, Abort When False); + Event Player.Ability_End = Position Of(Event Player) + Vector(0, 1, 0); + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.Ability_End, Event Player.Ability_Position, Color(Black), + Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player) || Is Using Ability 2(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage start to end (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players(Opposite Team Of(Team Of( + Event Player))), Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_Position, + Event Player.Ability_End, All Living Players(All Teams), Event Player, True), 1); + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_Position, Event Player.Ability_End, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage end to start (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.Abilities[8] == True; + Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Players(Opposite Team Of(Team Of(Event Player))), + Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.Ability_Active == True; + } + + actions + { + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.Ability_End, Event Player.Ability_Position, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.Ability_End, + Event Player.Ability_Position, All Living Players(All Teams), Event Player, True), 1); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Reaper: Loom") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Hacked, 1.500); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Rooted, 1.500); + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Event Player, 45); + } +} + +rule("Sigma: Gravity Well") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, 25); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Null, Rooted, 2); + Set Status(Event Player, Null, Invincible, 1); + Play Effect(Event Player, Ring Explosion, Color(Blue), Eye Position(Event Player), 50); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Sigma: Gravity Channels") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ultimate(Event Player)), Event Player, 150, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[12], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Echo: Focusing Optics") +{ + event + { + Player Dealt Damage; + Team 1; + Echo; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.Abilities[8] == True; + Normalized Health(Victim) > 0.500; + Normalized Health(Victim) <= 0.900; + Is Duplicating(Event Player) == False; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 3); + Play Effect(All Players(All Teams), Bad Explosion, Color(Violet), Victim, 0.500); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Wait(0.700, Abort When False); + Cancel Primary Action(Event Player); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Set Projectile Speed(Event Player, 100); + Wait(0.150, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Bomblets") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Is In Alternate Form(Event Player) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Orange), Null + Ray Cast Hit Position(Eye Position(Event Player), + Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, All Living Players(Opposite Team Of(Team Of( + Event Player))), All Players(Team Of(Event Player)), True), 2); + Damage(Players Within Radius(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 2, + Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 12); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Taser - Loop damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is True For Any(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive(Current Array Element) + && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status(Current Array Element, + Phased Out) && Distance Between(Event Player, Current Array Element) <= 25) == True; + Is Alive(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Explosion Sound, Color(White), Event Player.Ability_Player, 80); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Event Player.Ability_Player, 1); + Event Player.Ability_Player = Filtered Array(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive( + Current Array Element) && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status( + Current Array Element, Phased Out) && Distance Between(Event Player, Current Array Element) <= 25); + Damage(Players Within Radius(Event Player.Ability_Player, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 30); + Wait(0.450, Ignore Condition); + Loop If Condition Is True; + Event Player.Ability_Player = Null; + } +} + +rule("Bastion: Taser - Visual beam") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player + Vector(False, 1, False), + Event Player.Ability_Player != Null ? Event Player.Ability_Player : Event Player, Color(Aqua), + Visible To Position Radius and Color); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[12], 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Sombra: Malware") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, + Hacked) || Current Array Element.Feared_until >= Total Time Elapsed), All Players(Team Of(Event Player)), 200, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8], 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Sombra: Glitch") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Event Player.Ability_Active = True; + Event Player.Ability_Position = Position Of(Event Player); + Create Effect(All Players(All Teams), Sphere, Color(Purple), Event Player.Ability_Position, 15, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait(8, Ignore Condition); + Destroy Effect(Event Player.Effects_[1]); + Event Player.Ability_Active = False; + } +} + +rule("Sombra: Glitch - Loop") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.Ability_Active == True; + } + + actions + { + Set Status(Players Within Radius(Event Player.Ability_Position, 15, Opposite Team Of(Team Of(Event Player)), Off), Null, Hacked, + 0.750); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Mei: Cold Snap") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Event Player.Abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Event Player, 1, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Is Using Ability 1(Event Player), 99999); + Destroy Effect(Event Player.Effects_[1]); + Damage(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Frozen, 2); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Rooted, 2); + Play Effect(All Players(All Teams), Ring Explosion, Color(White), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Sky Blue), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player) + Vector(0, 1, 0), 20); + } +} + +rule("Mei: Icebound") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Is Firing Secondary(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Aqua), Event Player, 0.400, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Set Projectile Speed(Event Player, 200); + Wait Until(!Is Firing Secondary(Event Player), 99999); + Destroy Effect(Event Player.Effects_[2]); + Set Projectile Speed(Event Player, 100); + } +} + +rule("Mei: Icebound - Icicles hit") +{ + event + { + Player Dealt Damage; + Team 1; + Mei; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Is Using Ability 2(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 1.250); + Set Status(Victim, Null, Frozen, 1); + Set Status(Victim, Null, Rooted, 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Victim, 1); + } +} + +rule("Wrecking Ball: Mirror Ball") +{ + event + { + Player Took Damage; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 4.500, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage); + Wait(0.100, Ignore Condition); + } +} + +rule("Wrecking Ball: Distort") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.Abilities[12] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Set Status(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Hacked, Count Of( + Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces)) * 1.500); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Violet), Position Of(Event Player), 125); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Sound, Color(Purple), Position Of(Event Player), 16); + Play Effect(All Players(All Teams), Explosion Sound, Color(Violet), Position Of(Event Player), 80); + } +} + +rule("Symmetra: High voltage") +{ + event + { + Player Dealt Final Blow; + Team 1; + Symmetra; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Victim, 10); + Play Effect(All Players(All Teams), Bad Explosion, Color(Aqua), Victim, 8); + Damage(Players Within Radius(Victim, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 150); + } +} + +rule("Symmetra: Energy Source") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is True For Any(Players On Hero(Hero(Symmetra), Team Of(Event Player)), Is Using Ultimate(Current Array Element) + && Current Array Element.Abilities[12]) == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 1, 40); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Event Player, 0.100); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Junkrat: Pyromania") +{ + event + { + Player Dealt Knockback; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[8] == True; + Event Ability != Button(Melee); + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 2, 30); + Set Status(Victim, Null, Burning, 2); + } +} + +rule("Junkrat: Short Fused") +{ + event + { + Player Dealt Damage; + Team 1; + Junkrat; + } + + conditions + { + Event Player.Abilities[12] == True; + Event Ability == Button(Ability 2); + } + + actions + { + Event Player.Ability_Countdown = 4; + While(Event Player.Ability_Countdown > 0); + Event Player.Ability_Countdown -= 1; + Event Player.Ability_Position = Position Of(Victim) + Vector(Random Real(-2, 2), Random Real(-2, 2), Random Real(-2, 2)); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.Ability_Position, 4); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.Ability_Position, 4); + Damage(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 35); + Set Status(Players Within Radius(Event Player.Ability_Position, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player, Stunned, 0.800); + Wait(0.200, Ignore Condition); + End; + } +} + +rule("Zenyatta: Vigor") +{ + event + { + Player Dealt Healing; + Team 1; + Zenyatta; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Healee, Null, Invincible, 1); + Wait(0.800, Ignore Condition); + } +} + +rule("Zenyatta: Perfect Balance") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Over Time(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 0.750, 200); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player, 24); + Wait(0.600, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Stench") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Violet), Event Player, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Destroy Effect(Event Player.Effects_[1]); + } +} + +rule("Roadhog: Stench effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 8; + Event Player.Abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 9); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Rusted Anchor") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ability 1(Event Player)), Event Player, 400, + Receivers Damagers and Damage Percent); + Event Player.Modification_Damage[1] = Last Damage Modification ID; + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Stop Damage Modification(Event Player.Modification_Damage[1]); + } +} + +rule("Roadhog: Rusted Anchor - Reset cooldown") +{ + event + { + Player Earned Elimination; + Team 1; + Roadhog; + } + + conditions + { + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ability 1(Event Player), 3); + Set Ability Cooldown(Event Player, Button(Ability 1), False); + } +} + +rule("Zarya: Augment") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[8] == True; + } + + actions + { + Start Scaling Barriers(Event Player, 2, True); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5 + 50; + Set Max Health(Event Player, Event Player.PlayerHealth); + Wait Until(!Event Player.Abilities[8] || Hero Of(Event Player) != Hero(Zarya), 99999); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Stop Scaling Barriers(Event Player); + } +} + +rule("Zarya: Perpetual Energy") +{ + event + { + Player Dealt Knockback; + Team 1; + Zarya; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Event Player.Abilities[12] == True; + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 9999, 15); + Set Status(Victim, Null, Burning, 9999); + } +} + +rule("Doomfist: Phase Shifter") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + (Is Firing Secondary(Event Player) || Is Using Ability 1(Event Player) || Is Using Ability 2(Event Player)) == True; + Event Player.Abilities[8] == True; + } + + actions + { + Set Status(Event Player, Null, Phased Out, 1); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.Abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ultimate(Event Player), 99999); + Event Player.Ability_Position = Position Of(Event Player); + Event Player.Ability_Active = True; + Wait Until(Is Dead(Event Player), 8); + Event Player.Ability_Active = False; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Event Player.Ability_Active == True; + Event Player.Abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[1] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(Orange), Event Player.Ability_Position, 8, Visible To Position and Radius); + Event Player.Effects_[2] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player.Ability_Position, 16); + While(Event Player.Ability_Active == True); + Damage(Players Within Radius(Event Player.Ability_Position, 8, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 34); + Wait(0.235, Ignore Condition); + End; + Destroy Effect(Event Player.Effects_[1]); + Destroy Effect(Event Player.Effects_[2]); + } +} + +rule("Team 1 (Perk): Sharpshooter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Global.Perk[0] == True; + Event Ability != Null; + Distance Between(Event Player, Victim) >= 10; + } + + actions + { + Damage(Victim, Event Player, 50 / Event Player.DamageDealt * Event Damage); + } +} + +rule("Team 1 (Perk): Bulletstorm") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.Perk[1] == True; + (Ammo(Event Player, 0) < Max Ammo(Event Player, 0) || Ammo(Event Player, 1) < Max Ammo(Event Player, 1)) == True; + } + + actions + { + Set Ammo(Event Player, 0, 1000); + Set Ammo(Event Player, 1, 1000); + } +} + +rule("Team 1 Challenges") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + If(Global.Perk[2] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[17] = Last Text ID; + End; + If(Global.Perk[0] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[18] = Last Text ID; + End; + If(Global.Perk[1] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.AbilityHUD[19] = Last Text ID; + End; + If(Global.MaxHealthDone == 50); + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + End; + } +} + +rule("Remove Auto Repair when Player leaves") +{ + event + { + Player Left Match; + Team 1; + All; + } + + actions + { + Global.AutoRepair -= Event Player.Abilities[16]; + } +} + +rule("Refund") +{ + event + { + Subroutine; + Refund; + } + + actions + { + "Refund Money" + Event Player.Money[0] += Event Player.Money[1]; + Event Player.Money[1] = 0; + "Reset Headhunter" + Event Player.Abilities[1] = 0; + "Reset Ambush" + Event Player.Abilities[2] = 0; + "Reset QuickFix" + Event Player.Abilities[3] = 0; + "Reset HeavyWeight" + Event Player.Abilities[4] = 0; + "Reset Charged" + Event Player.Abilities[5] = 0; + "Reset Haste" + Event Player.Abilities[6] = 0; + "Reset HeavyImpact" + Event Player.Abilities[7] = 0; + "Reset HeroTalent1" + Event Player.Abilities[8] = 0; + "Reset SecondWind" + Event Player.Abilities[9] = 0; + "Reset BindingHeal" + Event Player.Abilities[10] = 0; + "Reset Resilience" + Event Player.Abilities[11] = 0; + "Reset HeroTalent2" + Event Player.Abilities[12] = 0; + "Reset Damage" + Event Player.Abilities[13] = 0; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + "Reset Health" + Event Player.Abilities[14] = 0; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + If(Global.MaxHealthDone == 0); + End; + "Reset Healing" + Event Player.Abilities[15] = 0; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + "Reset AutoRepair" + Global.AutoRepair -= Event Player.Abilities[16]; + Event Player.Abilities[16] = 0; + } +} + +rule("Lucio Dash HUD Creation") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + } + + actions + { + If(Event Player.Lucio_Dash_Active == False); + Event Player.Lucio_Dash_Active = True; + Create HUD Text(Event Player, Null, Null, Custom String("{0} Slam on ground - Press: {1}", Ability Icon String(Hero(Wrecking Ball), + Button(Crouch)), Input Binding String(Button(Crouch))), Left, 1000, Color(White), Color(White), Color(White), + Visible To and String, Default Visibility); + Event Player.Lucio_Dash_Icon = Last Text ID; + End; + } +} + +rule("Lucio Dash Remove HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) != Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + } + + actions + { + Destroy HUD Text(Event Player.Lucio_Dash_Icon); + Event Player.Lucio_Dash_Active = False; + } +} + +rule("Lucio Dash") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + Event Player.Lucio_Dash_Active == True; + Is On Ground(Event Player) == False; + Is Button Held(Event Player, Button(Crouch)) == True; + } + + actions + { + Apply Impulse(Event Player, Down, 20, To World, Cancel Contrary Motion); + } +} + +rule("Ana Self-Nano") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + Ultimate Charge Percent(Event Player) == 100; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Abort If(Global.SelfNanoWorkshopSetting == False && Number Of Players(Team 1) > 1); + Wait(0.100, Ignore Condition); + If(Is Using Ultimate(Event Player) == False); + Create Dummy Bot(Hero(Ana), Team Of(Event Player), -1, Position Of(Event Player) + Backward, Eye Position(Event Player)); + Event Player.AnaEntityID = Last Created Entity; + Wait(0.100, Ignore Condition); + Set Ultimate Charge(Event Player.AnaEntityID, 100); + Start Facing(Event Player.AnaEntityID, Direction Towards(Eye Position(Event Player.AnaEntityID), Position Of(Event Player) + Up), + 1000, To World, Direction and Turn Rate); + Set Invisible(Event Player.AnaEntityID, All); + Set Status(Event Player.AnaEntityID, Null, Phased Out, 9999); + Wait(0.150, Ignore Condition); + Press Button(Event Player.AnaEntityID, Button(Ultimate)); + Set Ultimate Charge(Event Player, 0); + Wait(0.150, Ignore Condition); + Teleport(Event Player.AnaEntityID, Position Of(First Of(Spawn Points(Team Of(Event Player))))); + Wait(10, Ignore Condition); + Destroy Dummy Bot(Team Of(Event Player), Slot Of(Event Player.AnaEntityID)); + End; + } +} + +rule("Reinhard Charge Cancel") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + } + + actions + { + Wait(0.600, Ignore Condition); + Wait Until(Is Button Held(Event Player, Button(Ability 1)), 5); + Set Status(Event Player, Null, Rooted, 0.001); + Wait Until(Event Player.ReinPin, 1); + If(Event Player.ReinPin != 0); + Apply Impulse(Event Player.ReinPin, Facing Direction Of(Event Player), 15, To World, Cancel Contrary Motion); + End; + } +} + +disabled rule("Map Editor Walls") +{ + event + { + Ongoing - Global; + } +} + +rule("Initial Global") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Empty Array; + Global.AllDir = Empty Array; + Global.firstpos = Empty Array; + Global.secondpos = Empty Array; + Global.firstpoint2 = Empty Array; + Global.secondpoint2 = Empty Array; + Global.second = Empty Array; + Global.z = Empty Array; + Global.Wall_ID = Empty Array; + Global.g_beamType = Empty Array; + } +} + +rule("Initial Player") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.filterpos = 0; + Event Player.lastsavedpos = 0; + Event Player.closestbodypos = 0; + Event Player.fullbodypos = 0; + Event Player.prevpos_intersection = 0; + Event Player.active_wall = Empty Array; + Event Player.closestwall = Empty Array; + } +} + +rule("Collision Logic") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Event Player.lastsavedpos = (Eye Position(Event Player) + Position Of(Event Player)) / 2; + Wait(0.016, Ignore Condition); + Event Player.closestwall = Filtered Array(Global.AllPos, Distance Between(Global.AllPos[Current Array Index], Event Player) + <= Distance Between(Global.AllPos[Current Array Index], Global.firstpos[Current Array Index]) + || Event Player.active_wall[Current Array Index] == 1 || (Dot Product(Direction Towards(Current Array Element, + Event Player.lastsavedpos), Global.AllDir[Current Array Index]) > 0) != (Dot Product(Direction Towards(Current Array Element, + Event Player), Global.AllDir[Current Array Index]) > 0)); + For Player Variable(Event Player, x, 0, Count Of(Event Player.closestwall), 1); + Global.z = Index Of Array Value(Global.AllPos, Event Player.closestwall[Event Player.x]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3 || Global.Wall_ID[Global.z] == 5); + If(Y Component Of(Global.firstpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.firstpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.firstpos[Global.z]; + Else If(Y Component Of(Global.secondpos[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.secondpos[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestbodypos = Global.secondpos[Global.z]; + Else; + Event Player.closestbodypos = Position Of(Event Player); + End; + Event Player.fullbodypos = Vector(X Component Of(Eye Position(Event Player)), Y Component Of(Event Player.closestbodypos), + Z Component Of(Eye Position(Event Player))); + Event Player.filterpos = Event Player.fullbodypos + Global.AllDir[Global.z] * Dot Product( + Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) / Dot Product(Global.AllDir[Global.z], + Global.AllDir[Global.z]); + If(Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3); + If((Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.lastsavedpos), Global.AllDir[Global.z]) > 0) != ( + Dot Product(Direction Towards(Global.AllPos[Global.z], Event Player.fullbodypos), Global.AllDir[Global.z]) > 0)); + Event Player.intersection_length = Dot Product(Global.AllPos[Global.z] - Event Player.fullbodypos, Global.AllDir[Global.z]) + / Dot Product(Direction Towards(Event Player.lastsavedpos, Event Player.fullbodypos), Global.AllDir[Global.z]); + Event Player.prevpos_intersection = Event Player.fullbodypos + Direction Towards(Event Player.lastsavedpos, + Event Player.fullbodypos) * Vector(1, Empty Array, 1) * Event Player.intersection_length; + If(Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of( + Global.firstpos[Global.z]), Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], + Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of( + Global.firstpos[Global.z]), Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), + Direction Towards(Global.firstpos[Global.z], Event Player.prevpos_intersection)) >= 0 && Dot Product(Direction Towards( + Global.secondpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.prevpos_intersection)) + >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.secondpos[Global.z], Event Player.prevpos_intersection)) >= 0); + Cancel Primary Action(Event Player); + Teleport(Event Player, Event Player.prevpos_intersection + Direction Towards(Event Player.prevpos_intersection, + Event Player.lastsavedpos) * Vector(1, Empty Array, 1) * 2); + End; + End; + End; + Event Player.thickness = 0; + If(Global.Wall_ID[Global.z] == 5); + Event Player.thickness = 4; + Else; + Event Player.thickness = 1; + End; + If(Distance Between(Event Player.fullbodypos, Event Player.filterpos) <= Event Player.thickness && Dot Product(Direction Towards( + Global.firstpos[Global.z], Vector(X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), + Z Component Of(Global.secondpos[Global.z]))), Direction Towards(Global.firstpos[Global.z], Event Player.filterpos)) + >= 0 && Dot Product(Direction Towards(Global.firstpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), + Y Component Of(Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards( + Global.firstpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product(Direction Towards(Global.secondpos[Global.z], Vector( + X Component Of(Global.secondpos[Global.z]), Y Component Of(Global.firstpos[Global.z]), Z Component Of( + Global.secondpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], Event Player.filterpos)) >= 0 && Dot Product( + Direction Towards(Global.secondpos[Global.z], Vector(X Component Of(Global.firstpos[Global.z]), Y Component Of( + Global.secondpos[Global.z]), Z Component Of(Global.firstpos[Global.z]))), Direction Towards(Global.secondpos[Global.z], + Event Player.filterpos)) >= 0); + If(!Global.is_Grounded); + Set Gravity(Event Player, 100); + End; + If(Event Player.active_wall[Global.z] == False); + Event Player.active_wall[Global.z] = 1; + If((Global.Wall_ID[Global.z] == 1 || Global.Wall_ID[Global.z] == 3) && Global.is_Grounded == False); + Set Gravity(Event Player, 100); + Else If(Global.Wall_ID[Global.z] == 5); + Disable Movement Collision With Environment(Event Player, False); + End; + End; + If(Global.Wall_ID[Global.z] == 1); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos) * Vector(1, Empty Array, 1), 0.001, + To World, Cancel Contrary Motion); + Set Move Speed(Event Player, 100 - Dot Product(Direction Towards(Eye Position(Event Player), Eye Position(Event Player) + + World Vector Of(Throttle Of(Event Player), Event Player, Rotation)), Direction Towards(Event Player.filterpos, + Event Player.fullbodypos) * -1) * 100); + Else If(Global.Wall_ID[Global.z] == 3); + Apply Impulse(Event Player, Direction Towards(Event Player.filterpos, Event Player.fullbodypos), Speed Of(Event Player), To World, + Cancel Contrary Motion); + End; + Else; + Event Player.active_wall[Global.z] = 0; + Set Move Speed(Event Player, 100); + End; + End; + End; + Loop; + } +} + +rule("Reset") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Count Of(Filtered Array(Event Player.active_wall, Current Array Element != 0)) == 0; + } + + actions + { + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("Effect Creation") +{ + event + { + Ongoing - Global; + } + + actions + { + Wait(5, Ignore Condition); + If(Global.showwalls); + For Global Variable(x, 0, Count Of(Global.AllPos), 1); + If(Global.Wall_ID[Global.x] == 5); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Else; + Skip(Array(14, 0, 5, 10)[Index Of Array Value(Array(1, 2, 3), Global.g_beamType[Global.x]) + 1]); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(9); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(4); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x], Vector(X Component Of(Global.secondpos[Global.x]), + Y Component Of(Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.secondpos[Global.x]), Y Component Of( + Global.firstpos[Global.x]), Z Component Of(Global.secondpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.firstpos[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.firstpos[Global.x]), Y Component Of(Global.secondpos[Global.x]), Z Component Of( + Global.firstpos[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.firstpos[Global.x]), Y Component Of( + Global.secondpos[Global.x]), Z Component Of(Global.firstpos[Global.x])), Global.secondpos[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + End; + Wait(0.016, Ignore Condition); + End; + End; + } +} + +rule("Wall Data") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.AllPos = Array(Vector(155.968, 12.470, -30.507), Vector(155.962, 12.472, -62.500), Vector(81.153, 6.453, -103.851), Vector( + 69.148, 6.474, -104.548)); + Global.AllDir = Array(Vector(-1, 0, -0.002), Vector(1, 0, -0.001), Vector(0, 0, 1), Vector(0.001, 0, 1)); + Global.firstpos = Array(Vector(155.971, 11.047, -31.771), Vector(155.964, 11.050, -61.229), Vector(79.761, 5.030, -103.852), + Vector(67.738, 5.022, -104.547)); + Global.secondpos = Array(Vector(155.965, 13.894, -29.242), Vector(155.960, 13.894, -63.771), Vector(82.544, 7.876, -103.851), + Vector(70.558, 7.925, -104.550)); + Global.firstpoint2 = Array(Vector(155.971, 13.894, -31.771), Vector(155.964, 13.894, -61.229), Vector(79.761, 7.876, -103.852), + Vector(67.738, 7.925, -104.547)); + Global.secondpoint2 = Array(Vector(155.965, 11.047, -29.242), Vector(155.960, 11.050, -63.771), Vector(82.544, 5.030, -103.851), + Vector(70.558, 5.022, -104.550)); + Global.z = 3; + Global.g_beamType = Array(1, 1, 1, 1); + Global.showwalls = True; + Global.Wall_ID = Array(5, 5, 5, 5); + } +} + +disabled rule("NEW SHOP") +{ + event + { + Ongoing - Global; + } +} + +rule("Setting Shop Position") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.ShopCamPos = 900 * Up; + Global.ShopPosAngle[1] = Direction From Angles(Horizontal Angle From Direction(Forward), Vertical Angle From Direction(Forward) + - 90); + Global.ShopPosAngle[0] = Cross Product(Global.ShopPosAngle[1], Forward); + Global.ShopBasePos = Global.ShopCamPos - 9 * Global.ShopPosAngle[1] + 142 * Forward; + } +} + +rule("Create Shop Buttons") +{ + event + { + Ongoing - Global; + } + + actions + { + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] + 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.ShopBasePos - 41 * Global.ShopPosAngle[1] - 90 * Global.ShopPosAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Refund"), + Global.ShopBasePos + 45 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 3, Do Not Clip, Visible To, Color(Green), + Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("[{0}] Leave", + Input Binding String(Button(Reload))), Global.ShopBasePos + 45 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 3, + Do Not Clip, Visible To and String, Color(Green), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("{0}$\n", Local Player.Money[0]), + Global.ShopBasePos + 36.500 * Global.ShopPosAngle[1], 3, Do Not Clip, Visible To and String, Color(White), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("▲"), Update Every Frame( + Global.ShopBasePos - (4 + Vertical Facing Angle Of(Local Player)) * Global.ShopPosAngle[1] + Horizontal Facing Angle Of( + Local Player) * Global.ShopPosAngle[0]), 4, Do Not Clip, Visible To Position and Color, Custom Color( + 245 + 10 * Sine From Radians(4 * Total Time Elapsed), 205 + 50 * Sine From Radians(4 * Total Time Elapsed), + 200 * Sine From Radians(4 * Total Time Elapsed), 255), Default Visibility); + "Headhunter" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[1] ? Custom String("Headhunter II\n  800$") : Custom String("Headhunter I\n  800$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[1] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Ambush" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[2] ? Custom String("Ambush II\n 800$") : Custom String("Ambush I\n 800$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[2] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Quick Fix" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[3] ? Custom String("Quick Fix II\n  700$") : Custom String("Quick Fix I\n  700$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[3] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavyweight" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[4] ? Custom String("Heavyweight II\n  1000$") : Custom String("Heavyweight I\n  1000$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[4] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Charged" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[5] ? Custom String("Charged II\n  700$") : Custom String("Charged I\n  700$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[5] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Haste" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[6] ? Custom String("Haste II\n 700$") : Custom String("Haste I\n 700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[6] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavy Impact" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[7] ? Custom String("Heavy Impact II\n  1000$") : Custom String("Heavy Impact I\n  1000$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[7] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 1" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 1\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] + 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[8] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "Second Wind" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[9] ? Custom String("Second Wind II\n   900$") : Custom String("Second Wind I\n   900$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[9] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Binding Heal" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[10] ? Custom String("Binding Heal II\n   700$") : Custom String("Binding Heal I\n   700$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[10] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Resilience" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.Abilities[11] ? Custom String("Resilience II\n  800$") : Custom String("Resilience I\n  800$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[11] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 2" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 2\n  1200$"), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 22.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.Abilities[12] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "PlusDamage" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Damage\n  400$"), + Global.ShopBasePos + 20 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealth" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Health\n 400$"), + Global.ShopBasePos - 2.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Healing\n  400$"), + Global.ShopBasePos - 25 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, Visible To and String, + Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "+{0} Auto-Repair\n    400$", Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Global.ShopBasePos - 47.500 * Global.ShopPosAngle[1] - 67.500 * Global.ShopPosAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Global.AutoRepair < 5 ? Color(Green) : Color(Gray), Default Visibility); + "Use Update Every Frame to avoid showing the String when the cursor is out of bounds, resulting in 0\r\n ROW 0" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -33.750 ? Array(Custom String("Leave Buy Menu\n"), Custom String( + ""), Custom String(""), Custom String("Refund your money\n"))[Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) + / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, + Color(White), Default Visibility); + "ROW 1" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 22.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -11.250 ? Array(Custom String("Increase your damage by 5%\n"), + Local Player.Abilities[9] ? Custom String( + "Second Wind II: 60% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds") + : Custom String( + "Second Wind I: 30% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds"), + Local Player.Abilities[5] ? Custom String("Charged II: Ultimates cost 40% less\n") : Custom String( + "Charged I: Ultimates cost 20% less\n"), Local Player.Abilities[1] ? Custom String( + "Headhunter II: Critical hits deal 80% more damage\n") : Custom String("Headhunter I: Critical hits deal 40% more damage\n")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 2" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 36.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 11.250 ? Array(Custom String("Increase your health by 5%\n"), + Local Player.Abilities[10] ? Custom String("Binding Heal II: Heal yourself for 50% the amount when healing allies\n") + : Custom String("Binding Heal I: Heal yourself for 25% the amount when healing allies\n"), + Local Player.Abilities[6] ? Custom String( + " Haste II: Ability cooldown is reduced by 50%\nDoes not affect abilities with multiple charges") : Custom String( + " Haste I: Ability cooldown is reduced by 25%\nDoes not affect abilities with multiple charges"), + Local Player.Abilities[2] ? Custom String("Ambush II: Deal 60% more damage when attacking enemies from behind or above\n") + : Custom String("Ambush I: Deal 30% more damage when attacking enemies from behind or above\n"))[Round To Integer(( + Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 3" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 83.750) < 72.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 33.750 ? Array(Custom String("Increase your healing by 5%\n"), + Local Player.Abilities[11] ? Custom String("Resilience II: Take 30% less damage while below 60% health\n") : Custom String( + "Resilience I: Take 30% less damage while below 30% health\n"), Local Player.Abilities[7] ? Custom String( + "Heavy Impact II: Every hit has a chance to stun the enemy for 2 seconds\n") : Custom String( + "Heavy Impact I: Every hit has a chance to stun the enemy for 1 second\n"), Local Player.Abilities[3] ? Custom String( + "Quick Fix II: Eliminations restore 100 HP and shortly increase speed by 40%\n") : Custom String( + "Quick Fix I: Eliminations restore 50 HP and shortly increase speed by 20%\n"))[Round To Integer((Horizontal Facing Angle Of( + Local Player) + 90) / 45, Down)] : Custom String("")), Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, + Visible To and String, Color(White), Default Visibility); + "ROW 4" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 133) < 99.250 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 56.250 ? Array(Custom String( + "Increase your auto-repair by {0}/5s\n", Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Custom String("{0}", Local Player.HeroTalentText[2][1]), Custom String("{0}", Local Player.HeroTalentText[1][1]), + Local Player.Abilities[4] ? Custom String( + "Heavyweight II: Your knock back attacks deal 50% more damage and knock back\n            You receive 33% less knock back") + : Custom String( + "Heavyweight I: Your knock back attacks deal 25% more damage and knock back\n            You receive 20% less knock back")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.ShopBasePos - 75 * Global.ShopPosAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + } +} + +rule("Toggle Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + !Is Dummy Bot(Event Player) == True; + Is Button Held(Event Player, Button(Reload)) == True; + !Is Communicating Any Emote(Event Player) == True; + } + + actions + { + If(Event Player.isInMenu == False); + Wait Until(!Is Button Held(Event Player, Button(Reload)), 0.500); + If(!Is Button Held(Event Player, Button(Reload))); + Abort; + End; + End; + Event Player.isInMenu = !Event Player.isInMenu; + } +} + +rule("Open Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == True; + } + + actions + { + Event Player.PlayerFacing = Facing Direction Of(Event Player); + Start Camera(Event Player, Global.ShopCamPos, Global.ShopCamPos + Forward, 0); + Disable Hero HUD(Event Player); + Call Subroutine(DisablePlayer); + Set Aim Speed(Event Player, 200); + } +} + +rule("Close Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == False; + } + + actions + { + Stop Camera(Event Player); + Enable Hero HUD(Event Player); + Call Subroutine(EnablePlayer); + Set Aim Speed(Event Player, 100); + Set Facing(Event Player, Event Player.PlayerFacing, To World); + } +} + +rule("Subroutine: Disable Player") +{ + event + { + Subroutine; + DisablePlayer; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + Set Primary Fire Enabled(Event Player, False); + Set Secondary Fire Enabled(Event Player, False); + Set Ability 1 Enabled(Event Player, False); + Set Ability 2 Enabled(Event Player, False); + Set Melee Enabled(Event Player, False); + Set Jump Enabled(Event Player, False); + Set Crouch Enabled(Event Player, False); + Disallow Button(Event Player, Button(Ultimate)); + } +} + +rule("Subroutine: Enable Player") +{ + event + { + Subroutine; + EnablePlayer; + } + + actions + { + Stop Forcing Throttle(Event Player); + Set Primary Fire Enabled(Event Player, True); + Set Secondary Fire Enabled(Event Player, True); + Set Ability 1 Enabled(Event Player, True); + Set Ability 2 Enabled(Event Player, True); + Set Melee Enabled(Event Player, True); + Set Jump Enabled(Event Player, True); + Set Crouch Enabled(Event Player, True); + Allow Button(Event Player, Button(Ultimate)); + } +} + +rule("Buy Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Primary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + Event Player.isInMenu = !Event Player.isInMenu; + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Money[1] != 0); + Call Subroutine(Refund); + Else; + Small Message(Local Player, Custom String("You don't have anything to refund!")); + End; + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[13] += 1; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 2); + If(Event Player.Money[0] >= 900); + Event Player.Money[0] -= 900; + Event Player.Money[1] += 900; + Event Player.Abilities[9] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[5] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[1] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[14] += 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[10] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[6] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[2] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Event Player.Abilities[15] += 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 2); + If(Event Player.Money[0] >= 800); + Event Player.Money[0] -= 800; + Event Player.Money[1] += 800; + Event Player.Abilities[11] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[7] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 2); + If(Event Player.Money[0] >= 700); + Event Player.Money[0] -= 700; + Event Player.Money[1] += 700; + Event Player.Abilities[3] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Global.AutoRepair != 5); + If(Event Player.Money[0] >= 400); + Event Player.Money[0] -= 400; + Event Player.Money[1] += 400; + Global.AutoRepair += 1; + Event Player.Abilities[16] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[12] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 1); + If(Event Player.Money[0] >= 1200); + Event Player.Money[0] -= 1200; + Event Player.Money[1] += 1200; + Event Player.Abilities[8] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 2); + If(Event Player.Money[0] >= 1000); + Event Player.Money[0] -= 1000; + Event Player.Money[1] += 1000; + Event Player.Abilities[4] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + End; + } +} + +rule("Refund Single Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Secondary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[13] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[13] -= 1; + Event Player.DamageDealt = 100 + Global.DamageDone + Event Player.Abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.DamageDealt); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[9] != 0); + Event Player.Money[0] += 900; + Event Player.Money[1] -= 900; + Event Player.Abilities[9] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[5] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[5] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[1] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[1] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[14] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[14] -= 1; + Event Player.PlayerHealth = 100 + Global.MaxHealthDone + Event Player.Abilities[14] * 5; + Set Max Health(Event Player, Event Player.PlayerHealth); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[10] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[10] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[6] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[6] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[2] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[2] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[15] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Event Player.Abilities[15] -= 1; + Set Healing Dealt(Event Player, 100 + Event Player.Abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[11] != 0); + Event Player.Money[0] += 800; + Event Player.Money[1] -= 800; + Event Player.Abilities[11] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[7] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[7] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[3] != 0); + Event Player.Money[0] += 700; + Event Player.Money[1] -= 700; + Event Player.Abilities[3] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.Abilities[16] != 0); + Event Player.Money[0] += 400; + Event Player.Money[1] -= 400; + Global.AutoRepair -= 1; + Event Player.Abilities[16] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.Abilities[12] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[12] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.Abilities[8] != 0); + Event Player.Money[0] += 1200; + Event Player.Money[1] -= 1200; + Event Player.Abilities[8] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.Abilities[4] != 0); + Event Player.Money[0] += 1000; + Event Player.Money[1] -= 1000; + Event Player.Abilities[4] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + End; + } +} + +rule("Create Player HUD") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Custom String("{0}{1}", + Event Player, Event Player.isInMenu ? Custom String("(In Shop)") : Custom String("")), Custom String("{0}{1}", Is Alive( + Event Player) ? Custom String("{0} HP", Round To Integer(Health(Event Player), Up)) : Custom String("Dead"), Custom String( + ", {0}$", Event Player.Money)), Left, Local Player == Event Player ? -1 : Slot Of(Event Player), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), + Visible To Sort Order String and Color, Default Visibility); + Create HUD Text(Event Player.Abilities[13] || Global.DamageDone ? Event Player : Null, Null, Null, Custom String("+{0}% Damage", + Global.DamageDone + Event Player.Abilities[13] * 5), Left, 913, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[9] ? Event Player : Null, Null, Null, Custom String("Second Wind {0}", + Event Player.Abilities[9] == 1 ? Custom String("I") : Custom String("II")), Left, 908, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[5] ? Event Player : Null, Null, Null, Custom String("Charged {0}", + Event Player.Abilities[5] == 1 ? Custom String("I") : Custom String("II")), Left, 905, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[1] ? Event Player : Null, Null, Null, Custom String("Headhunter {0}", + Event Player.Abilities[1] == 1 ? Custom String("I") : Custom String("II")), Left, 901, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[14] || Global.MaxHealthDone ? Event Player : Null, Null, Null, Custom String("+{0}% Health", + Global.MaxHealthDone + Event Player.Abilities[14] * 5), Left, 914, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[10] ? Event Player : Null, Null, Null, Custom String("Binding Heal {0}", + Event Player.Abilities[10] == 1 ? Custom String("I") : Custom String("II")), Left, 909, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[6] ? Event Player : Null, Null, Null, Custom String("Haste {0}", + Event Player.Abilities[6] == 1 ? Custom String("I") : Custom String("II")), Left, 906, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[2] ? Event Player : Null, Null, Null, Custom String("Ambush {0}", + Event Player.Abilities[2] == 1 ? Custom String("I") : Custom String("II")), Left, 902, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[15] ? Event Player : Null, Null, Null, Custom String("+{0}% Healing", + Event Player.Abilities[15] * 5), Left, 915, Color(White), Color(White), Color(Turquoise), Visible To and String, + Default Visibility); + Create HUD Text(Event Player.Abilities[11] ? Event Player : Null, Null, Null, Custom String("Resilience {0}", + Event Player.Abilities[11] == 1 ? Custom String("I") : Custom String("II")), Left, 910, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[7] ? Event Player : Null, Null, Null, Custom String("Heavy Impact {0}", + Event Player.Abilities[7] == 1 ? Custom String("I") : Custom String("II")), Left, 907, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[3] ? Event Player : Null, Null, Null, Custom String("Quick Fix {0}", + Event Player.Abilities[3] == 1 ? Custom String("I") : Custom String("II")), Left, 903, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Global.AutoRepair ? Event Player : Null, Null, Null, Custom String("{0} total Auto-Repair/5s", + Global.AutoRepair * (Global.UpgradeGateMaxHealthValue >= Global.UpgradeGateMaxHealthMaxValue[2] ? 10 : 5)), Left, 916, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[2][0], Event Player.HeroTalentText[2][1]), Top, 902, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[12] ? Event Player : Null, Null, Null, Custom String("Hero Talent 2"), Left, 912, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.HeroTalentText[1][0], Event Player.HeroTalentText[1][1]), Top, 901, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[8] ? Event Player : Null, Null, Null, Custom String("Hero Talent 1"), Left, 911, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.Abilities[4] ? Event Player : Null, Null, Null, Custom String("Heavyweight {0}", + Event Player.Abilities[4] == 1 ? Custom String("I") : Custom String("II")), Left, 904, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + } +} + +rule("Rein Pin detect") +{ + event + { + Player Dealt Knockback; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 1); + Has Status(Victim, Stunned) == True; + } + + actions + { + Event Player.ReinPin = Victim; + Wait(1, Ignore Condition); + Event Player.ReinPin = Null; + } +} + +rule("Boss Rotation") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.activeBoss == True; + } + + actions + { + If(Global.bossRotation == 0 || Global.bossRotation == 3); + Global.bossRotation = 1; + Global.lastBoss[1] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 1); + Global.bossRotation = 2; + Global.lastBoss[2] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 2); + Global.bossRotation = 3; + Global.lastBoss[3] = Hero Of(Global.activeBoss); + End; + } +} + +rule("15 minutes hud") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.TimeMin == 10; + } + + actions + { + Create HUD Text(All Players(Team 1), Global.activeBoss ? Custom String("Boss: {0}, HP: {1}/{2}", Hero Of(Global.activeBoss), + Health(Global.activeBoss), Max Health(Global.activeBoss)) : Custom String(""), Null, Null, Top, 900, Color(Red), Color(White), + Color(White), Visible To and String, Default Visibility); + } +} + +rule("debug") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + (Is Button Held(Event Player, Button(Primary Fire)) && Is Button Held(Event Player, Button(Crouch))) == True; + } + + actions + { + Global.TimeSec = 59; + } +} + +disabled rule("debug") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.IsDebug == True; + } + + actions + { + Create HUD Text(Local Player, Custom String("{0}", Position Of(Local Player)), Null, Null, Left, 0, Color(Yellow), Color(White), + Color(White), Visible To and String, Default Visibility); + Set Status(Event Player, Null, Invincible, 9999); + Set Status(Event Player, Null, Phased Out, 9999); + } +} + +rule("ending 1 part 1") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("Exfiltration available! (optional - ends the mode)"), Null, Null, Top, 50, + Color(Red), Color(White), Color(White), Visible To and String, Default Visibility); + Global.GlobalHuds[1] = Last Text ID; + Create In-World Text(All Players(Team 1), Custom String( + "Exfiltration available! Gather here!\n{0}/{1} Players ready to exfiltrate!", Count Of(Filtered Array(All Players(Team 1), + Distance Between(Vector(186, 11, -46.500), Current Array Element) <= 9)), Count Of(All Players(Team 1))), Vector(186, 15, + -46.500), 1.200, Do Not Clip, Visible To and String, Color(Green), Default Visibility); + Wait(3, Ignore Condition); + Destroy HUD Text(Global.GlobalHuds[1]); + } +} + +rule("ending 1 part 2") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + Distance Between(Vector(186, 11, -46.500), All Players(Team 1)) <= 9; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GG! YOU DID IT!")); + Destroy All Dummy Bots; + Disable Movement Collision With Environment(All Players(Team 1), True); + Start Accelerating(All Players(Team 1), Up, 100, 5, To World, Direction Rate and Max Speed); + Wait(5, Ignore Condition); + Declare Team Victory(Team 1); + } +} + +rule("Team 1 (Ability): Second Wind save life") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[9] == True; + Event Player.secondWindActive == True; + Health(Event Player) == 1; + } + + actions + { + Small Message(All Players(All Teams), Custom String("{0} received a second wind!", Event Player)); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Green), Event Player, 1); + Clear Status(Event Player, Unkillable); + Set Player Health(Event Player, Max Health(Event Player)); + Event Player.lastSecondWind = 30; + Event Player.secondWindActive = 0; + } +} + +rule("Team 1 (Ability): Second Wind after buying") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.Abilities[9] == True; + Event Player.secondWindActive == False; + Event Player.lastSecondWind == 0; + } + + actions + { + If(Random Integer(1, 100) > Event Player.Abilities[9] * 30); + Wait(30, Ignore Condition); + Loop; + End; + Set Status(Event Player, Null, Unkillable, 9999); + Event Player.secondWindActive = 1; + } +} + +rule("Team 1 (Ability): Second Wind counter") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Player.lastSecondWind > 0; + } + + actions + { + Wait(1, Ignore Condition); + Event Player.lastSecondWind -= 1; + Loop If Condition Is True; + } +} + +rule("Team 1: Change Hero") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Distance Between(Vector(149.000, 10, -62.000), All Players(Team 1)) <= 2; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + Set Player Allowed Heroes(Event Player, Hero(Pharah)); + Set Player Allowed Heroes(Event Player, Hero(Ana)); + If(Global.IsStoryHeroes); + Reset Player Hero Availability(Event Player); + Set Player Allowed Heroes(Event Player, Array(Hero(Ana), Hero(Brigitte), Hero(Mercy), Hero(Lúcio), Hero(Moira), Hero(Baptiste), + Hero(Ashe), Hero(D.Va), Hero(Genji), Hero(Hanzo), Hero(Widowmaker), Hero(Cassidy), Hero(Reinhardt), Hero(Soldier: 76), Hero( + Torbjörn), Hero(Tracer), Hero(Winston), Hero(Pharah))); + Else; + Reset Player Hero Availability(Event Player); + End; + Wait(0.500, Ignore Condition); + Wait Until(Has Spawned(Event Player), 99999); + Teleport(Event Player, Vector(149.000, 10, -62.000)); + } +} \ No newline at end of file diff --git a/defendTheCastleExtended/old_versions/c127.ow b/defendTheCastleExtended/old_versions/c127.ow new file mode 100644 index 0000000..04a3f33 --- /dev/null +++ b/defendTheCastleExtended/old_versions/c127.ow @@ -0,0 +1,9359 @@ +settings +{ + main + { + Description: "Defend The Castle Extended v0.6.c127\nby ShuriZma#2349\nJ1K6F (Code Version: c126)\nOriginal mode by HuKuTa94#2589\n\nDefend the gate, kill enemies and don't allow them to damage the gate!\n\nSpecial Thanks to:\nShingen#21859 for the abilities,\nLemonAid#11644 for the Hero Talents\n& Josbird for teaching me about Menus!\n\nFind this mode on: workshop.codes/defend-the-castle\nFind the Original Mode on: workshop.codes/BQEGS\nTell me what you think on Discord: discord.shurizma.de\n\nPS: SHINGEN PLS COME BACK" + Mode Name: "Defend The Castle Extended" + } + + lobby + { + Max Spectators: 0 + Max Team 1 Players: 4 + Max Team 2 Players: 0 + Return To Lobby: Never + Swap Teams After Match: No + } + + modes + { + Escort + { + enabled maps + { + Havana + } + } + + Team Deathmatch + { + enabled maps + { + } + } + + General + { + Game Mode Start: Immediately + Spawn Health Packs: Disabled + } + } + + workshop + { + Ana can nano herself even if there are other players only if no player targeted: On + Story Heroes: Off + } + + extensions + { + Beam Effects + Beam Sounds + Buff Status Effects + Debuff Status Effects + Buff and Debuff Sounds + Energy Explosion Effects + Kinetic Explosion Effects + Explosion Sounds + Play More Effects + Spawn More Dummy Bots + } +} + +variables +{ + global: + 0: gatePosition + 1: zenSpawnPositions + 2: spawnPositionMaxId + 3: loopIterator1 + 4: bigBossSpawnPositions + 5: playerSpawnPositions + 6: gateHealthChase + 7: gateHealth + 8: gateMaxHealth + 9: gateProgressBarColorCurrent + 10: gateProgressBarColorComponent + 11: gateHealthEvent + 12: bastionTargetPositions + 13: sniperPositions + 14: ballSpawnPositions + 15: zenRespawnTime + 16: timeSec + 17: timeMin + 18: time5Min + 19: time10Min + 20: isDebug + 21: isDebugAINavigation + 22: botOrisaParent + 23: isStoryHeroes + 24: botOrisaChild + 25: gateRepairPosition + 26: botOrisaTargetPosition + 27: botEchoRespawnPosition + 28: botEchoTeleportPositions + 29: upgradeGateMaxHealthValue + 30: upgradeGateMaxHealthHudId + 31: upgradePlayerMaxHealthValue + 32: upgradePlayerMaxHealthHudId + 33: upgradeCriticalDamageValue + 34: upgradeCriticalDamageHudId + 35: upgradeMaxAmmoValue + 36: upgradeMaxAmmoHudId + 37: upgradeMaxAmmoMaxValue + 38: upgradePlayerMaxHealthMaxValue + 39: upgradeCriticalDamageMaxValue + 40: upgradeGateMaxHealthMaxValue + 41: damageDealt + 42: selfNanoWorkshopSetting + 43: gameLogicCountOfUniqueHeroes + 44: isNewWaveGameLogicProcessing + 45: autoRepair + 46: upgradePerkSharpshooterValue + 47: perk + 48: maxHealthDone + 49: defaultCurrentBot + 50: defaultHeroBotsPool + 51: defaultHeroBotsPoolCurrentId + 52: shopCamPosition + 53: shopBasePosition + 54: shopPositionAngle + 55: activeBoss + 56: bossTrigger + 57: bossRotation + 58: lastBoss + 59: startMoney + 60: moneyMultiplier + 61: challengeCount + 62: upgradeBossHealthValue + 63: globalHUDs + 112: allPositions + 113: allDirections + 114: wallFirstPosition + 115: wallSecondPosition + 116: wallFirstPoint + 117: wallSecondPoint + 118: second + 119: z + 120: wallId + 121: showWalls + 122: isGrounded + 123: BeamType + 124: x + 125: nodePositions + 126: nodeConnections + 127: distanceMatrix + + player: + 0: botSeePlayer + 1: botDoesUniqueBehaviour + 2: botEffects + 3: botRayCastHitPosition + 4: botEventPosition + 5: currentHero + 6: modificationDamage + 7: isRespawning + 8: botBastionArtilleryDidShotsCount + 9: botCounter + 10: hasBadStatus + 11: eventHealth + 12: healOverTimeId + 13: botIsOrisaChild + 14: botEchoCapturedPlayer + 15: botPlayersInRadius + 16: botWidowShotTime + 17: botWidowTeleportTime + 18: effects_ + 19: anaEntityID + 20: money + 21: lucioDashActive + 22: lucioDashIcon + 23: heroTalentText + 24: damageDealt + 25: hpPool + 26: playerHealth + 27: abilities + 28: abilityCountdown + 29: abilityHUD + 30: abilityProjectile1 + 31: abilityProjectile2 + 32: abilityEnd + 33: abilityPosition + 34: abilityActive + 35: abilityResource + 36: abilityPlayer + 37: fearedUntil + 38: stormEffects + 39: stormProjectile + 40: stormEndPoint + 41: chainReactionOn + 42: chainReactionImmune + 43: isDead + 44: isNanoed + 45: isInMenu + 46: isBoss + 47: reinPin + 48: playerFacing + 49: genDirection + 50: genAvailable + 51: secondWindActive + 52: lastSecondWind + 53: deathPosition + 104: x + 105: filterPosition + 106: lastSavedPosition + 107: closestBodyPosition + 108: fullBodyPosition + 109: previousPositionIntersection + 110: activeWall + 111: closestWall + 112: intersectionLength + 113: thickness + 114: botCancelPathFinding + 115: botLoopIterator1 + 116: botLoopIterator2 + 117: botTempArray + 118: botTargetPlayer + 119: botTargetPosition + 120: botClosestNodeIdToTarget + 121: botClosestNodeIdToBot + 122: botPreviousNodeId + 123: botNextNodeId + 124: botNextNodePosition + 125: botCurrentDistanceToTarget + 126: botShortestDistanceToTarget + 127: botIsPathFinding +} + +subroutines +{ + 0: BotBastionArtilleryDamage + 1: BotBastionFlameGunDamage + 2: BotBastionRespawn + 3: GateProgressBarColor + 4: BotZenyattaRespawn + 5: BotWidowRespawn + 6: BotBallRespawn + 7: GameLogicAddNextHeroInGame + 8: BotOrisaRespawn + 9: BotLandingFromSky + 10: BotEchoRespawn + 11: BotEchoDetachPlayer + 12: BotEchoFlyToPlayer + 13: BotEchoFlyToPortal + 14: GameLogicSetBotProperties + 15: DisablePlayer + 16: BotAppearFromUnderground + 17: BotReinRespawn + 18: PlayerInit + 19: BotInit + 20: PlayerRespawn + 21: BotRespawn + 22: BotWidowBadStatus + 23: GameLogicWave0 + 24: Refund + 25: EnablePlayer + 26: GateRepair + 124: BotStartPathFinding + 125: BotGetClosestNodeIdToTarget + 126: BotGetNextNodeIdAndPosition + 127: BotResetPathFinding +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("MAP: HAVANA") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Havana); + } + + actions + { + Global.nodePositions = Array(Vector(147.588, 6.425, -46.749), Vector(136.181, 6.425, -57.159), Vector(130.189, 6.425, -63.781), + Vector(123.305, 6.425, -57.983), Vector(125.678, 6.504, -46.633), Vector(114.485, 7.471, -46.699), Vector(138.743, 6.425, + -32.974), Vector(126.498, 6.425, -39.920), Vector(124.572, 10.434, -34.300), Vector(138.605, 5.359, -18.647), Vector(119.009, + 2.331, -31.024), Vector(121.138, 5.228, -19.933), Vector(126.722, 6.425, -29.505), Vector(102.762, 3.157, -33.609), Vector( + 76.030, 7.418, -74.087), Vector(83.720, 9.425, -33.744), Vector(97.439, 7.238, -42.379), Vector(86.252, 12.416, -47.261), + Vector(65.178, 11.425, -73.187), Vector(97.466, 7.269, -50.596), Vector(113.039, 7.424, -37.337), Vector(106.179, 7.450, + -46.143), Vector(90.086, 7.411, -44.653), Vector(78.752, 7.418, -62.140), Vector(82.124, 7.428, -44.229), Vector(90.675, 7.231, + -51.234), Vector(85.717, 4.692, -63.446), Vector(90.830, 4.330, -70.697), Vector(102.425, 2.387, -72.817), Vector(81.443, + 4.425, -81.648), Vector(70.743, 6.418, -81.495), Vector(69.738, 6.419, -96.344), Vector(127.586, 12.643, -63.344), Vector( + 118.911, 13.468, -58.008), Vector(102.885, 1.092, -56.579), Vector(100.009, 2.967, -67.139), Vector(106.703, 0.465, -44.628), + Vector(81.695, 7.418, -52.140), Vector(126.979, 12.393, -55.079), Vector(153.720, 18.578, -21.745), Vector(155.301, 18.619, + -17.595), Vector(133.043, 10.425, -26.625), Vector(114.646, 7.278, -57.336), Vector(95.160, 3.688, -81.194), Vector(78.456, + 5.418, -93.581), Vector(75.455, 5.418, -101.492), Vector(148.071, 9.432, -32.123), Vector(146.706, 9.425, -27.858), Vector( + 144.273, 9.445, -63.119), Vector(144.278, 9.454, -58.447)); + Global.nodeConnections = Array(Array(1, 6, 4, 7), Array(2, 1, 4, 6, 7, 0, 49), Array(1, 3), Array(2, 4, 42), Array(3, 1, 5, 7, 6, + 1, 0), Array(4, 7, 20, 21, 19, 16, 42), Array(7, 1, 4, 1, 9, 12, 0, 46), Array(4, 5, 6, 1, 1, 12, 0), Array(7, 41), Array(6, + 11), Array(11, 13), Array(9, 10, 13), Array(6, 7, 10), Array(10, 16, 36), Array(18, 23, 30), Array(17, 24), Array(13, 19, 22, + 21, 25, 5), Array(15, 22, 25, 23), Array(14), Array(16, 21, 22, 26, 27, 35, 25, 5), Array(5, 13, 10), Array(19, 16, 5, 13, 22, + 34), Array(16, 19, 21, 24, 25), Array(14, 25, 26, 37), Array(22, 15, 37), Array(23, 22, 19, 16, 26, 27, 35, 37), Array(25, 19, + 27, 35, 29), Array(19, 26, 25, 29, 35, 43), Array(35, 34, 43), Array(27, 26, 30, 43, 44), Array(29, 14, 31), Array(30, 29, 45), + Array(33, 38, 1, 48), Array(32, 38, 42), Array(35, 36, 28), Array(28, 19, 25, 27, 26, 34), Array(13, 34), Array(25, 23, 24), + Array(5, 4, 1, 6, 1, 32, 33, 0), Array(40), Array(39), Array(6, 8, 47, 46), Array(3, 5, 34), Array(28, 27, 29, 44), Array(29, + 43, 45), Array(44, 31), Array(6, 47), Array(46, 41), Array(49, 32), Array(1, 0, 6, 48)); + Global.distanceMatrix = Array(Array(0, 1, 2, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, + 4, 5, 4, 4, 5, 5, 5, 0, 0, 4, 3, 5, 6, 7, 2, 3, 3, 2), Array(1, 0, 1, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, + 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 3, 4, 4, 4, 5, 5, 4, 0, 0, 4, 3, 5, 6, 7, 2, 3, 2, 1), Array(2, 1, 0, 1, 2, 3, 2, 2, 6, 3, 4, 4, + 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 4, 6, 7, 8, 4, 5, 3, 4, 4, 6, 5, 0, 0, 5, 2, 5, 6, 7, 3, 4, 3, 2), Array(2, 2, + 1, 0, 1, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, 5, 6, 2, 3, 3, 5, 6, 0, 0, 5, 1, 4, + 5, 6, 3, 4, 4, 3), Array(1, 1, 2, 1, 0, 1, 1, 1, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, + 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, 2, 3, 3, 2), Array(2, 2, 3, 2, 1, 0, 2, 1, 6, 3, 2, 3, 2, 2, 4, 4, 1, 5, 5, 1, 1, 1, 2, 3, + 3, 2, 2, 2, 3, 3, 4, 5, 5, 6, 2, 2, 3, 3, 6, 0, 0, 5, 1, 3, 4, 5, 3, 4, 4, 3), Array(1, 1, 2, 2, 1, 2, 0, 1, 4, 1, 2, 2, 1, 3, + 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 4, 5, 4, 4, 4, 5, 5, 0, 0, 3, 3, 5, 6, 7, 1, 2, 3, 2), Array(1, 1, 2, 2, + 1, 1, 1, 0, 5, 2, 2, 3, 1, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, + 2, 3, 3, 2), Array(2, 2, 3, 3, 2, 2, 2, 1, 0, 3, 3, 4, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, + 5, 5, 6, 0, 0, 1, 3, 5, 6, 7, 2, 2, 4, 3), Array(2, 2, 3, 3, 2, 3, 1, 2, 5, 0, 2, 1, 2, 2, 6, 6, 3, 7, 7, 4, 4, 4, 4, 5, 5, 4, + 5, 5, 5, 6, 7, 8, 5, 6, 4, 5, 3, 5, 6, 0, 0, 4, 4, 6, 7, 8, 2, 3, 4, 3), Array(4, 4, 5, 5, 4, 3, 3, 4, 7, 2, 0, 1, 4, 1, 5, 5, + 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 7, 8, 3, 4, 2, 4, 8, 0, 0, 6, 4, 5, 6, 7, 4, 5, 6, 5), Array(3, 3, 4, 4, 3, 3, + 2, 3, 6, 1, 1, 0, 3, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 6, 7, 3, 4, 2, 4, 7, 0, 0, 5, 4, 5, 6, 7, 3, 4, + 5, 4), Array(2, 2, 3, 3, 2, 2, 1, 1, 5, 2, 1, 2, 0, 2, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, 3, 5, + 6, 0, 0, 4, 3, 5, 6, 7, 2, 3, 4, 3), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 3, 1, 2, 4, 0, 4, 4, 1, 5, 5, 2, 3, 2, 2, 3, 3, 2, 3, 3, + 3, 4, 5, 6, 7, 8, 2, 3, 1, 3, 8, 0, 0, 7, 3, 4, 5, 6, 5, 6, 6, 5), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 5, 6, 6, 4, 0, 4, 3, 5, + 1, 3, 5, 4, 3, 1, 3, 2, 2, 3, 4, 2, 1, 2, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 3, 3, 3, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, + 5, 10, 7, 5, 6, 6, 4, 3, 0, 3, 1, 4, 3, 5, 3, 2, 2, 1, 2, 3, 3, 4, 4, 4, 5, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 4, 5, 6, 7, 8, + 8, 7), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 3, 3, 0, 4, 4, 1, 2, 1, 1, 2, 2, 1, 2, 2, 3, 3, 4, 5, 6, 7, 2, 2, 2, 2, + 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 1, 2, 0, 3, 2, 4, 2, 1, 1, 2, 1, 2, 2, + 3, 3, 3, 4, 8, 9, 3, 2, 4, 2, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 6, 7, 7, 5, 1, 5, 4, 6, + 0, 4, 6, 5, 4, 2, 4, 3, 3, 4, 5, 3, 2, 3, 10, 11, 5, 4, 6, 3, 11, 0, 0, 10, 6, 4, 4, 4, 8, 9, 9, 8), Array(3, 3, 4, 3, 2, 1, 3, + 2, 7, 4, 3, 4, 3, 2, 3, 3, 1, 4, 4, 0, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 3, 4, 6, 7, 2, 1, 3, 2, 7, 0, 0, 6, 2, 2, 3, 4, 4, 5, 5, + 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 3, 1, 2, 3, 1, 5, 5, 2, 6, 6, 2, 0, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 6, 7, 3, 3, 2, 4, 7, + 0, 0, 6, 2, 4, 5, 6, 4, 5, 5, 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 4, 3, 1, 4, 5, 1, 2, 0, 1, 3, 2, 2, 2, 2, 2, + 3, 4, 5, 6, 7, 1, 2, 2, 3, 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 3, 2, 1, 3, 4, + 1, 3, 1, 0, 2, 1, 1, 2, 2, 3, 3, 4, 5, 7, 8, 2, 2, 3, 2, 8, 0, 0, 7, 3, 3, 4, 5, 5, 6, 6, 5), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, + 6, 4, 5, 5, 3, 1, 3, 2, 4, 2, 2, 4, 3, 2, 0, 2, 1, 1, 2, 3, 2, 2, 3, 8, 9, 3, 2, 4, 1, 9, 0, 0, 8, 4, 3, 3, 4, 6, 7, 7, 6), + Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 3, 1, 2, 2, 4, 2, 4, 2, 1, 2, 0, 2, 3, 3, 4, 4, 4, 5, 8, 9, 3, 3, 4, 1, 9, 0, + 0, 8, 4, 4, 5, 6, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 2, 3, 1, 4, 3, 1, 3, 2, 1, 1, 2, 0, 1, 1, 2, 2, + 3, 4, 7, 8, 2, 1, 3, 1, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, + 3, 2, 2, 2, 3, 1, 0, 1, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 2, 2, 3, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, + 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 0, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 1, 2, 3, 5, 6, 6, 5), Array( + 5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 4, 5, 3, 6, 5, 2, 4, 3, 3, 3, 4, 2, 2, 2, 0, 2, 3, 4, 8, 9, 1, 1, 2, 3, 9, 0, 0, 8, + 4, 1, 2, 3, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 2, 5, 3, 6, 3, 2, 4, 3, 3, 3, 4, 2, 1, 1, 2, 0, 1, 2, + 8, 9, 3, 2, 4, 3, 9, 0, 0, 8, 4, 1, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 1, 5, 4, 6, 2, 3, 5, 4, + 4, 2, 4, 3, 2, 2, 3, 1, 0, 1, 9, 10, 4, 3, 5, 3, 10, 0, 0, 9, 5, 2, 2, 2, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, + 7, 6, 5, 2, 6, 4, 7, 3, 3, 5, 4, 4, 3, 5, 3, 2, 2, 3, 1, 1, 0, 9, 10, 4, 3, 5, 4, 10, 0, 0, 9, 5, 2, 2, 1, 7, 8, 8, 7), Array( + 2, 1, 2, 3, 2, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 4, 5, 6, 7, 0, 1, 3, 4, 4, 5, 1, 0, 0, 5, + 2, 5, 6, 7, 3, 4, 1, 2), Array(2, 2, 3, 2, 2, 2, 2, 3, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, + 1, 0, 2, 3, 3, 5, 1, 0, 0, 5, 1, 4, 5, 6, 3, 4, 2, 3), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 5, 3, 4, 5, 2, 4, 5, 3, 6, 5, 2, 4, 3, + 3, 3, 4, 2, 2, 2, 1, 3, 4, 5, 8, 9, 0, 1, 1, 3, 9, 0, 0, 8, 4, 2, 3, 4, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, + 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 1, 1, 2, 3, 4, 7, 8, 1, 0, 2, 2, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(5, 5, + 6, 5, 4, 3, 5, 4, 9, 4, 2, 3, 5, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 8, 9, 1, 2, 0, 4, 9, 0, 0, 8, 4, 3, + 4, 5, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 2, 2, 3, 3, 2, 4, 3, 2, 1, 1, 1, 2, 2, 3, 3, 3, 4, 8, 9, + 3, 2, 4, 0, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(1, 1, 2, 2, 1, 1, 1, 2, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, + 4, 3, 3, 3, 4, 4, 5, 6, 1, 1, 3, 3, 4, 4, 0, 0, 0, 4, 2, 4, 5, 6, 2, 3, 2, 2), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(2, 2, 3, 3, 2, 3, 1, 2, 1, 2, 3, 3, 2, + 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 0, 4, 6, 7, 8, 1, 1, 4, 3), Array(3, 3, 2, + 1, 2, 1, 3, 2, 7, 4, 3, 4, 3, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 6, 7, 1, 2, 2, 4, 7, 0, 0, 6, 0, 3, 4, + 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 3, 5, 3, 6, 4, 2, 4, 3, 3, 3, 4, 2, 2, 1, 1, 1, 2, 3, 8, 9, 2, + 2, 3, 3, 9, 0, 0, 8, 4, 0, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 3, 6, 4, 7, 4, 3, 5, 4, 4, 4, 5, + 3, 2, 2, 2, 1, 2, 2, 9, 10, 3, 3, 4, 4, 10, 0, 0, 9, 5, 1, 0, 1, 7, 8, 8, 7), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 7, 8, 7, 6, + 3, 7, 5, 8, 4, 4, 6, 5, 5, 4, 6, 4, 3, 3, 3, 2, 2, 1, 10, 11, 4, 4, 5, 5, 11, 0, 0, 10, 6, 2, 1, 0, 8, 9, 9, 8), Array(2, 2, 3, + 3, 2, 3, 1, 2, 3, 2, 3, 3, 2, 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 2, 4, 6, 7, + 8, 0, 1, 4, 3), Array(3, 3, 4, 4, 3, 4, 2, 3, 2, 3, 4, 4, 3, 5, 8, 8, 5, 9, 9, 5, 5, 5, 6, 7, 7, 6, 6, 6, 7, 7, 8, 9, 6, 7, 6, + 6, 6, 7, 7, 0, 0, 1, 5, 7, 8, 9, 1, 0, 5, 4), Array(2, 2, 3, 4, 3, 3, 2, 3, 6, 3, 4, 4, 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, + 5, 5, 5, 5, 6, 7, 8, 1, 2, 4, 5, 5, 6, 2, 0, 0, 5, 3, 6, 7, 8, 3, 4, 0, 1), Array(1, 1, 2, 3, 2, 3, 1, 2, 5, 2, 3, 3, 2, 4, 7, + 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 2, 3, 5, 5, 5, 6, 3, 0, 0, 4, 4, 6, 7, 8, 2, 3, 1)); + } +} + +rule("SUBROUTINE: BOT - RESET PATH FINDING") +{ + event + { + Subroutine; + BotResetPathFinding; + } + + actions + { + Event Player.botTargetPlayer = -1; + Event Player.botTargetPosition = -1; + Event Player.botPreviousNodeId = -1; + Event Player.botClosestNodeIdToTarget = -1; + Event Player.botNextNodeId = -1; + Event Player.botNextNodePosition = -1; + Event Player.botIsPathFinding = False; + Event Player.botCancelPathFinding = False; + Stop Throttle In Direction(Event Player); + disabled Stop Facing(Event Player); + } +} + +rule("SUBROUTINE: BOT - START PATH FINDING") +{ + event + { + Subroutine; + BotStartPathFinding; + } + + actions + { + disabled Abort If(Event Player.botIsPathFinding == True); + Call Subroutine(BotGetNextNodeIdAndPosition); + disabled Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Event Player.botIsPathFinding = True; + } +} + +rule("SUBROUTINE: BOT - GET NEXT NODE ID AND POSITION") +{ + event + { + Subroutine; + BotGetNextNodeIdAndPosition; + } + + actions + { + "BOT JUST START FOLLOW PATH OR LOST NEXT NODE" + If(Event Player.botPreviousNodeId == -1); + Event Player.botClosestNodeIdToBot = Index Of Array Value(Global.nodePositions, Sorted Array(Filtered Array(Global.nodePositions, + Is In Line of Sight(Position Of(Event Player) + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS) == True), + Distance Between(Position Of(Event Player), Current Array Element))[0]); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + "NEXT NODE IS TARGET (DISTANCE TO TARGET NODE = 1)" + If(Global.distanceMatrix[Event Player.botClosestNodeIdToBot][Event Player.botClosestNodeIdToTarget] == 1); + Event Player.botNextNodeId = Event Player.botClosestNodeIdToTarget; + "CHECK CONNECTIONS OF REACHED NODE" + Else; + Event Player.botShortestDistanceToTarget = 999; + Event Player.botCurrentDistanceToTarget = Event Player.botShortestDistanceToTarget; + Event Player.botTempArray = Global.nodeConnections[Event Player.botClosestNodeIdToBot]; + For Player Variable(Event Player, botLoopIterator1, 0, Count Of(Event Player.botTempArray), 1); + Event Player.botCurrentDistanceToTarget = Global.distanceMatrix[Event Player.botTempArray[Event Player.botLoopIterator1]][Event Player.botClosestNodeIdToTarget]; + If(Event Player.botCurrentDistanceToTarget < Event Player.botShortestDistanceToTarget); + Event Player.botShortestDistanceToTarget = Event Player.botCurrentDistanceToTarget; + Event Player.botNextNodeId = Event Player.botTempArray[Event Player.botLoopIterator1]; + End; + End; + End; + "NEXT NODE IS HIGHER THAN BOT AND BOT DIDN'T REACH CLOSEST NODE" + If(Y Component Of(Position Of(Event Player)) - Y Component Of(Global.nodePositions[Event Player.botNextNodeId]) + < -3 && Event Player.botPreviousNodeId != Event Player.botClosestNodeIdToBot); + Event Player.botPreviousNodeId = Event Player.botClosestNodeIdToBot; + Event Player.botNextNodeId = Event Player.botClosestNodeIdToBot; + "BOT CAN SEE TARGET POSITION AND NEXT NODE IS TARGET" + Else If( + Global.distanceMatrix[Event Player.botClosestNodeIdToBot][Event Player.botClosestNodeIdToTarget] == 1 && Is In Line of Sight( + Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.botTargetPosition + Vector(0, 2, 0), Barriers Do Not Block LOS)); + Event Player.botNextNodePosition = Event Player.botTargetPosition; + Abort; + "BOT CAN'T SEE NEXT NODE AND PREV NODE != REACHED NODE" + Else If(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), + Global.nodePositions[Event Player.botNextNodeId] + Vector(0, 2, 0), Barriers Do Not Block LOS) + == False && Event Player.botPreviousNodeId != Event Player.botClosestNodeIdToBot); + Event Player.botPreviousNodeId = Event Player.botClosestNodeIdToBot; + Event Player.botNextNodeId = Event Player.botClosestNodeIdToBot; + End; + Event Player.botNextNodePosition = Global.nodePositions[Event Player.botNextNodeId]; + } +} + +rule("SUBROUTINE: BOT - GET CLOSEST NODE ID AND POSITION TO TARGET") +{ + event + { + Subroutine; + BotGetClosestNodeIdToTarget; + } + + actions + { + Event Player.botTargetPosition = Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) + : Event Player.botTargetPosition; + Event Player.botClosestNodeIdToTarget = Index Of Array Value(Global.nodePositions, Sorted Array(Filtered Array( + Global.nodePositions, Is In Line of Sight(Event Player.botTargetPosition + Vector(0, 2, 0), Current Array Element, + Barriers Do Not Block LOS) == True), Distance Between(Event Player.botTargetPosition, Current Array Element))[0]); + } +} + +rule("BOT: PATH FINDING - START") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + (Event Player.botTargetPosition != -1 || Event Player.botTargetPlayer != -1) == True; + } + + actions + { + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - CANCEL") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.botIsPathFinding == True; + Event Player.botCancelPathFinding == True; + } + + actions + { + Start Rule(BotResetPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - LOST THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.botIsPathFinding == True; + (Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.botNextNodePosition + Vector(0, 2.500, 0), + Barriers Do Not Block LOS) == False && Speed Of In Direction(Event Player, Throttle Of(Event Player)) < 2) == True; + } + + actions + { + Wait(0.500, Abort When False); + "RESET PREV NODE ID TO INFORM BOT THAT IT LOST NEXT NODE" + Event Player.botPreviousNodeId = -1; + "TRY FIND NEW NEXT NODE" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodeId), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +rule("BOT: PATH FINDING - REACHED THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.botIsPathFinding == True; + Event Player.botClosestNodeIdToTarget >= 0; + (Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.botNextNodePosition), 0, Z Component Of(Event Player.botNextNodePosition))) < 0.850) == True; + } + + actions + { + Event Player.botPreviousNodeId = Event Player.botNextNodeId; + Event Player.botClosestNodeIdToBot = Event Player.botNextNodeId; + "BOT'S TARGET IS PLAYER" + If(Event Player.botTargetPlayer != -1); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + Event Player.botCurrentDistanceToTarget = Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of( + Position Of(Event Player))), Vector(X Component Of(Event Player.botTargetPosition), 0, Z Component Of( + Event Player.botTargetPosition))); + "BOT REACHED THE TARGET NODE OR TARGET POSITION" + If(Event Player.botNextNodeId == Event Player.botClosestNodeIdToTarget || Event Player.botCurrentDistanceToTarget <= 0.850); + "BOT DIDN'T REACH TARGET POSITION" + If(Event Player.botCurrentDistanceToTarget > 0.850); + Event Player.botNextNodePosition = Event Player.botTargetPosition; + Skip(6); + "BOT REACHED TARGET" + Else; + Call Subroutine(BotResetPathFinding); + Abort; + End; + End; + "CONTINUE FOLLOW PATH" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: GAME MODE INIT - WORKSHOP SETTINGS") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.isDebug = False; + Global.isDebugAINavigation = False; + Global.gateMaxHealth = Workshop Setting Integer(Custom String("Defend The Castle Extended"), Custom String("Gate Max Health"), 500, 100, 1000, + 0); + Global.moneyMultiplier = Workshop Setting Real(Custom String("Defend The Castle Extended"), Custom String("money Multiplicator"), 1, 0.500, 2, 0); + Global.isStoryHeroes = Workshop Setting Toggle(Custom String("Defend The Castle Extended"), Custom String("Story Heroes"), True, 0); + Global.selfNanoWorkshopSetting = Workshop Setting Toggle(Custom String("Ana Self Nano"), Custom String( + "Ana can nano herself even if there are other players (only if no player targeted)"), False, 0); + } +} + +rule("GLOBAL: GAME MODE INIT - COMMON PROPERTIES") +{ + event + { + Ongoing - Global; + } + + actions + { + Create HUD Text(All Players(All Teams), Null, Null, Custom String( + "Defend The Castle Extended v0.6.c127 BY ShuriZma#2349\r\nOriginal mode by HUKUTA94#2589\r\nDiscord: discord.shurizma.de\r\n{0}", Custom String( + "Special Thanks to:\nShingen#21859 for the abilities,\nLemonAid#11644 for the Hero Talents &\nJosbird for teaching me about Menus{0}", + Custom String(" \nPS: SHINGEN PLS COME BACK"))), Right, -1000, Null, Null, Color(White), Visible To, + Default Visibility); + Global.gateRepairPosition = Vector(153, 8, -46.500); + Global.gatePosition = Vector(148.800, 6, -46.400); + Global.ballSpawnPositions = Array(Vector(104, 7, -46), Vector(106, 2, -31)); + Global.sniperPositions = Array(Vector(154, 18, -22.600), Vector(86, 12, -46.600), Vector(80.880, 11.300, -71.600), Vector(98, 9, + -19)); + Global.zenSpawnPositions = Array(Vector(79.500, 5, -100), Vector(90, 4, -88), Vector(65, 11, -70), Vector(85, 4, -68), Vector(96, + 2, -73), Vector(84, 7, -47), Vector(95, 9, -34), Vector(108, 1.700, -28), Vector(113, 7, -37), Vector(123, 5, -19), Vector(144, + 5, -19), Vector(123, 6, -39), Vector(123, 6, -61), Vector(129, 6, -30.500), Vector(135, 6, -63)); + Global.playerSpawnPositions = Array(Vector(153.300, 10, -63.800), Vector(153.300, 10, -61.700), Vector(153.300, 10, -31.700), + Vector(153.300, 10, -29.600)); + Global.bigBossSpawnPositions = Array(Vector(78, 4, -84), Vector(95, 4, -82)); + Global.bastionTargetPositions = Array(Vector(131, 12, -62), Vector(115, 7, -46), Objective Position(2), Vector(136, 10, -27)); + Global.spawnPositionMaxId = 2; + Global.botOrisaTargetPosition = Vector(104, 7, -46); + Global.botEchoRespawnPosition = Vector(130, 23, -44); + Global.botEchoTeleportPositions = Array(Vector(88, 23, -79), Vector(108, 18, -27)); + Global.defaultHeroBotsPool = Array(Hero(Zenyatta), Hero(Widowmaker), Null, Hero(Bastion), Hero(Echo), Hero(Bastion)); + Global.zenRespawnTime = 10; + Global.gameLogicCountOfUniqueHeroes = 5; + Global.lastBoss = Array(Null, Null, Null, Null); + Create Effect(All Players(Team 1), Ring, Color(Sky Blue), Vector(186, 11, -46.500), 9, Visible To Position and Radius); + Create Effect(All Players(Team 1), Ring, Color(Yellow), Vector(149.000, 10, -62.000), 2, Visible To Position and Radius); + } +} + +disabled rule("PLAYER: DEBUG - PRESS INTERACT") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Host Player == True; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + disabled Modify Player Score(Event Player, 10); + disabled Global.gateHealth -= 5; + disabled Start Rule(GateProgressBarColor, Restart Rule); + Global.timeSec = 59; + Set Status(Event Player, Null, Phased Out, 9999); + disabled Set Ultimate Charge(Event Player, 100); + disabled Kill(Event Player, Null); + disabled Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: DEBUG - AI NAVIGATION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.isDebugAINavigation == True; + } + + actions + { + For Global Variable(loopIterator1, 0, Count Of(Global.nodePositions), 1); + Create Effect(All Players(All Teams), Sphere, Color(Red), Global.nodePositions[Global.loopIterator1], 0.850, Visible To); + Create In-World Text(All Players(All Teams), Custom String("NODE {0}", Global.loopIterator1), + Global.nodePositions[Global.loopIterator1], 1.200, Clip Against Surfaces, Visible To, Color(White), Default Visibility); + End; + } +} + +disabled rule("GLOBAL: DEBUG - CREATE BOTS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + Create Dummy Bot(Hero(Bastion), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + Create Dummy Bot(Hero(Orisa), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +disabled rule("PLAYER: DEBUG - INFOS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.isDebug == True; + Host Player == Event Player; + Has Spawned(Event Player) == True; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Create HUD Text(Event Player, Custom String("POS {0}\r\nFACING {1}", Position Of(Event Player), Facing Direction Of(Event Player)), + Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + Create HUD Text(Event Player, Custom String("SERVER PERFORMANCE\r\nLOAD {0}%\r\nPEAK {1}%\r\nAVG {2}%", Server Load, + Server Load Peak, Server Load Average), Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create Progress Bar HUD Text(Event Player, 45, Custom String("45 / 100 KILLS"), Left, -99, Color(Blue), Color(White), + Visible To Values and Color, Default Visibility); + disabled Create HUD Text(Event Player, Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Null, Custom String( + "LEVEL 1 - 50 AMMO CLIP"), Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + "ЭФФЕКТ С ОФФСЕТОМ ОТ ПОЗИЦИИ ГЛАЗ" + disabled Create Beam Effect(All Players(All Teams), Bad Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + Facing Direction Of( + Event Player) * 3, Eye Position(Event Player) + Facing Direction Of(Event Player) * 50, Color(Purple), + Visible To Position and Radius); + } +} + +disabled rule("=== TEAM UPGRADES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: TEAM UPGRADES - INIT") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.upgradeMaxAmmoMaxValue[0] = 250; + Global.upgradeMaxAmmoMaxValue[1] = 500; + Global.upgradeMaxAmmoMaxValue[2] = 1000; + Global.upgradeCriticalDamageMaxValue[0] = 10; + Global.upgradeCriticalDamageMaxValue[1] = 5; + Global.upgradeCriticalDamageMaxValue[2] = 5; + Global.upgradePlayerMaxHealthMaxValue[0] = 2500; + Global.upgradePlayerMaxHealthMaxValue[1] = 5000; + Global.upgradePlayerMaxHealthMaxValue[2] = 10000; + Global.upgradeGateMaxHealthMaxValue[0] = Round To Integer(Global.gateMaxHealth + Global.gateMaxHealth * 0.500, Up); + Global.upgradeGateMaxHealthMaxValue[1] = Global.upgradeGateMaxHealthMaxValue[0] + Global.upgradeGateMaxHealthMaxValue[0]; + Global.upgradeGateMaxHealthMaxValue[2] = Global.upgradeGateMaxHealthMaxValue[1] + Global.upgradeGateMaxHealthMaxValue[1]; + Abort If(Global.isDebug == False); + Global.upgradeMaxAmmoMaxValue[0] = 1; + Global.upgradeCriticalDamageMaxValue[0] = 1; + Global.upgradePlayerMaxHealthMaxValue[0] = 1; + Global.upgradeGateMaxHealthMaxValue[0] = 1; + Global.upgradeMaxAmmoMaxValue[1] = 1; + Global.upgradeCriticalDamageMaxValue[1] = 1; + Global.upgradePlayerMaxHealthMaxValue[1] = 1; + Global.upgradeGateMaxHealthMaxValue[1] = 1; + Global.upgradeMaxAmmoMaxValue[2] = 1; + Global.upgradeCriticalDamageMaxValue[2] = 1; + Global.upgradePlayerMaxHealthMaxValue[2] = 1; + Global.upgradeGateMaxHealthMaxValue[2] = 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GATE'S MAX HEALTH UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.gatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.gatePosition, 100); + Global.gateMaxHealth = Global.upgradeGateMaxHealthMaxValue[0]; + Global.gateHealth = Global.gateMaxHealth; + Destroy HUD Text(Global.upgradeGateMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("GATE'S MAX HEALTH: {0} HP", Global.upgradeGateMaxHealthMaxValue[0]), Right, 1, Color( + Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeGateMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X GATE REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.upgradeGateMaxHealthValue, Global.upgradeGateMaxHealthMaxValue[1]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.upgradeGateMaxHealthHudId[1] = Last Text ID; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X GATE REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.gatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.gatePosition, 100); + Destroy HUD Text(Global.upgradeGateMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X GATE REPAIR"), Right, 2, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.upgradeGateMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X AUTO-REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.upgradeGateMaxHealthValue, Global.upgradeGateMaxHealthMaxValue[2]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.upgradeGateMaxHealthHudId[2] = Last Text ID; + Global.gateHealth = Global.gateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 3 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X AUTO-REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.gatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.gatePosition, 100); + Destroy HUD Text(Global.upgradeGateMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X AUTO-REPAIR"), Right, 3, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.upgradeGateMaxHealthHudId[2] = Last Text ID; + Global.gateHealth = Global.gateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - PLAYER'S MAX HEALTH - DEALT HEALING") +{ + event + { + Player Received Healing; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + disabled Healer != Event Player; + Global.upgradePlayerMaxHealthValue < Global.upgradePlayerMaxHealthMaxValue[2]; + } + + actions + { + Global.upgradePlayerMaxHealthValue += Event Healing; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH UNLOCKED!")); + Destroy HUD Text(Global.upgradePlayerMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +50%"), Right, 4, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradePlayerMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("Up You Go: You respawn twice as fast"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.upgradePlayerMaxHealthValue, Down), + Global.upgradePlayerMaxHealthMaxValue[1]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.upgradePlayerMaxHealthHudId[1] = Last Text ID; + For Global Variable(loopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 100); + End; + Global.maxHealthDone = 50; + All Players(Team 1).playerHealth = 100 + Global.maxHealthDone + All Players(Team 1).abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).playerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK UP YOU GO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("UP YOU GO UNLOCKED!")); + Destroy HUD Text(Global.upgradePlayerMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String("Up You Go"), + Right, 5, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradePlayerMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +100%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.upgradePlayerMaxHealthValue, Down), + Global.upgradePlayerMaxHealthMaxValue[2]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.upgradePlayerMaxHealthHudId[2] = Last Text ID; + Set Respawn Max Time(All Players(Team 1), 5); + Heal(All Players(Team 1), Null, 9999); + For Global Variable(loopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 100); + End; + Global.perk[2] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).abilityHUD[17] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH 2 UNLOCKED!")); + Destroy HUD Text(Global.upgradePlayerMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +100%"), Right, 6, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradePlayerMaxHealthHudId[2] = Last Text ID; + For Global Variable(loopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 100); + End; + Global.maxHealthDone = 150; + All Players(Team 1).playerHealth = 100 + Global.maxHealthDone + All Players(Team 1).abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).playerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Hero Of(Victim) == Hero(Widowmaker); + Global.upgradeCriticalDamageValue < Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.upgradeCriticalDamageValue += 1; + Small Message(All Players(Team 1), Custom String("CRITICAL DAMAGE CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - CRITICAL DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.upgradeCriticalDamageValue >= Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("CRITICAL DAMAGE 150% UNLOCKED!")); + Destroy HUD Text(Global.upgradeCriticalDamageHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "CRITICAL DAMAGE 150%"), Right, 7, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeCriticalDamageHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String( + "Sharpshooter: Deal 40% more damage to enemies that are further than 15 meters away"), Custom String("KILL ECHO {0}/{1}", + Global.upgradePerkSharpshooterValue, Global.upgradeCriticalDamageMaxValue[1]), Left, 14, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.upgradeCriticalDamageHudId[1] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - UNLOCKED") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Global.upgradeCriticalDamageValue >= Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.500); + } +} + +rule("PLAYER: UPGRADE - PERK SHARPSHOOTER - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Echo); + Global.upgradePerkSharpshooterValue < Global.upgradeCriticalDamageMaxValue[1]; + Global.upgradeCriticalDamageValue >= Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.upgradePerkSharpshooterValue += 1; + Small Message(All Players(Team 1), Custom String("SHARPSHOOTER CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - PERK SHARPSHOOTER - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.upgradePerkSharpshooterValue >= Global.upgradeCriticalDamageMaxValue[1]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("SHARPSHOOTER UNLOCKED!")); + Destroy HUD Text(Global.upgradeCriticalDamageHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Sharpshooter"), Right, 8, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeCriticalDamageHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("-10% BOSS HEALTH"), Custom String("KILL Bosses {0}/{1}", + Global.upgradeBossHealthValue, Global.upgradeCriticalDamageMaxValue[2]), Left, 14, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.upgradeCriticalDamageHudId[2] = Last Text ID; + Global.perk[0] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).abilityHUD[18] = Last Text ID; + Global.challengeCount += 1; + } +} + +disabled rule("PLAYER: UPGRADE - -10% BOSS HEALTH - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Global.upgradePerkSharpshooterValue >= Global.upgradeCriticalDamageMaxValue[1]; + Global.upgradeBossHealthValue < Global.upgradeCriticalDamageMaxValue[2]; + Victim.isBoss == 1; + } + + actions + { + Global.upgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - -10% BOSS HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("-10% BOSS HEALTH UNLOCKED!")); + Destroy HUD Text(Global.upgradeCriticalDamageHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "-10% BOSS HEALTH"), Right, 9, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeCriticalDamageHudId[2] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - MAX AMMO - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Zenyatta); + Global.upgradeMaxAmmoValue < Global.upgradeMaxAmmoMaxValue[2]; + } + + actions + { + If(Event Player.isBoss == 1); + Global.upgradeMaxAmmoValue += 10; + Else; + Global.upgradeMaxAmmoValue += 1; + End; + } +} + +rule("GLOBAL: UPGRADE - MAX AMMO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("MAX AMMO 200% UNLOCKED!")); + Destroy HUD Text(Global.upgradeMaxAmmoHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "MAX AMMO 200%"), Right, 10, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("Bulletstorm: Your weapon can hold unlimited ammo"), + Custom String("KILL {2}: {0}/{1}", Global.upgradeMaxAmmoValue, Global.upgradeMaxAmmoMaxValue[1], Hero(Zenyatta)), Left, 15, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.upgradeMaxAmmoHudId[1] = Last Text ID; + For Global Variable(loopIterator1, 0, Count Of(All Players(Team 1)), 1); + Set Max Ammo(All Players(Team 1)[Global.loopIterator1], 0, Max Ammo(All Players(Team 1)[Global.loopIterator1], 0) * 2); + Set Max Ammo(All Players(Team 1)[Global.loopIterator1], 1, Max Ammo(All Players(Team 1)[Global.loopIterator1], 1) * 2); + Set Ammo(All Players(Team 1)[Global.loopIterator1], 0, Max Ammo(All Players(Team 1)[Global.loopIterator1], 0)); + Set Ammo(All Players(Team 1)[Global.loopIterator1], 1, Max Ammo(All Players(Team 1)[Global.loopIterator1], 1)); + End; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK BULLETSTORM - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("BULLETSTORM UNLOCKED!")); + Destroy HUD Text(Global.upgradeMaxAmmoHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Bulletstorm"), Right, 11, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeMaxAmmoHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("+50% DAMAGE"), Custom String("KILL {2}: {0}/{1}", + Global.upgradeMaxAmmoValue, Global.upgradeMaxAmmoMaxValue[2], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.upgradeMaxAmmoHudId[2] = Last Text ID; + Global.perk[1] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).abilityHUD[19] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - +50% DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("+50% DAMAGE UNLOCKED!")); + Destroy HUD Text(Global.upgradeMaxAmmoHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "+50% DAMAGE"), Right, 12, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeMaxAmmoHudId[2] = Last Text ID; + Global.damageDealt = 50; + All Players(Team 1).damageDealt = 100 + Global.damageDealt + All Players(Team 1).abilities[13] * 5; + Set Damage Dealt(All Players(Team 1), All Players(Team 1).damageDealt); + Global.challengeCount += 1; + } +} + +disabled rule("=== GAME PHASES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: ASEMBLING PHASE - MAKE CHALLENGES HUDS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Assembling Heroes == True; + } + + actions + { + If(Global.isDebug); + Set Match Time(1); + Else; + Disable Inspector Recording; + Set Match Time(20); + End; + Create In-World Text(All Players(Team 1), Custom String(" {0}\r\nREPAIR\r\n {1}", Hero Icon String(Hero(Torbjörn)), + Ability Icon String(Hero(Bastion), Button(Secondary Fire))), Global.gatePosition + Vector(0, 1.400, 0), 1.200, Do Not Clip, + Visible To, Color(White), Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("TEAM CHALLENGES"), Left, 11, Color(White), Color(Blue), Color( + White), Visible To, Default Visibility); + "UPGRADE - GATE'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String( + "GATE'S MAX HEALTH: {0} HP", Global.upgradeGateMaxHealthMaxValue[0]), Custom String("REPAIR GATE {0}/{1} HP", + Global.upgradeGateMaxHealthValue, Global.upgradeGateMaxHealthMaxValue[0]), Left, 12, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.upgradeGateMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 2, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - PLAYER'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +50%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.upgradePlayerMaxHealthValue, Down), + Global.upgradePlayerMaxHealthMaxValue[0]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.upgradePlayerMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 4, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - CRITICAL DAMAGE" + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("CRITICAL DAMAGE 150%"), Custom String( + "KILL WIDOW WITH HEADSHOT: {0}/{1}", Global.upgradeCriticalDamageValue, Global.upgradeCriticalDamageMaxValue[0]), Left, 14, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.upgradeCriticalDamageHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 6, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - MAX AMMO" + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("MAX AMMO 200%"), Custom String("KILL {2}: {0}/{1}", + Global.upgradeMaxAmmoValue, Global.upgradeMaxAmmoMaxValue[0], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.upgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Custom String("HOLD {0} - Reload to open the shop", Input Binding String(Button(Reload))), + Null, Null, Top, 1000, Color(Yellow), Color(White), Color(White), Visible To and String, Default Visibility); + } +} + +rule("GLOBAL: SETUP PHASE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + If(Global.isDebug); + Set Match Time(1); + Else; + Pause Match Time; + Create HUD Text(All Players(Team 1), Custom String("PRESS {0} TO START", Button(Interact)), Null, Null, Top, 50, Color(Red), Color( + White), Color(White), Visible To and String, Default Visibility); + Global.globalHUDs[0] = Last Text ID; + Set Match Time(20); + Wait Until(Is True For Any(All Players(Team 1), Is Button Held(Current Array Element, Button(Interact))), 99999); + Destroy HUD Text(Global.globalHUDs[0]); + Unpause Match Time; + End; + Set Objective Description(All Players(All Teams), Custom String("DEFEND GATE"), Visible To and String); + } +} + +rule("GLOBAL: GAME IN PROGRESS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + } + + actions + { + Set Match Time(3599); + Pause Match Time; + Disable Built-In Game Mode Scoring; + Disable Built-In Game Mode Announcer; + Disable Built-In Game Mode Completion; + Disable Game Mode HUD(All Players(All Teams)); + Disable Game Mode In-World UI(All Players(All Teams)); + Global.gateHealth = Global.gateMaxHealth; + Global.gateHealthChase = Global.gateHealth; + Global.gateProgressBarColorComponent = 255; + Global.gateProgressBarColorCurrent = Color(White); + Create Progress Bar HUD Text(All Players(Team 1), Global.gateHealthChase * 100 / Global.gateMaxHealth, Custom String( + "GATE {0}/{1}", Global.gateHealth, Global.gateMaxHealth), Top, 1, Global.gateProgressBarColorCurrent, Color(White), + Visible To Values and Color, Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("SURVIVED TIME: {0}:{1}", Global.timeMin, + Global.timeSec < 10 ? Custom String("0{0}", Global.timeSec) : Global.timeSec), Top, 2, Color(White), Color(White), Color( + White), Visible To and String, Default Visibility); + Start Rule(GameLogicWave0, Do Nothing); + } +} + +disabled rule("=== GAME - MAIN LOGIC ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: DEFEAT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.isDebug == False; + Global.gateHealth <= 0; + } + + actions + { + Declare Team Victory(Team 2); + } +} + +rule("GLOBAL: TIMER - MAIN GAME LOOP") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + disabled Global.gateHealth > 0; + } + + actions + { + Wait(1, Ignore Condition); + Global.timeSec += 1; + If(Global.timeSec == 60); + Global.timeSec = 0; + Global.timeMin += 1; + Global.time5Min = Round To Integer(Global.timeMin / 5, Down); + Global.time10Min = Round To Integer(Global.timeMin / 10, Down); + Global.spawnPositionMaxId += 1; + disabled Start Rule(gameLogicAddNextHeroInGame, Restart Rule); + Else If(Global.timeSec == 30); + Global.spawnPositionMaxId += 1; + End; + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GAME LOGIC - ADD NEXT HERO IN GAME") +{ + event + { + Subroutine; + gameLogicAddNextHeroInGame; + } + + actions + { + "REDUCE RESPAWN TIME FOR ZENS" + disabled Global.zenRespawnTime -= 1.500; + disabled Global.zenRespawnTime = Max(1, Global.zenRespawnTime); + disabled Set Respawn Max Time(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Global.defaultHeroBotsPool[0]), + Global.zenRespawnTime); + "ALL HEROES WAS ADDED IN GAME" + Abort If(Global.defaultHeroBotsPoolCurrentId == Count Of(Global.defaultHeroBotsPool) - 1); + Global.defaultHeroBotsPoolCurrentId += 1; + "ВРЕМЕННЫЙ КОСТЫЛЬ ЧТОБЫ ЭХО ЗАМЕНИЛА ХАМСТЕРА" + If(Global.defaultHeroBotsPool[Global.defaultHeroBotsPoolCurrentId] == Hero(Echo)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Abort; + End; + "ABORT IF NEXT HERO IN ARRAY ORDER IS NULL" + Abort If(Global.defaultHeroBotsPool[Global.defaultHeroBotsPoolCurrentId] == Null); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Global.defaultHeroBotsPool[Global.defaultHeroBotsPoolCurrentId], Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("SUBROUTINE: GAME LOGIC - SET BOT PROPERTIES") +{ + event + { + Subroutine; + gameLogicSetBotProperties; + } + + actions + { + Abort If(Event Player.botIsOrisaChild == True); + If(Global.timeMin >= 10); + If(Filtered Array(Global.lastBoss, Current Array Element == Hero Of(Event Player)) == False); + If(Global.activeBoss == False); + If(Global.bossTrigger < Global.timeMin); + Global.bossTrigger = Global.timeMin; + Global.activeBoss = Event Player; + Event Player.isBoss = 1; + Big Message(All Players(Team 1), Custom String("BOSS SPAWNED - {0}", Hero Of(Event Player))); + End; + End; + End; + End; + "PROPERTIES BY DEFAULT" + Set Gravity(Event Player, 100); + Set Damage Dealt(Event Player, 100); + Set Respawn Max Time(Event Player, 10); + Start Scaling Player(Event Player, 1, False); + "INDIVIDUAL HERO'S PROPERTIES" + If(Hero Of(Event Player) == Hero(Zenyatta)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 30); + Set Max Health(Event Player, 10 * (100 + 10 * Global.timeMin + 25 * Global.time5Min + 50 * Global.time10Min) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 1.500, False); + Else; + If(20 + 3 * Number Of Players(Team 1) + 3 * Global.timeMin > 75); + Set Move Speed(Event Player, 75); + Else; + Set Move Speed(Event Player, 20 + 3 * Count Of(All Players(Team 1)) + 3 * Global.timeMin); + End; + Set Max Health(Event Player, 100 + 10 * Global.timeMin + 25 * Global.time5Min + 50 * Global.time10Min); + End; + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 20); + Set Max Health(Event Player, 5 * (70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.timeMin + 25 * Global.time5Min + 50 * Global.time10Min) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + If(30 + Global.timeMin + 2.500 * Global.time5Min > 40); + Set Move Speed(Event Player, 40); + Else; + Set Move Speed(Event Player, 30 + Global.timeMin + 2.500 * Global.time5Min); + End; + Set Ultimate Charge(Event Player, 0); + Set Max Health(Event Player, 70 + 20 * Count Of(All Players(Team 1)) + 10 * Global.timeMin + 25 * Global.time5Min + 50 * Global.time10Min); + End; + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + If(Event Player.isBoss == 1); + Set Damage Dealt(Event Player, 2 * (85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.time5Min + 50 * Global.time10Min)); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 5 * (100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.timeMin + 15 * Global.time5Min + 40 * Global.time10Min) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Event Player.botCounter = 0; + Set Damage Dealt(Event Player, 85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.time5Min + 50 * Global.time10Min); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 100 + 25 * Count Of(All Players(Team 1)) + 5 * Global.timeMin + 15 * Global.time5Min + 40 * Global.time10Min); + End; + Else If(Hero Of(Event Player) == Hero(Bastion)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 50); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Min + 10 * Global.time10Min); + Start Scaling Player(Event Player, 3, False); + Set Max Health(Event Player, 5 * (155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.timeMin + 40 * Global.time5Min + 65 * Global.time10Min) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Else; + Set Move Speed(Event Player, 80); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Min + 10 * Global.time10Min); + Start Scaling Player(Event Player, 2, False); + Set Max Health(Event Player, 155 + 150 * Count Of(All Players(Team 1)) + 20 * Global.timeMin + 40 * Global.time5Min + 65 * Global.time10Min); + End; + Else If(Hero Of(Event Player) == Hero(Orisa)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 5 * (220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.time5Min + 100 * Global.time10Min) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Set Move Speed(Event Player, 30 + 5 * Global.time5Min); + Else; + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.time5Min + 100 * Global.time10Min); + Set Move Speed(Event Player, 90 + 5 * Global.time5Min); + End; + Else If(Hero Of(Event Player) == Hero(Echo)); + If(Event Player.isBoss == 1); + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 70 + 5 * Global.time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 5 * (90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.timeMin + 25 * Global.time5Min + 50 * Global.time10Min) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 130 + 5 * Global.time5Min); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 90 + 25 * Count Of(All Players(Team 1)) + 15 * Global.timeMin + 25 * Global.time5Min + 50 * Global.time10Min); + End; + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.500, False); + Set Move Speed(Event Player, 70); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Min + 10 * Global.time10Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 5 * (55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.timeMin + 25 * Global.time5Min + 50 * Global.time10Min) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Else; + disabled Start Scaling Player(Event Player, 0.850, False); + Set Move Speed(Event Player, 110); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Min + 10 * Global.time10Min); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 55 + 25 * Count Of(All Players(Team 1)) + 15 * Global.timeMin + 25 * Global.time5Min + 50 * Global.time10Min); + End; + End; + Wait(0.250, Ignore Condition); + "FILL HEALTH" + Heal(Event Player, Null, 100000); + } +} + +disabled rule("=== GATE ===") +{ + event + { + Ongoing - Global; + } +} + +rule("Subroutine: GATE REPAIR") +{ + event + { + Subroutine; + GateRepair; + } + + actions + { + Small Message(Event Player, Custom String("REPAIR +2% ULTIMATE")); + "UPGRADE - GATE'S MAX HEALTH" + If(Global.upgradeGateMaxHealthValue < Global.upgradeGateMaxHealthMaxValue[2]); + If(Event Player.isNanoed == 1); + If(Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1]); + Global.upgradeGateMaxHealthValue += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.upgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1]); + Global.upgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.upgradeGateMaxHealthValue += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + End; + End; + "HEAL GATE" + If(Event Player.isNanoed == 1); + If(Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1]); + Global.gateHealth += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.gateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1]); + Global.gateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.gateHealth += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + If(Global.gateHealth > Global.gateMaxHealth); + Global.gateHealth = Global.gateMaxHealth; + "CHARGE ULTIMATE" + Else; + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + End; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + } +} + +rule("TORB: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Has Spawned(Event Player) == True; + Weapon(Event Player) == 2; + Is Firing Primary(Event Player) == True; + Global.gateHealth < Global.gateMaxHealth; + Is In View Angle(Event Player, Global.gateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.gatePosition) < 3.500; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(Is Using Ability 2(Event Player) == True ? 0.350 : 0.700, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Brig: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.gateHealth < Global.gateMaxHealth; + Is In View Angle(Event Player, Global.gateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.gatePosition) < 5; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Rein: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.gateHealth < Global.gateMaxHealth; + Is In View Angle(Event Player, Global.gateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.gatePosition) < 3; + Is Game In Progress == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Call Subroutine(GateRepair); + Wait(0.850, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GATE PROGRESS BAR COLOR") +{ + event + { + Subroutine; + GateProgressBarColor; + } + + actions + { + Stop Chasing Global Variable(gateHealthChase); + Chase Global Variable Over Time(gateHealthChase, Global.gateHealth, 0.100, Destination and Duration); + "GATE WAS DAMAGED" + If(Global.gateHealth < Global.gateHealthEvent); + For Global Variable(loopIterator1, 0, 3, 1); + Global.gateProgressBarColorCurrent = Color(Red); + Wait(0.030, Ignore Condition); + Global.gateProgressBarColorCurrent = Color(White); + Wait(0.030, Ignore Condition); + End; + "GATE WAS REPAIRED" + Else; + Global.gateProgressBarColorCurrent = Color(Green); + Wait(0.030, Ignore Condition); + Global.gateProgressBarColorCurrent = Color(Yellow); + Wait(0.030, Ignore Condition); + End; + Global.gateHealthEvent = Global.gateHealth; + Global.gateProgressBarColorComponent = Global.gateHealth * 255 / Global.gateMaxHealth; + Global.gateProgressBarColorCurrent = Custom Color(255, Global.gateProgressBarColorComponent, Global.gateProgressBarColorComponent, + 255); + } +} + +disabled rule("=== COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("ALL: INIT") +{ + event + { + Player Joined Match; + All; + All; + } + + actions + { + "ALL (COMMON) INIT" + Event Player.isDead = True; + Disable Kill Feed(Event Player); + Disable Game Mode In-World UI(Event Player); + Disable Death Spectate Target HUD(Event Player); + "BOT INIT" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotInit); + "PLAYER INIT" + Else; + Call Subroutine(PlayerInit); + End; + } +} + +rule("SUBROUTINE: BOT - INIT") +{ + event + { + Subroutine; + BotInit; + } + + actions + { + "INIT VARS" + Event Player.hasBadStatus = False; + Event Player.isRespawning = False; + Event Player.botDoesUniqueBehaviour = False; + Event Player.botEventPosition = Vector(9999, 999, 9999); + "DISABLE ALL FOR BOT" + Disable Hero HUD(Event Player); + Disable Messages(Event Player); + Disable Text Chat(Event Player); + Disable Scoreboard(Event Player); + Disable Game Mode HUD(Event Player); + Disable Death Spectate All Players(Event Player); + Disable Voice Chat(Event Player, True, True, True); + "INIT AI NAVIGATION VARS" + Call Subroutine(BotResetPathFinding); + } +} + +rule("SUBROUTINE: PLAYER - INIT") +{ + event + { + Subroutine; + PlayerInit; + } + + actions + { + "STORY HEROES" + If(Global.isStoryHeroes); + Reset Player Hero Availability(Event Player); + Set Player Allowed Heroes(Event Player, Array(Hero(Ana), Hero(Brigitte), Hero(Mercy), Hero(Lúcio), Hero(Moira), Hero(Baptiste), + Hero(Ashe), Hero(D.Va), Hero(Genji), Hero(Hanzo), Hero(Widowmaker), Hero(Cassidy), Hero(Reinhardt), Hero(Soldier: 76), Hero( + Torbjörn), Hero(Tracer), Hero(Winston), Hero(Pharah))); + End; + "TEAM CHALLENGE - PLAYER'S MAX HEALTH" + If(Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[0]); + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + End; + If(Is Game In Progress); + Disable Game Mode HUD(Event Player); + End; + } +} + +rule("ALL: RESPAWN") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + (Hero Of(Event Player) != Event Player.currentHero || Event Player.isDead == True) == True; + } + + actions + { + Event Player.isDead = False; + "BOT RESPAWN" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotRespawn); + If(Global.isDebugAINavigation); + Create Beam Effect(All Players(All Teams), Good Beam, Eye Position(Event Player), Event Player.botNextNodePosition, Color(Green), + Visible To Position and Radius); + End; + "PLAYER RESPAWN" + Else; + Call Subroutine(PlayerRespawn); + End; + "MUST BE AFTER ALL RESPAWN SUBROUTINES!" + Event Player.currentHero = Hero Of(Event Player); + } +} + +rule("SUBROUTINE: BOT - RESPAWN") +{ + event + { + Subroutine; + BotRespawn; + } + + actions + { + "RESET COMMON PROPERTIES" + Event Player.isRespawning = True; + Enable Nameplates(Event Player, All Players(Team 1)); + Call Subroutine(BotResetPathFinding); + disabled If(Hero Of(Event Player) != Event Player.currentHero); + Call Subroutine(gameLogicSetBotProperties); + disabled End; + "INDIVIDUAL HERO'S RESPAWN SCRIPTS" + If(Hero Of(Event Player) == Hero(Bastion)); + Call Subroutine(botBastionRespawn); + Else If(Hero Of(Event Player) == Hero(Zenyatta)); + Call Subroutine(botZenyattaRespawn); + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + Call Subroutine(botWidowRespawn); + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Call Subroutine(botBallRespawn); + Else If(Hero Of(Event Player) == Hero(Orisa)); + Call Subroutine(botOrisaRespawn); + Else If(Hero Of(Event Player) == Hero(Echo)); + Call Subroutine(botEchoRespawn); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Call Subroutine(BotReinRespawn); + End; + Event Player.isRespawning = False; + } +} + +rule("SUBROUTINE: PLAYER - RESPAWN") +{ + event + { + Subroutine; + PlayerRespawn; + } + + actions + { + "TEAM CHALLENGE - MAX AMMO" + If(Hero Of(Event Player) != Event Player.currentHero && Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[0]); + Set Max Ammo(Event Player, 0, Ammo(Event Player, 0) * 2); + Set Max Ammo(Event Player, 1, Ammo(Event Player, 1) * 2); + Set Ammo(Event Player, 0, Max Ammo(Event Player, 0)); + Set Ammo(Event Player, 1, Max Ammo(Event Player, 1)); + End; + "MUST BE AFTER TEAM CHALLENGE MAX AMMO!" + disabled Event Player.currentHero = Hero Of(Event Player); + "PLAYER RESPAWN" + Set Status(Event Player, Null, Phased Out, 3); + Set Facing(Event Player, Vector(-1, 0, 0), To World); + If(Ability Cooldown(Players On Hero(Hero(Mercy), Team 1), Button(Ability 2)) >= 29); + Wait(0.250, Ignore Condition); + Teleport(Event Player, Event Player.deathPosition); + Else; + Teleport(Event Player, Global.playerSpawnPositions[Slot Of(Event Player) == Count Of(Global.playerSpawnPositions) ? Random Integer( + 0, Count Of(Global.playerSpawnPositions) - 1) : Slot Of(Event Player)]); + End; + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + } +} + +rule("PLAYER: DEATH") +{ + event + { + Player Died; + Team 1; + All; + } + + actions + { + If(Hero Of(Event Player) == Hero(Roadhog)); + Event Player.abilities[8] -= 1; + Wait(Global.perk[2] ? 5 : 10, Ignore Condition); + Event Player.abilities[8] += 1; + End; + Event Player.deathPosition = Position Of(Event Player); + disabled If(Event Player.lastSecondWind > 0); + disabled Event Player.lastSecondWind = 0; + disabled End; + Event Player.isDead = True; + } +} + +rule("BOT: DEATH") +{ + event + { + Player Died; + Team 2; + All; + } + + actions + { + If(Event Player.isBoss == 1); + If(Global.upgradePerkSharpshooterValue >= Global.upgradeCriticalDamageMaxValue[1]); + If(Global.upgradeBossHealthValue < Global.upgradeCriticalDamageMaxValue[2]); + Global.upgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + End; + End; + Event Player.isBoss = 0; + Global.activeBoss = Null; + Big Message(All Players(Team 1), Custom String("BOSS DIED - {0}", Hero Of(Event Player))); + End; + Event Player.isDead = True; + Event Player.hasBadStatus = False; + Event Player.botDoesUniqueBehaviour = False; + Disable Nameplates(Event Player, All Players(Team 1)); + disabled Stop Holding Button(Event Player, Button(Ability 1)); + disabled Stop Holding Button(Event Player, Button(Primary Fire)); + disabled Stop Holding Button(Event Player, Button(Secondary Fire)); + "BOT HAS 1 EFFECT IN VAR (NOT ARRAY)" + Skip If(!Entity Exists(Event Player.botEffects), 1); + Destroy Effect(Event Player.botEffects); + "BOT HAS MORE THEN 1 EFFECT IN VAR (ARRAY)" + Skip If(Count Of(Event Player.botEffects) == 0, 3); + For Player Variable(Event Player, botLoopIterator1, 0, Count Of(Event Player.botEffects), 1); + Destroy Effect(Event Player.botEffects[Event Player.botLoopIterator1]); + End; + } +} + +disabled rule("=== BOT COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BAD STATUS") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.hasBadStatus == False; + (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + Event Player.hasBadStatus = True; + "PROCESS BAD STATUS" + If(Hero Of(Event Player) == Hero(Widowmaker)); + Start Rule(BotWidowBadStatus, Do Nothing); + End; + Wait Until(!Has Status(Event Player, Knocked Down) && !Has Status(Event Player, Asleep) && !Has Status(Event Player, Frozen) + && !Has Status(Event Player, Stunned), 15); + Event Player.hasBadStatus = False; + } +} + +rule("SUBROUTINE: BOT - LANDING FROM SKY") +{ + event + { + Subroutine; + botLandingFromSky; + } + + actions + { + Stop Throttle In Direction(Event Player); + "SET RESPAWN POSITION" + Event Player.botEventPosition = Random Value In Array(Global.bigBossSpawnPositions); + "CREATE EFFECTS" + disabled Create Effect(All Players(All Teams), Light Shaft, Color(Red), Event Player.botEventPosition, 3, Visible To); + disabled Event Player.botEffects = Last Created Entity; + "RESPAWN IN LIGHT SHAFT EFFECT" + Teleport(Event Player, Event Player.botEventPosition + Vector(0, 25, 0)); + Wait(0.020, Ignore Condition); + "SLOW LANDING" + Set Gravity(Event Player, 50); + While(Is In Air(Event Player) == True); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Position Of(Event Player) + Vector(0, -2.700, 0), 2); + Wait(0.250, Ignore Condition); + End; + Set Gravity(Event Player, 100); + disabled Destroy Effect(Event Player.botEffects); + "LANDING EFFECTS" + Play Effect(All Players(All Teams), Wrecking Ball Piledriver Impact Effect, Custom Color(105, 87, 46, 255), Position Of( + Event Player), 8); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Sound, Color(White), Position Of(Event Player), 150); + } +} + +rule("SUBROUTINE: BOT - APPEAR FROM UNDERGROUND") +{ + event + { + Subroutine; + botAppearFromUnderground; + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1); + Wait(0.200, Ignore Condition); + Set Gravity(Event Player, 20); + Disable Movement Collision With Environment(Event Player, True); + Teleport(Event Player, Global.zenSpawnPositions[Random Integer(Min(Global.timeMin, Count Of(Global.zenSpawnPositions) - 10), Min( + Global.spawnPositionMaxId, Count Of(Global.zenSpawnPositions) - 4))] + Vector(0, -1.500, 0)); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Sigma Accretion Impact Effect, Custom Color(220, 175, 100, 255), Eye Position(Event Player), + 3); + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(Gray), Eye Position(Event Player), 50); + Apply Impulse(Event Player, Up, 3.500, To World, Cancel Contrary Motion); + Wait(0.400, Ignore Condition); + Clear Status(Event Player, Knocked Down); + Set Gravity(Event Player, 100); + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("=== PLAYER MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("PLAYER: DARKNESS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + !Entity Exists(Event Player.botEffects) == True; + } + + actions + { + Disable Nameplates(Event Player, All Players(All Teams)); + Start Forcing Player Outlines(Event Player, All Players(All Teams), False, Color(White), Default); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 14), 25, Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(-5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + } +} + +rule("PLAYER: HEALTH REGEN") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + actions + { + Stop Heal Over Time(Event Player.healOverTimeId); + Event Player.eventHealth = Health(Event Player); + Wait(4, Ignore Condition); + "TOOK DAMAGE, RESET REGENERATION TIMER" + Loop If(Is Alive(Event Player) && Event Player.eventHealth > Health(Event Player)); + Start Heal Over Time(Event Player, Null, 3, Max Health(Event Player) / 3); + Event Player.healOverTimeId = Last Heal Over Time ID; + } +} + +disabled rule("=== NERFS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("REINHARDT: ANTI-CHARGE FOR BASTION & ORISA") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Using Ability 1(Event Player) == True; + Hero Of(Ray Cast Hit Player(Eye Position(Event Player) + Vector(0, 2, 0), Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 2, All Living Players(Team 2), Event Player, True)) == (Hero(Bastion) == True || Hero( + Orisa) == True); + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1.500); + } +} + +rule("HOG: ANTI-HOOK FOR BASTION & ORISA") +{ + event + { + Player Dealt Damage; + Team 1; + Roadhog; + } + + conditions + { + Event Ability == Button(Ability 1); + (Hero Of(Victim) == Hero(Bastion) || Hero Of(Victim) == Hero(Orisa)) == True; + } + + actions + { + Set Status(Event Player, Null, Stunned, 0.005); + } +} + +disabled rule("=== ZENYATTA ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ZEN - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Zenyatta; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + } + + actions + { + Set Ammo(Event Player, 0, 0); + Communicate(Event Player, Hello); + disabled Call Subroutine(BotResetPathFinding); + Wait(1.500, Ignore Condition); + Abort If(Is Dead(Event Player) == True); + Kill(Event Player, Null); + } +} + +rule("BOT: ZEN - DEATH") +{ + event + { + Player Died; + Team 2; + Zenyatta; + } + + actions + { + "EFFECT" + Play Effect(All Players(All Teams), Junkrat Frag Launcher Explosion Effect, Color(Red), Eye Position(Event Player), 2.500); + Play Effect(All Players(All Teams), Ashe Dynamite Explosion Sound, Color(Red), Eye Position(Event Player), 70); + "DAMAGE AND APPLY IMPULSE TO PLAYERS" + Event Player.botPlayersInRadius = Players Within Radius(Position Of(Event Player), 2.500, All Teams, Surfaces And Enemy Barriers); + For Player Variable(Event Player, botLoopIterator1, 0, Count Of(Event Player.botPlayersInRadius), 1); + Apply Impulse(Event Player.botPlayersInRadius[Event Player.botLoopIterator1], Direction Towards(Position Of(Event Player), + Eye Position(Event Player.botPlayersInRadius[Event Player.botLoopIterator1])), 5, To World, Incorporate Contrary Motion); + If(Team Of(Event Player.botPlayersInRadius[Event Player.botLoopIterator1]) == Team 1); + Damage(Event Player.botPlayersInRadius[Event Player.botLoopIterator1], Event Player, 50); + End; + End; + "DAMAGE GATE" + If(Distance Between(Position Of(Event Player), Global.gatePosition) < 3 && Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.gateHealth -= 125; + Else; + Global.gateHealth -= 25; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Respawn(Event Player); + Abort; + End; + "KILLED BY PLAYER" + Teleport(Event Player, Vector(0, -999, 0)); + Wait(2, Ignore Condition); + Respawn(Event Player); + Wait(2, Ignore Condition); + } +} + +rule("SUBROUTINE: ZEN - RESPAWN") +{ + event + { + Subroutine; + botZenyattaRespawn; + } + + actions + { + Call Subroutine(botAppearFromUnderground); + Event Player.botTargetPosition = Global.gatePosition; + Event Player.botIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WRECKING BALL ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BALL - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + disabled Distance Between(Position Of(Event Player), Global.gatePosition) < 3; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Set Ammo(Event Player, 0, 0); + Wait(1, Ignore Condition); + Set Ultimate Charge(Event Player, 100); + Start Holding Button(Event Player, Button(Ultimate)); + Wait Until(Is Using Ultimate(Event Player), 0.600); + Abort If(Is Dead(Event Player)); + Kill(Event Player, Null); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Effect, Color(Orange), Eye Position(Event Player), 6); + Play Effect(All Players(All Teams), DVa Self Destruct Explosion Sound, Color(White), Eye Position(Event Player), 250); + If(Distance Between(Position Of(Event Player), Global.gatePosition) < 3.500 && Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.gateHealth -= 300; + Else; + Global.gateHealth -= 150; + End; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Damage(Players Within Radius(Eye Position(Event Player), 7, Team 1, Surfaces And All Barriers), Event Player, 200); + } +} + +rule("BOT: BALL - ALTERNATIVE FORM") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is In Alternate Form(Event Player) == False; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is In Alternate Form(Event Player), 10); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: BALL - DEATH") +{ + event + { + Player Died; + Team 2; + Wrecking Ball; + } + + actions + { + Stop Holding Button(Event Player, Button(Ability 1)); + Stop Holding Button(Event Player, Button(Ultimate)); + } +} + +rule("SUBROUTINE: BALL - RESPAWN") +{ + event + { + Subroutine; + botBallRespawn; + } + + actions + { + "RESPAWN IN AIR" + Teleport(Event Player, Random Value In Array(Global.ballSpawnPositions) + Vector(0, 20, 0)); + Stop Holding Button(Event Player, Button(Ultimate)); + Wait(0.250, Ignore Condition); + "LANDING" + Start Holding Button(Event Player, Button(Crouch)); + Wait Until(Is On Ground(Event Player), 9999); + Stop Holding Button(Event Player, Button(Crouch)); + "LANDING IMPACT EFFECT" + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(White), Event Player, 150); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Effect, Color(Gray), Position Of(Event Player), 10); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Eye Position(Event Player), 1.500, Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + "PATH FINDING TO GATE" + Event Player.botTargetPosition = Global.gatePosition; + Event Player.botIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +disabled rule("=== ECHO ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ECHO - FLY ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Is Using Ability 1(Event Player) == False; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), 0); + Press Button(Event Player, Button(Ability 1)); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - BEAM ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Is Using Ability 1(Event Player) == False; + Event Player.botDoesUniqueBehaviour == True; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - BAD STATUS - RESET BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.hasBadStatus == True; + disabled (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + If(Event Player.botDoesUniqueBehaviour); + Call Subroutine(botEchoDetachPlayer); + End; + Wait Until(Event Player.hasBadStatus, 7); + } +} + +rule("BOT: ECHO - CAN'T SEE PORTAL - APPLY IMPULSE") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == True; + Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Wait(0.300, Abort When False); + Apply Impulse(Event Player, Vector(Random Integer(-1, 1), 1, Random Integer(-1, 1)), 20, To World, Incorporate Contrary Motion); + Wait(1, Ignore Condition); + If(!Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS)); + Event Player.botTargetPosition = Global.botEchoRespawnPosition; + Start Rule(BotStartPathFinding, Restart Rule); + Else; + Call Subroutine(BotResetPathFinding); + End; + Loop If Condition Is True; + } +} + +disabled rule("BOT: ECHO - MAIN LOGIC - BACKUP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + } + + actions + { + If(!Event Player.botIsPathFinding); + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Is In Line of Sight(Eye Position(Event Player), + Eye Position(Current Array Element), Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), + Position Of(Current Array Element)))[0]; + End; + "NO PLAYERS IN VIEW RANGE" + disabled If(Event Player.botSeePlayer == Null); + disabled Stop Throttle In Direction(Event Player); + disabled End; + "FLY TO PLAYER" + If(Event Player.botSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) + > 4 && Event Player.botDoesUniqueBehaviour == False); + Event Player.botTargetPlayer = Event Player.botSeePlayer; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + "ACTIVATE FOCUS BEAM" + Else If(Event Player.botSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) + < 4 && Event Player.botDoesUniqueBehaviour == False && Event Player.hasBadStatus == False); + Event Player.botDoesUniqueBehaviour = True; + Set Status(Event Player.botSeePlayer, Event Player, Stunned, 1); + Set Status(Event Player.botSeePlayer, Event Player, Hacked, 99999); + Attach Players(Event Player.botSeePlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + "TELEPORT PLAYER TO AWAY" + Else If(Event Player.botDoesUniqueBehaviour && Distance Between(Position Of(Event Player.botSeePlayer), + Global.botEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.botEchoRespawnPosition, 1); + Teleport(Event Player.botSeePlayer, Random Value In Array(Global.botEchoTeleportPositions)); + Set Status(Event Player.botSeePlayer, Event Player, Knocked Down, 1); + Call Subroutine(botEchoDetachPlayer); + "BEGIN TO FLY TO THE PORTAL" + Else If(Event Player.botDoesUniqueBehaviour == True); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.botIsPathFinding); + Event Player.botTargetPlayer = Event Player.botSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + } + + actions + { + If(Event Player.botDoesUniqueBehaviour == False); + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + End; + "TELEPORT PLAYER SO FAR" + If(Event Player.botDoesUniqueBehaviour && Distance Between(Position Of(Event Player.botEchoCapturedPlayer), + Global.botEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.botEchoRespawnPosition, 1); + Teleport(Event Player.botEchoCapturedPlayer, Random Value In Array(Global.botEchoTeleportPositions)); + Set Status(Event Player.botEchoCapturedPlayer, Event Player, Knocked Down, 1); + Call Subroutine(botEchoDetachPlayer); + End; + "BEGIN TO FLY TO THE PORTAL WITH A PLAYER" + If(Event Player.botDoesUniqueBehaviour); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.botIsPathFinding); + Event Player.botTargetPlayer = Event Player.botEchoCapturedPlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - DEFEND PORTAL") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer == Null; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Call Subroutine(botEchoFlyToPortal); + } +} + +rule("BOT: ECHO - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer), Barriers Do Not Block LOS) == True; + } + + actions + { + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(botEchoFlyToPlayer); + } +} + +rule("BOT: ECHO - PATH FINDING TO PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Event Player.botDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer), Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.botTargetPlayer = Event Player.botSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Call Subroutine(BotStartPathFinding); + } +} + +rule("BOT: ECHO - ATTACH PLAYER BY BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.hasBadStatus == False; + Event Player.botSeePlayer != Null; + Event Player.isRespawning == False; + Event Player.botEchoCapturedPlayer == Null; + Event Player.botDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer), Barriers Do Not Block LOS) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) < 3; + } + + actions + { + Event Player.botDoesUniqueBehaviour = True; + Event Player.botEchoCapturedPlayer = Event Player.botSeePlayer; + Set Status(Event Player.botEchoCapturedPlayer, Event Player, Stunned, 0.700); + Set Status(Event Player.botEchoCapturedPlayer, Event Player, Hacked, 10); + Attach Players(Event Player.botEchoCapturedPlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - PLAYER DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Is Dead(Event Player.botEchoCapturedPlayer) != Null; + } + + actions + { + If(Event Player.botDoesUniqueBehaviour); + Call Subroutine(botEchoDetachPlayer); + End; + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(botEchoFlyToPortal); + } +} + +rule("BOT: ECHO - DEATH") +{ + event + { + Player Died; + Team 2; + Echo; + } + + actions + { + Call Subroutine(botEchoDetachPlayer); + Stop Holding Button(Event Player, Button(Jump)); + Wait(5, Ignore Condition); + Teleport(Event Player, Vector(0, 999, 0)); + Start Forcing Player To Be Hero(Event Player, Hero(Orisa)); + } +} + +rule("SUBROUTINE: ECHO - RESPAWN") +{ + event + { + Subroutine; + botEchoRespawn; + } + + actions + { + Event Player.botCounter = 0; + Event Player.botEffects = Empty Array; + Create Effect(All Players(All Teams), Good Aura, Color(Sky Blue), Global.botEchoRespawnPosition, Event Player.botCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, botEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Global.botEchoRespawnPosition, Event Player.botCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, botEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Energy Sound, Color(White), Global.botEchoRespawnPosition, 200, Visible To); + Modify Player Variable(Event Player, botEffects, Append To Array, Last Created Entity); + Chase Player Variable Over Time(Event Player, botCounter, 3, 0.800, Destination and Duration); + Play Effect(All Players(All Teams), Sombra EMP Explosion Effect, Color(Sky Blue), Global.botEchoRespawnPosition, 12); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Null, Global.botEchoRespawnPosition, 100); + Wait(3, Ignore Condition); + Teleport(Event Player, Global.botEchoRespawnPosition); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Global.botEchoRespawnPosition, 2.500); + Play Effect(All Players(All Teams), Debuff Impact Sound, Null, Global.botEchoRespawnPosition, 100); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PLAYER") +{ + event + { + Subroutine; + botEchoFlyToPlayer; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Stop Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PORTAL") +{ + event + { + Subroutine; + botEchoFlyToPortal; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - DETACH PLAYER") +{ + event + { + Subroutine; + botEchoDetachPlayer; + } + + actions + { + Detach Players(Event Player.botEchoCapturedPlayer); + Clear Status(Event Player.botEchoCapturedPlayer, Hacked); + "IF PLAYER INSIDE THE WALL" + If(Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botEchoCapturedPlayer), Barriers Do Not Block LOS)); + Teleport(Event Player.botEchoCapturedPlayer, Position Of(Event Player)); + End; + Event Player.botDoesUniqueBehaviour = False; + Event Player.botEchoCapturedPlayer = Null; + } +} + +disabled rule("=== REINHARDT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: REIN - SET PLAYER AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + disabled Event Player.botIsPathFinding == False; + "BOT IS FAR FROM GATES" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Global.gatePosition), 0, Z Component Of(Global.gatePosition))) > 20; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET CLOSEST PLAYER TO BOT AS TARGET AND FOLLOW HIM" + Event Player.botTargetPlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Position Of(Event Player.botTargetPlayer)), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - SET GATE AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + "BOT DOESN'T FOLLOW PLAYER" + Event Player.botTargetPlayer == -1; + "CAN'T SEE ANY PLAYER" + disabled Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), !Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET GATE AS TARGET" + Event Player.botTargetPosition = Global.gatePosition; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - TARGET DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botTargetPlayer != -1; + Is Dead(Event Player.botTargetPlayer) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + } +} + +rule("BOT: REIN - ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) + : Global.gatePosition) < 4; + "CAN ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) : Global.gatePosition), 0, + Z Component Of(Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) : Global.gatePosition))) < 4; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + "TARGET IS PLAYER" + Abort If(Event Player.botTargetPlayer != -1); + If(Event Player.isBoss == 1); + "TARGET IS GATE" + Global.gateHealth -= 25; + Else; + Global.gateHealth -= 5; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: REIN - STOP ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) + : Global.gatePosition) > 4; + "CAN'T ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) : Global.gatePosition), 0, + Z Component Of(Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) : Global.gatePosition))) > 4; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + } +} + +rule("BOT: REIN - USE SHIELD") +{ + event + { + Player Took Damage; + Team 2; + Reinhardt; + } + + conditions + { + Distance Between(Position Of(Event Player), Position Of(Event Player.botTargetPlayer)) > 3; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Attacker)), 200, To World, + Direction and Turn Rate); + Start Holding Button(Event Player, Button(Secondary Fire)); + Wait Until(Distance Between(Position Of(Event Player), Position Of(Event Player.botTargetPlayer)) < 3, 3); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("BOT: REIN - CHARGE IN GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botTargetPlayer == -1; + Is Using Ability 1(Event Player) == False; + Is In Line of Sight(Eye Position(Event Player), Global.gatePosition, Barriers Do Not Block LOS) == True; + Is In View Angle(Event Player, Global.gatePosition, 7.500) == True; + } + + actions + { + disabled Wait(0.800, Abort When False); + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is Using Ability 1(Event Player), 1); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: REIN - DEATH") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("SUBROUTINE: REIN - RESPAWN") +{ + event + { + Subroutine; + BotReinRespawn; + } + + actions + { + Call Subroutine(botAppearFromUnderground); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WIDOW ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: WIDOW - SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.botSeePlayer == Null; + Event Player.hasBadStatus == False; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Event Player.botWidowShotTime = Total Time Elapsed + (Global.timeMin >= 9 ? Random Real(2, 5) : Random Real(5, 10)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), 9999, To World, + Direction and Turn Rate); + } +} + +rule("BOT: WIDOW - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.botSeePlayer != Null; + Event Player.hasBadStatus == False; + Total Time Elapsed >= Event Player.botWidowShotTime; + } + + actions + { + Press Button(Event Player, Button(Primary Fire)); + Stop Facing(Event Player); + Event Player.botSeePlayer = Null; + } +} + +rule("BOT: WIDOW - Aim Sound") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Alive(Event Player) == True; + Is In Line of Sight(Eye Position(Players On Hero(Hero(Widowmaker), Team 2)), Eye Position(Event Player), Barriers Do Not Block LOS) + == True; + Is Alive(Players On Hero(Hero(Widowmaker), Team 2)) == True; + Players On Hero(Hero(Widowmaker), Team 2).botSeePlayer == True; + } + + actions + { + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 100); + Wait(1, Abort When False); + Loop If Condition Is True; + } +} + +rule("BOT: WIDOW - TELEPORT TO NEW POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.hasBadStatus == False; + Total Time Elapsed >= Event Player.botWidowTeleportTime; + } + + actions + { + Event Player.botWidowTeleportTime = Total Time Elapsed + 28; + Event Player.botWidowShotTime = Total Time Elapsed + (Global.timeMin >= 9 ? Random Real(1, 3) : Random Real(3, 6)); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Event Player, 1); + Wait(0.016, Ignore Condition); + Teleport(Event Player, Filtered Array(Global.sniperPositions, Distance Between(Event Player.botEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.sniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.botEventPosition = Position Of(Event Player); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + } +} + +rule("BOT: WIDOW - DEATH") +{ + event + { + Player Died; + Team 2; + Widowmaker; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + Wait(0.250, Ignore Condition); + Destroy Effect(Event Player.botEffects); + } +} + +rule("SUBROUTINE: WIDOW - RESPAWN") +{ + event + { + Subroutine; + botWidowRespawn; + } + + actions + { + "RESPAWN ON RANDOM SNIPER POSITION" + Teleport(Event Player, Filtered Array(Global.sniperPositions, Distance Between(Event Player.botEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.sniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.botEventPosition = Position Of(Event Player); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Wait(0.700, Ignore Condition); + Start Holding Button(Event Player, Button(Secondary Fire)); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + Wait Until(Is Dead(Event Player), 99999); + Destroy Effect(Event Player.botEffects); + } +} + +rule("SUBROUTINE: WIDOW - BAD STATUS") +{ + event + { + Subroutine; + BotWidowBadStatus; + } + + actions + { + Stop Facing(Event Player); + Destroy Effect(Event Player.botEffects); + Wait Until(!Event Player.hasBadStatus, 15); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + } +} + +disabled rule("=== BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("BOT: BASTION - FLAME GUN") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.botDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.botSeePlayer), 50) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) < 8; + } + + actions + { + Event Player.botDoesUniqueBehaviour = True; + Stop Holding Button(Event Player, Button(Primary Fire)); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Update Every Frame(Eye Position(Event Player) + World Vector Of( + Vector(-1, -1.200, 1.800), Event Player, Rotation)), 1, Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + Start Rule(botBastionFlameGunDamage, Do Nothing); + Wait(1.100, Ignore Condition); + Destroy Effect(Event Player.botEffects); + Wait(4, Ignore Condition); + Loop If Condition Is True; + } +} + +disabled rule("BOT: BASTION - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + disabled Event Player.botSeePlayer == Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - CAN'T SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == False; + } + + actions + { + Event Player.botSeePlayer = Null; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - MOVE TO BASTION'S TARGET (POSITION)") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Event Player.botTargetPosition = Random Value In Array(Filtered Array(Global.bastionTargetPositions, Distance Between(Position Of( + Event Player), Current Array Element) > 3.500)); + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("BOT: BASTION - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + "SEE THE PLAYER" + If(Event Player.botSeePlayer != Null); + Stop Holding Button(Event Player, Button(Secondary Fire)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer) - Vector(0, 0.500, + 0)), 100, To World, Direction and Turn Rate); + "SELF REPAIRING" + Else If(!Is Firing Secondary(Event Player) && Health(Event Player) < Max Health(Event Player)); + Start Holding Button(Event Player, Button(Secondary Fire)); + End; + "START FOLLOW PATH" + disabled If(!Event Player.botIsPathFinding && !Event Player.botDoesUniqueBehaviour); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled Wait(0.050, Ignore Condition); + disabled Event Player.botTargetPosition = Random Value In Array(Global.bastionTargetPositions); + disabled Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Event Player.botTargetPosition + Vector(0, 2, 0)), 100, + To World, Direction and Turn Rate); + disabled Start Rule(BotStartPathFinding, Do Nothing); + "REACHED PATH TARGET" + disabled Else If(Distance Between(Position Of(Event Player), Event Player.botTargetPosition) <= 3); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled End; + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - ARTILLERY") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.botDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.botSeePlayer), 30) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) > 18; + Distance Between(Eye Position(Event Player), Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Up * 99, Null, Event Player, False)) >= 35; + } + + actions + { + "TRYING TO CAPTURE TARGET" + Wait(0.800, Abort When False); + "CAPTURE TARGET" + Event Player.botDoesUniqueBehaviour = True; + Stop Throttle In Direction(Event Player); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Update Every Frame(Eye Position(Event Player)), + Update Every Frame(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 1000, All Living Players(Team 1), Event Player, True)), Color(Sky Blue), Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + Wait(1.400, Ignore Condition); + Destroy Effect(Event Player.botEffects); + Abort If(Is Dead(Event Player)); + Event Player.botEventPosition = Position Of(Event Player.botSeePlayer); + "SHOOT FROM ARTILLERY" + Event Player.botBastionArtilleryDidShotsCount = 0; + For Player Variable(Event Player, botLoopIterator1, 0, 4, 1); + Event Player.botBastionArtilleryDidShotsCount += 1; + Play Effect(All Players(All Teams), Wrecking Ball Minefield Explosion Sound, Color(White), Eye Position(Event Player), 250); + Play Effect(All Players(All Teams), Pharah Barrage Explosion Effect, Color(Orange), Eye Position(Event Player) + World Vector Of( + Vector(0, 1.400, -0.700), Event Player, Rotation), 2); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) + World Vector Of(Vector(0, 1.400, + -0.700), Event Player, Rotation), Eye Position(Event Player) + World Vector Of(Vector(Random Real(-1, 1), Random Integer(40, + 80), Random Real(0.500, 1.500)), Event Player, Rotation), Color(Orange), Visible To); + Event Player.botEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.botEffects); + Wait(0.400, Ignore Condition); + If(Is Dead(Event Player)); + Break; + End; + End; + disabled Call Subroutine(BotResetPathFinding); + disabled Start Rule(BotStartPathFinding, Do Nothing); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Wait(1.500, Ignore Condition); + Start Rule(botBastionArtilleryDamage, Do Nothing); + Wait(4, Ignore Condition); + } +} + +rule("BOT: BASTION - PRIMARY FIRE") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Event Player.botDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.botSeePlayer), 40) == True; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Stop Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Bastion; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + For Player Variable(Event Player, botLoopIterator1, 0, 3, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Effect, Color(White), Event Player, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player, 100); + Wait(0.250, Ignore Condition); + End; + } +} + +rule("SUBROUTINE: BASTION - RESPAWN") +{ + event + { + Subroutine; + botBastionRespawn; + } + + actions + { + Abort If(Event Player.botIsOrisaChild == True); + Call Subroutine(botLandingFromSky); + Set Ammo(Event Player, 0, 0); + Wait Until(!Is Reloading(Event Player), 99999); + Event Player.botTargetPosition = Objective Position(2); + } +} + +rule("SUBROUTINE: BASTION - ARTILLERY DAMAGE") +{ + event + { + Subroutine; + botBastionArtilleryDamage; + } + + actions + { + Event Player.botDoesUniqueBehaviour = False; + "EXPLOSIONS OF ARTILLERY" + For Player Variable(Event Player, botLoopIterator2, 0, Event Player.botBastionArtilleryDidShotsCount, 1); + Event Player.botEventPosition = Ray Cast Hit Position(Event Player.botEventPosition + Vector(0, 50, 0), + Event Player.botEventPosition + Vector(Random Integer(-4, 4), -15, Random Integer(-4, 4)), Null, Event Player, True); + Damage(Players Within Radius(Event Player.botEventPosition, 8, Team 1, Surfaces And Enemy Barriers), Event Player, 50); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player.botEventPosition, 150); + Play Effect(All Players(All Teams), Pharah Rocket Launcher Explosion Effect, Color(Orange), Event Player.botEventPosition, 5); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Event Player.botEventPosition, + Event Player.botEventPosition + Vector(0, 60, 0), Color(Orange), Visible To); + Event Player.botEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.botEffects); + Wait(0.400, Ignore Condition); + End; + } +} + +disabled rule("SUBROUTINE: BASTION - FLAME GUN DAMAGE") +{ + event + { + Subroutine; + botBastionFlameGunDamage; + } + + actions + { + Event Player.botRayCastHitPosition = Eye Position(Event Player) + World Vector Of(Vector(-1, -1.200, 1.800), Event Player, + Rotation); + "FIRE PARTICLES OF FLAME GUN" + For Player Variable(Event Player, botLoopIterator1, 1, 13, 3); + Event Player.botEventPosition = Ray Cast Hit Position(Event Player.botRayCastHitPosition, + Event Player.botRayCastHitPosition + Facing Direction Of(Event Player) * Event Player.botLoopIterator1, Null, Event Player, + True); + Damage(Players Within Radius(Event Player.botEventPosition, 4, Team 1, Surfaces And Enemy Barriers), Event Player, 20); + Set Status(Players Within Radius(Event Player.botEventPosition, 4, Team 1, Off), Event Player, Burning, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player.botEventPosition, 150); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.botEventPosition, 2.500); + Wait(0.200, Ignore Condition); + End; + Event Player.botDoesUniqueBehaviour = False; + } +} + +disabled rule("=== ORISA + BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ORISA-BASTION - REACHED TARGET POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botIsPathFinding == True; + Distance Between(Position Of(Event Player), Global.botOrisaTargetPosition) < 1.500; + } + + actions + { + Call Subroutine(BotResetPathFinding); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Vector(X Component Of(Global.gatePosition), -999, + Z Component Of(Global.gatePosition))), 80, To World, Direction and Turn Rate); + Start Facing(Global.botOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Barriers Do Not Block LOS) ? Global.gatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + disabled Start Facing(Global.botOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Barriers Do Not Block LOS) ? Global.gatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element) && Is In Line of Sight(Eye Position(Event Player), Position Of(Current Array Element), + Barriers Do Not Block LOS)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + Press Button(Event Player, Button(Ability 1)); + Wait Until(Y Component Of(Facing Direction Of(Event Player)) < -0.300, 99999); + Press Button(Event Player, Button(Ability 2)); + Wait(0.800, Ignore Condition); + Global.botOrisaChild.botDoesUniqueBehaviour = False; + Disallow Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ORISA-BASTION - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Event Player.botDoesUniqueBehaviour = True; + While(Is Alive(Event Player)); + disabled Create Effect(All Players(All Teams), Bad Aura, Color(Purple), Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3.200, 1, Visible To Position and Radius); + disabled Event Player.botEffects = Last Created Entity; + Wait(1.500, Ignore Condition); + disabled Destroy Effect(Event Player.botEffects); + Abort If(Is Dead(Event Player)); + Press Button(Event Player, Button(Primary Fire)); + Press Button(Event Player, Button(Reload)); + Event Player.botRayCastHitPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Facing Direction Of(Event Player) * 999, All Players(Team 1), All Players(Team 2), True); + "ANTI-SHIELD BUG" + Event Player.botRayCastHitPosition = Event Player.botRayCastHitPosition + Direction Towards(Event Player.botRayCastHitPosition, + Eye Position(Event Player)) * 0.200; + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3, Event Player.botRayCastHitPosition, Color(Purple), Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + Damage(Players Within Radius(Event Player.botRayCastHitPosition, 4, Team 1, Surfaces And All Barriers), Event Player, 0.040); + Play Effect(All Players(All Teams), Pharah Concussive Blast Effect, Color(Purple), Event Player.botRayCastHitPosition, 4); + Play Effect(All Players(All Teams), Pharah Concussive Blast Sound, Color(Purple), Event Player.botRayCastHitPosition, 250); + Play Effect(All Players(All Teams), Bad Explosion, Color(Purple), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 3.300, 2); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Color(Purple), Eye Position(Event Player), 170); + If(Distance Between(Event Player.botRayCastHitPosition, Global.gatePosition) < 4 && Is In Line of Sight( + Event Player.botRayCastHitPosition, Global.gatePosition, Enemy Barriers Block LOS)); + Global.gateHealth -= 80; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Wait(0.150, Ignore Condition); + Destroy Effect(Event Player.botEffects); + Wait(0.060, Ignore Condition); + Wait Until(!Is Reloading(Event Player), 2.500); + End; + } +} + +rule("BOT: ORISA-BASTION - CAN'T SEE THE TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Is In Line of Sight(Eye Position(Event Player), Global.gatePosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.botTargetPosition = Global.botOrisaTargetPosition; + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: ORISA-BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Orisa; + } + + actions + { + Allow Button(Event Player, Button(Ability 2)); + Kill(Global.botOrisaChild, Null); + Detach Players(Global.botOrisaChild); + Clear Status(Global.botOrisaChild, Phased Out); + Set Damage Dealt(Global.botOrisaChild, 100); + Global.botOrisaChild.botIsOrisaChild = False; + Global.botOrisaChild = Null; + Global.botOrisaParent = Null; + Start Forcing Player To Be Hero(Event Player, Hero(Widowmaker)); + } +} + +rule("SUBROUTINE: ORISA - RESPAWN") +{ + event + { + Subroutine; + botOrisaRespawn; + } + + actions + { + Global.botOrisaParent = Event Player; + "WAITING FOR ANY BASTION TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero(Bastion)), + 99999); + "SETUP BASTION AS CHILD" + Global.botOrisaChild = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Bastion))[0]; + Global.botOrisaChild.botIsOrisaChild = True; + Global.botOrisaChild.botDoesUniqueBehaviour = True; + Wait(2, Ignore Condition); + Respawn(Global.botOrisaChild); + Start Scaling Player(Global.botOrisaChild, 1.800, False); + Set Damage Dealt(Global.botOrisaChild, 2000); + Set Status(Global.botOrisaChild, Null, Phased Out, 9999); + Disable Nameplates(Global.botOrisaChild, All Players(All Teams)); + Set Facing(Global.botOrisaChild, Vector(X Component Of(Facing Direction Of(Event Player)), 9999, Z Component Of( + Facing Direction Of(Event Player))), To World); + Start Holding Button(Global.botOrisaChild, Button(Ability 1)); + Wait Until(Is In Alternate Form(Global.botOrisaChild), 5); + Stop Holding Button(Global.botOrisaChild, Button(Ability 1)); + Teleport(Global.botOrisaChild, Position Of(Event Player)); + Attach Players(Global.botOrisaChild, Global.botOrisaParent, Vector(0, 1.800, 0.230)); + disabled Wait(1, Ignore Condition); + disabled Stop Holding Button(Global.botOrisaChild, Button(Primary Fire)); + disabled Wait(0.250, Ignore Condition); + Call Subroutine(botLandingFromSky); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + Event Player.botTargetPosition = Global.botOrisaTargetPosition; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 0 - ZENS, REINS, BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMin == 0; + } + + actions + { + "CREATE BOTS - ZEN" + While(Count Of(All Players(Team 2)) < 13); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "BALL" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "REPLACE DEAD ZEN TO REIN" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) != 3); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 1 - WIDOW") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMin == 1; + } + + actions + { + Global.isNewWaveGameLogicProcessing = True; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Global.isNewWaveGameLogicProcessing = False; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 3 - BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMin == 3; + } + + actions + { + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 5 - REINS WAVE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMin == 5; + } + + actions + { + "PREPARE WAVE - DESTROY WIDOW AND BALLS" + Destroy Dummy Bot(Team 2, Slot Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))[0])); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))[0]; + Kill(Global.defaultCurrentBot, Null); + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + End; + "BOSS WAVE" + Big Message(All Players(All Teams), Custom String("BOSS WAVE - {1} {0}", Hero Icon String(Hero(Reinhardt)), Hero(Reinhardt))); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) < 6); + Wait Until(Is True For Any(All Players(Team 2), Distance Between(Position Of(Current Array Element), Global.gatePosition) + > 13 && Hero Of(Current Array Element) == Hero(Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + disabled Wait(0.200, Ignore Condition); + disabled Set Max Health(Global.defaultCurrentBot, 50); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) > 3); + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Reinhardt)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Reinhardt))[0]; + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(All Players(Team 2)) < 13); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Big Message(All Players(All Teams), Custom String("BOSS WAVE FINISHED!")); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 7 - BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMin == 7; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 9 - ECHO, +1 BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMin == 9; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Echo))) == 0); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + "FILL EMPTY SLOTS BY ZENS" + While(Count Of(All Players(Team 2)) < 12); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("Ana Nano Variable") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + } + + actions + { + Player Closest To Reticle(Event Player, Team 1).isNanoed = 1; + } +} + +rule("isNanoed") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isNanoed == True; + } + + actions + { + If(Is Dead(Event Player)); + Event Player.isNanoed = 0; + End; + Wait(8, Ignore Condition); + Event Player.isNanoed = 0; + } +} + +rule("money on kill") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + actions + { + If(Hero Of(Victim) == Hero(Zenyatta)); + All Players(Team 1).money[0] += 5 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 10 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Reinhardt)); + All Players(Team 1).money[0] += 15 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 20 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Wrecking Ball)); + All Players(Team 1).money[0] += 25 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 25 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Widowmaker)); + All Players(Team 1).money[0] += 30 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 30 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Bastion)); + All Players(Team 1).money[0] += 50 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 50 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Echo)); + All Players(Team 1).money[0] += 75 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 75 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Orisa)); + All Players(Team 1).money[0] += 100 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 100 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + } +} + +rule("abilities and Hero Talents by Shingen and LemonAid") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.damageDealt = 100; + Event Player.playerHealth = 100; + Event Player.money[0] = 2400 + Global.startMoney; + If(Custom String("{0}", Event Player) == Custom String("ShuriZma")); + Create HUD Text(Event Player, Custom String("Serverload: {0}, AVG {1}, Peak {2}", Server Load, Server Load Average, + Server Load Peak), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + End; + } +} + +rule("Team 1 (Ability): Headhunter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.abilities[1] == True; + Event Was Critical Hit == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.abilities[1] * 40 / Event Player.damageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Ambush") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.abilities[2] == True; + Event Ability != Null; + (Y Component Of(Position Of(Event Player)) - Y Component Of(Position Of(Victim)) >= 3 || Absolute Value(Horizontal Angle Towards( + Victim, Event Player)) >= 90) == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.abilities[2] * 30 / Event Player.damageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Quick Fix") +{ + event + { + Player Earned Elimination; + Team 1; + All; + } + + conditions + { + Event Player.abilities[3] == True; + } + + actions + { + Heal(Event Player, Null, Event Player.abilities[3] * 50); + Set Move Speed(Event Player, 100 + Event Player.abilities[3] * 20); + Wait(5, Restart When True); + Set Move Speed(Event Player, 100); + } +} + +rule("Team 1 (Ability): Heavyweight") +{ + event + { + Player Dealt Knockback; + Team 1; + All; + } + + conditions + { + Event Player.abilities[4] == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.abilities[4] * 25 / Event Player.damageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Charged") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[5] == True; + Ultimate Charge Percent(Event Player) < Event Player.abilities[5] * 20; + } + + actions + { + Set Ultimate Charge(Event Player, Event Player.abilities[5] * 20); + If(Is Duplicating(Event Player)); + Wait(0.016, Ignore Condition); + Set Ultimate Charge(Event Player, Event Player.abilities[5] * 20); + End; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Team 1 (Ability): Haste Primary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Primary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Primary Fire), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Primary Fire))); + } +} + +rule("Team 1 (Ability): Haste Secondary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Secondary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Secondary Fire), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Secondary Fire))); + } +} + +rule("Team 1 (Ability): Haste Ability 1") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 1)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 1))); + } +} + +rule("Team 1 (Ability): Haste Ability 2") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 2)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 2))); + } +} + +rule("Team 1 (Ability): Haste Jump") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Jump)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Jump), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, Button( + Jump))); + } +} + +rule("Team 1 (Ability): Haste Crouch") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Crouch)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Crouch), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, Button( + Crouch))); + } +} + +rule("Team 1 (Ability): Heavy Impact") +{ + event + { + Player Took Damage; + Team 2; + All; + } + + conditions + { + Attacker.abilities[7] == True; + } + + actions + { + Abort If(Random Real(-0.020, 1) > Event Damage / Max Health(Event Player)); + Set Status(Event Player, Attacker, Stunned, 1 * Attacker.abilities[7]); + Wait(5, Ignore Condition); + } +} + +rule("Team 1 (Ability): Binding Heal") +{ + event + { + Player Dealt Healing; + Team 1; + All; + } + + conditions + { + Event Player.abilities[10] == True; + Healee != Event Player; + } + + actions + { + Set Player Health(Event Player, Health(Event Player) + Event Player.abilities[10] * 0.250 * Event Healing); + } +} + +rule("Team 1 (Ability): Resilience") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[11] == True; + Normalized Health(Event Player) < Event Player.abilities[11] * 0.300; + } + + actions + { + Set Damage Received(Event Player, 70); + Wait Until(!(Event Player.abilities[11] && Normalized Health(Event Player) < Event Player.abilities[11] * 0.300), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Auto Repair") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.autoRepair == True; + Global.gateHealth < Global.gateMaxHealth; + } + + actions + { + If(Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2]); + Global.gateHealth += 10 * Global.autoRepair; + Global.upgradeGateMaxHealthValue += 10 * Global.autoRepair; + Else; + Global.gateHealth += 5 * Global.autoRepair; + Global.upgradeGateMaxHealthValue += 5 * Global.autoRepair; + End; + If(Global.gateHealth > Global.gateMaxHealth); + Global.gateHealth = Global.gateMaxHealth; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(5, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ana Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Ana), Button(Ability 1)), Custom String( + "Sleep Paralysis: Slept enemies cannot be woken up by damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Ana), Button(Ability 2)), Custom String( + "Multinade: Ana throws multiple Biotic Grenades")); + } +} + +rule("Brigitte Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Brigitte), Button(Ability 1)), Custom String( + "Heavy Iron: Hitting enemies with Whip Flail will root them in pace")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Brigitte), Button(Ultimate)), Custom String( + "Endeavor: Gain a health, damage and speed boost when your barrier breaks")); + } +} + +rule("Mercy Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Mercy), Button(Ability 2)), Custom String( + "Angelic blessing: Healing an ally slowly charges their ultimate")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Mercy), Button(Ultimate)), Custom String( + "Holy light missiles: Unleash blasts of holy light missiles during valkyrie")); + } +} + +rule("Lúcio Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Lúcio), Button(Secondary Fire)), Custom String( + "Healing Wave: Soundwave heals allies for 30% of their max HP")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Lúcio), Button(Ability 1)), Custom String( + "Reverse Amp: Amp It Up inflicts the opposite effect of the currently played song to enemies")); + } +} + +rule("Moira Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Moira), Button(Secondary Fire)), Custom String( + "Hose: Biotic Grasp primary will damage and push enemies back")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Moira), Button(Ability 2)), Custom String( + "Flourish: Biotic Orbs are 3x more effective")); + } +} + +rule("Baptiste Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + actions + { + Event Player.heroTalentText[1] = Array(Icon String(Poison), Custom String( + "Corrode: Regenerative Burst will damage and poison enemies")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Breakthrough: Immortality Field HP threshold increased to 100%; allies inside gain ultimate")); + } +} + +rule("Ashe Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Ashe), Button(Ability 2)), Custom String( + "Wildfire: Shooting a burning enemy ignites other nearby enemies")); + Event Player.heroTalentText[2] = Array(Icon String(Fire), Custom String( + "Flare trigger: Coach gun instantly damages all burning enemies")); + } +} + +rule("D.Va Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(D.Va), Button(Secondary Fire)), Custom String( + "Voltage Grid: Defense Matrix will damage and root enemies it's casted over")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(D.Va), Button(Ability 1)), Custom String( + "Shooting Star: Boosters set enemies on fire")); + } +} + +rule("Genji Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Genji), Button(Ability 1)), Custom String( + "Venomous Strike: Swift Strike poisons enemies; heal for poison damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Genji), Button(Ultimate)), Custom String( + "Dragon's Breath: Dragonblade fires large explosive energy charges")); + } +} + +rule("Hanzo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Hanzo; + } + + actions + { + Event Player.heroTalentText[1] = Array(Icon String(Bolt), Custom String( + "Stormbreak: Enemies eliminated by hanzo unleash a thundercloud")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Hanzo), Button(Ability 2)), Custom String( + "Punch II: Storm Arrows deal more damage and stun and knockback enemies")); + } +} + +rule("Widowmaker Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Widowmaker; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Widowmaker), Button(Ultimate)), Custom String( + "Kiss Of Death: Scoped critical hits against enemies below 30% health explode and instantly die")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Widowmaker), Button(Ability 2)), Custom String( + "Epidemic: Enemies hurt by Venom Mine unleash toxic pulses; heal for dealt damage")); + } +} + +rule("McCree Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Cassidy), Button(Ability 2)), Custom String( + "Panic: Flashbang puts enemies in fear; deal +120% more damage to enemies in fear")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Cassidy), Button(Ultimate)), Custom String( + "Clocked: Deadeye deals more damage and knocks enemies down")); + } +} + +rule("Reinhardt Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Reinhardt), Button(Ability 2)), Custom String( + "Fire Blast: Fire Strike explodes as it deals damage, setting enemies on fire")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Reinhardt), Button(Ultimate)), Custom String( + "Epicenter: Earthshatter travels in all directions")); + } +} + +rule("Soldier: 76 Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ultimate)), Custom String( + "Triple Threat: 2 more rockets are fired alongside Helix Rockets")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Soldier: 76), Button(Ability 1)), Custom String( + "Shoulder Check: Sprinting into enemies will damage and tackle them to the ground")); + } +} + +rule("Torbjörn Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Torbjörn), Button(Ability 2)), Custom String( + "Melting point: Unleash heatwaves during overload and molten core")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Torbjörn), Button(Ultimate)), Custom String( + "Roots Of Magma: Enemies trapped in Molten Core blots cannot move")); + } +} + +rule("Tracer Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Tracer), Button(Ability 2)), Custom String( + "Vortex: Recall pulls and roots enemies towards the activation point")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Tracer), Button(Ultimate)), Custom String( + "Chain Reaction: Pulse Bomb creates chain explosions on enemies damaged by it")); + } +} + +rule("Winston Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Winston), Button(Ability 2)), Custom String( + "Blast Barrier: Barrier Projector damages enemies inside the area")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Winston), Button(Ultimate)), Custom String( + "Next Generation: Eliminations during Primal Rage add +15% ultimate charge towards the next")); + } +} + +rule("Pharah Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Pharah; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ability 2)), Custom String( + "Head Trauma: Concussive Blast stuns and damages enemies for 25% of their max health")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Pharah), Button(Ability 1)), Custom String( + "Thunderbird: Gain 150 shields and deal 4x the damage to barriers and objects")); + } +} + +rule("Bastion Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Bomblets: Bullets shot during sentry configuration are explosive")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ability 1)), Custom String( + "Tesla: A powerful mounted laser will autmotically attack one enemy at a time")); + } +} + +rule("Doomfist Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Jump)), Custom String( + "Phase Shifter: Immune to damage while any ability is active")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Doomfist), Button(Ultimate)), Custom String( + "Fissure: Meteor Strike leaves a large fissure behind that burns enemies over it")); + } +} + +rule("Echo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Focusing Optics: Focusing Beam damage ramp starts at 90% health")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Streamline: Fire many more sticky bombs per burst")); + } +} + +rule("Junkrat Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Junkrat; + } + + actions + { + Event Player.heroTalentText[1] = Array(Icon String(Fire), Custom String("Pyromania: All explosive attacks inflict fire damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Junkrat), Button(Ability 2)), Custom String( + "Short Fused: Steel Trap sets off violent explosions once triggered")); + } +} + +rule("Mei Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Mei), Button(Ultimate)), Custom String( + "Cold Snap: Instantly freeze neaerby enemies once Cryo-Freeze expires")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Mei), Button(Ability 2)), Custom String( + "Icebound: While Ice Wall is up, Icicles freeze and deal much more damage")); + } +} + +rule("Orisa Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Orisa), Button(Ability 1)), Custom String( + "Immovable Object: During Fortify, become immune and convert 50% of taken damage to healing")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Orisa), Button(Secondary Fire)), Custom String( + "Unstoppable Force: Halt! is much larger and pushes enemies. When triggered, it explodes violently")); + } +} + +rule("Reaper Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Reaper), Button(Ability 1)), Custom String( + "shadow streak: shadow step creates a beam that damages enemies who cross")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Reaper), Button(Ultimate)), Custom String( + "Loom: Traumatize enemies in front of you when using Wraith Form")); + } +} + +rule("Roadhog Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + actions + { + Event Player.heroTalentText[1] = Array(Icon String(Poison), Custom String("Stench: Roadhog constantly damages enemies nearby")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Roadhog), Button(Ability 1)), Custom String( + "Rusted Anchor: Hook deals more damage; Eliminations will reset hook cooldown")); + } +} + +rule("Sigma Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Sigma), Button(Ability 1)), Custom String( + "Gravity Well: Kinetic Grasp gives invincibility")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Sigma), Button(Ultimate)), Custom String( + "Gravity Channels: Gravitic Flux damages enemies for 75% of max hp instead of 50%")); + } +} + +rule("Sombra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Sombra), Button(Secondary Fire)), Custom String( + "Malware: Enemies hacked or in fear take +100% more damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Sombra), Button(Ultimate)), Custom String( + "Glitch: EMP leaves behind a large hack zone ")); + } +} + +rule("Symmetra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Symmetra; + } + + actions + { + Event Player.heroTalentText[1] = Array(Icon String(Bolt), Custom String( + "High Voltage: Enemies eliminated by Symmetra explode and damage other enemies")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ultimate)), Custom String( + "Energy Source: While Photon Barrier is active, all players regenerate health and gain ultimate")); + } +} + +rule("Wrecking Ball Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ultimate)), Custom String( + "Mirror Ball: Reflect 100% of taken damage to nearby enemies")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ability 2)), Custom String( + "Distort: Adaptive Shields damages and hacks nearby enemies")); + } +} + +rule("Zarya Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zarya; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Zarya), Button(Ability 1)), Custom String( + "Augment: Health and barrier hp increased by 50%; barrier sized doubled")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Perpetual Energy: secondary inflicts burn damage that continues to last until the enemy dies")); + } +} + +rule("Zenyatta Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Vigor: The ally under the effect of Harmony Orb is immune to damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Zenyatta), Button(Ultimate)), Custom String( + "Perfect Balance: Transcendence damages enemies in a large proximity")); + } +} + +rule("Ana: Sleep Paralysis") +{ + event + { + Player Dealt Damage; + Team 1; + Ana; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Black), Victim, 1); + Wait(0.250, Ignore Condition); + Set Status(Victim, Null, Knocked Down, 5); + } +} + +rule("Ana: Multinade") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Event Player.abilityCountdown = 4; + While(Event Player.abilityCountdown > 0); + Wait(0.030, Ignore Condition); + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Cancel Primary Action(Event Player); + Wait(0.050, Ignore Condition); + Press Button(Event Player, Button(Ability 2)); + Event Player.abilityCountdown -= 1; + End; + Wait(2, Ignore Condition); + } +} + +rule("Brigitte: Heavy Iron") +{ + event + { + Player Dealt Damage; + Team 1; + Brigitte; + } + + conditions + { + (Event Ability == Button(Primary Fire) || Event Ability == Button(Ability 1)) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Victim, 1.500); + Set Status(Victim, Null, Rooted, 0.500); + Set Environment Credit Player(Victim, Event Player); + } +} + +rule("Brigitte: Endeavor") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Ability Cooldown(Event Player, Button(Secondary Fire)) >= 0.100; + Event Player.abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player, 0.400, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Eye Position(Event Player), 15); + Heal(Players Within Radius(Event Player, 15, Team Of(Event Player), Off), Event Player, 200); + Event Player.damageDealt *= 2.500; + Set Move Speed(Event Player, 100 * 1.750); + Add Health Pool To Player(Event Player, Armor, Max Health(Event Player) / 2, False, True); + Event Player.hpPool[1] = Last Created Health Pool; + Wait Until(Is Dead(Event Player), 6); + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Set Move Speed(Event Player, 100); + Remove Health Pool From Player(Event Player.hpPool[1]); + Destroy Effect(Event Player.effects_[1]); + } +} + +rule("Mercy: Angelic Blessing") +{ + event + { + Player Dealt Healing; + All; + Mercy; + } + + conditions + { + Event Player.abilities[8] == True; + Healee != Event Player; + Normalized Health(Healee) < True; + } + + actions + { + Set Ultimate Charge(Healee, Ultimate Charge Percent(Healee) + 1); + Wait(0.400, Ignore Condition); + } +} + +rule("Mercy: Aurora") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ultimate(Event Player) == True; + } + + actions + { + Wait(1.500, Ignore Condition); + Event Player.abilityProjectile1 = Eye Position(Event Player); + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(All Teams), Event Player, True); + Create Beam Effect(All Players(All Teams), Mercy Heal Beam, Event Player, Event Player.abilityProjectile1, Color(White), + Visible To Position and Radius); + Event Player.effects_[3] = Last Created Entity; + Chase Player Variable At Rate(Event Player, abilityProjectile1, Event Player.abilityEnd, 70, Destination and Rate); + While(Event Player.abilityEnd != Event Player.abilityProjectile1); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Event Player.abilityProjectile1, 1); + Wait(0.032, Ignore Condition); + End; + Destroy Effect(Event Player.effects_[3]); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.abilityProjectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.abilityProjectile1, 5); + Damage(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 120); + Loop If Condition Is True; + } +} + +rule("Lucio: Healing Wave") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4); + Heal(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 4, 4, Team Of(Event Player), Surfaces), + Event Player, Max Health(Filtered Array(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4, Team Of(Event Player), Surfaces), Is Alive(Current Array Element))) * 0.300); + } +} + +rule("Lucio: Reverse Amp") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + If(Is Using Ability 1(Event Player)); + Set Status(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Rooted, 4); + Else; + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 16.250); + End; + Play Effect(All Players(All Teams), Ring Explosion, Is Using Ability 1(Event Player) ? Color(Green) : Color(Yellow), Event Player, + 1); + Wait(0.400, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Hose") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Event Player.abilities[8] == True; + Ability Resource(Event Player, Button(Primary Fire)) > False; + } + + actions + { + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Facing Direction Of(Event Player), 15, To World, + Cancel Contrary Motion); + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && !Is In Line of Sight(Current Array Element, Event Player, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Up, 8, To World, Cancel Contrary Motion); + Start Damage Over Time(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), + Distance Between(Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS)), Event Player, 1, 15); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Flourish - Damage") +{ + event + { + Player Dealt Damage; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("[Moira] Flourish - Healing") +{ + event + { + Player Dealt Healing; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[12] == True; + } + + actions + { + Heal(Healee, Event Player, Event Healing * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Healee, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("Baptiste: Corrode") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 20); + Wait(0.200, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 12); + } +} + +rule("Baptiste: Breakthrough") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Status(Event Player, Unkillable) == True; + (Event Player.abilities[12] ? Players On Hero(Hero(Baptiste), Team Of(Event Player)) : Empty Array).abilities[12] == True; + } + + actions + { + Heal(Event Player, Event Player, 10000); + Set Status(Event Player, Null, Invincible, 0.800); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ashe: Firebourne") +{ + event + { + Player Dealt Damage; + Team 1; + Ashe; + } + + conditions + { + Event Player.abilities[8] == True; + Event Ability == Button(Primary Fire); + Has Status(Victim, Burning) == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Null, Burning, 10); + Start Damage Over Time(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Event Player, 10, 15); + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 5); + Wait(0.250, Ignore Condition); + } +} + +rule("Ashe: Taunt") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Damage(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, Burning)), + Event Player, 125); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Frozen, + 0.016); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Stunned, + 2); + } +} + +rule("D.Va: Voltage Grid") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 2, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 5, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 8, 0.500); + Wait(0.300, Ignore Condition); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Wait(0.016, Ignore Condition); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Loop If Condition Is True; + } +} + +rule("D.Va: Shooting Star") +{ + event + { + Player Dealt Knockback; + Team 1; + D.Va; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, 40); + Set Status(Victim, Null, Burning, 3); + Start Damage Over Time(Victim, Event Player, 3, 35); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 1); + } +} + +rule("Genji: Venomous Strike") +{ + event + { + Player Dealt Damage; + Team 1; + Genji; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.abilities[8] == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 3, 25); + Start Damage Over Time(Victim, Event Player, 3, 25); + Damage(Victim, Event Player, 25); + Heal(Event Player, Event Player, 25); + } +} + +rule("Genji: Dragon's Breath") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is Firing Primary(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Good Aura, Color(Lime Green), Event Player.abilityProjectile1, 1, + Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Event Player.abilityProjectile1 = Eye Position(Event Player); + Chase Player Variable At Rate(Event Player, abilityProjectile1, Event Player.abilityEnd, 80, Destination and Rate); + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True); + Wait Until(Event Player.abilityEnd == Event Player.abilityProjectile1, 1); + Destroy Effect(Event Player.effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Green), Event Player.abilityProjectile1, 100); + Play Effect(All Players(All Teams), Bad Explosion, Color(Lime Green), Event Player.abilityProjectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Green), Event Player.abilityProjectile1, 5); + Damage(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 100); + } +} + +rule("[Hanzo] Stormbreak (stormEffects6)") +{ + event + { + Player Died; + Team 2; + All; + } + + conditions + { + Attacker.abilities[8] == True; + Hero Of(Attacker) == Hero(Hanzo); + } + + actions + { + Event Player.stormProjectile = Eye Position(Event Player); + Event Player.stormEndPoint = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Up * 12, Null, + All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, stormProjectile, Event Player.stormEndPoint, 4, Destination and Rate); + Create Effect(All Players(All Teams), Cloud, Color(White), Vector(False, -0.500, False) + Event Player.stormProjectile, 4, + Visible To Position and Radius); + Event Player.stormEffects[3] = Last Created Entity; + Create Effect(All Players(All Teams), Bad Aura, Color(White), Event Player.stormProjectile, 3, Visible To Position and Radius); + Event Player.stormEffects[4] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(White), Event Player.stormProjectile, 3.500, Visible To Position and Radius); + Event Player.stormEffects[5] = Last Created Entity; + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.stormProjectile, Ray Cast Hit Position( + Event Player.stormProjectile, Vector(0.100, 0, 0) + Event Player.stormProjectile + Down * 1000, Null, All Players(All Teams), + False), Color(Aqua), Visible To Position and Radius); + Event Player.stormEffects[6] = Last Created Entity; + While(Distance Between(Event Player.stormProjectile, Event Player.stormEndPoint) > 1); + Wait(0.600, Ignore Condition); + Damage(Players Within Radius(Ray Cast Hit Position(Event Player.stormProjectile, Event Player.stormProjectile + Down * 1000, + Null, All Players(All Teams), False), 3, Team Of(Event Player), Surfaces), Attacker, 50); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Ray Cast Hit Position(Event Player.stormProjectile, + Event Player.stormProjectile + Down * 1000, Null, All Players(All Teams), False), 3); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Ray Cast Hit Position(Event Player.stormProjectile, + Event Player.stormProjectile + Down * 1000, Null, All Players(All Teams), False), 3); + End; + Destroy Effect(Event Player.stormEffects[3]); + Destroy Effect(Event Player.stormEffects[4]); + Destroy Effect(Event Player.stormEffects[5]); + Destroy Effect(Event Player.stormEffects[6]); + } +} + +rule("Hanzo: Punch II") +{ + event + { + Player Dealt Damage; + Team 1; + Hanzo; + } + + conditions + { + Event Player.abilities[12] == True; + Event Ability == Button(Ability 2); + Hero Of(Victim) != Hero(Torbjörn); + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.800); + Apply Impulse(Victim, Facing Direction Of(Event Player), 12, To World, Cancel Contrary Motion); + Apply Impulse(Victim, Up, 5, To World, Cancel Contrary Motion); + Set Environment Credit Player(Victim, Event Player); + Set Status(Victim, Null, Stunned, 1); + } +} + +rule("Widowmaker: Kiss Of Death") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + (Normalized Health(Victim) <= 0.300 || Event Damage >= Normalized Health(Victim) + Event Damage) == True; + Is Firing Secondary(Event Player) == True; + Event Ability == Button(Primary Fire); + Event Player.abilities[8] == True; + Event Damage >= 40; + Event Was Critical Hit == True; + } + + actions + { + Kill(Victim, Event Player); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 2), Victim, 3); + Damage(Players Within Radius(Victim, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage * 1.500); + } +} + +rule("Widowmaker: Epidemic") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 8); + Play Effect(All Players(All Teams), Good Explosion, Color(Purple), Victim, 4); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Victim, 16); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Victim, 3); + Start Damage Over Time(Players Within Radius(Victim, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, 50); + Start Heal Over Time(Event Player, Event Player, 3, 50); + Wait(0.500, Ignore Condition); + } +} + +rule("McCree: Panic") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[8] == True; + } + + actions + { + Victim.fearedUntil = Total Time Elapsed + 3.500; + } +} + +rule("McCree: Panic - Damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), + Event Player.fearedUntil >= Total Time Elapsed), All Players(Team Of(Event Player)), 220, + Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Wait Until(!Event Player.abilities[8], 99999); + Stop Damage Modification(Event Player.modificationDamage[1]); + } +} + +rule("McCree: Clocked") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Damage(Victim, Event Player, Event Damage * 1.500); + Set Status(Victim, Null, Knocked Down, 3); + } +} + +rule("Reinhardt: Fire Blast") +{ + event + { + Player Dealt Damage; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Start Damage Over Time(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, 20); + Set Status(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Burning, 5); + } +} + +rule("Reinhardt: Epicenter") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is On Ground(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, Knocked Down, 2.500); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 10); + Damage(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, 50); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 20); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 30); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 40); + Wait(5, Ignore Condition); + } +} + +rule("[Soldier: 76] Rocket Assault Rifle") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Event Player.abilityProjectile2 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(-2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.abilityProjectile1 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.abilityPosition = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, + 0), Event Player, Rotation); + Event Player.abilityEnd = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, 0), + Event Player, Rotation); + Chase Player Variable At Rate(Event Player, abilityPosition, Event Player.abilityProjectile1, 60, Destination and Rate); + Chase Player Variable At Rate(Event Player, abilityEnd, Event Player.abilityProjectile2, 60, Destination and Rate); + Wait Until(Event Player.abilityPosition == 0 && Event Player.abilityEnd == 0, 2.500); + } +} + +rule("[Soldier: 76] First Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.abilityProjectile1 != Event Player.abilityPosition; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.abilityPosition, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.abilityPosition, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.abilityPosition, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.abilityPosition, 2.500); + Stop Chasing Player Variable(Event Player, abilityPosition); + Wait(0.016, Ignore Condition); + Damage(Players Within Radius(Event Player.abilityPosition, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 80); + Stop Chasing Player Variable(Event Player, abilityPosition); + Event Player.abilityPosition = 0; + Event Player.abilityProjectile1 = 0; + Wait(0.016, Ignore Condition); + } +} + +rule("[Soldier: 76] Second Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.abilityProjectile2 != Event Player.abilityEnd; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.abilityEnd, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.abilityEnd, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.abilityEnd, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.abilityEnd, 2.500); + Stop Chasing Player Variable(Event Player, abilityEnd); + Damage(Players Within Radius(Event Player.abilityEnd, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Event Player.abilityEnd = 0; + Event Player.abilityProjectile2 = 0; + } +} + +rule("Soldier: 76 - Init rockets") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Event Player.abilityProjectile1 = Event Player.abilityPosition; + Event Player.abilityProjectile2 = Event Player.abilityEnd; + } +} + +rule("[Soldier: 76] Shoulder Check") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[12] == True; + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 3; + Is Alive(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) == True; + } + + actions + { + Damage(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Event Player, 55); + Set Status(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Null, Knocked Down, 1.500); + Apply Impulse(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Facing Direction Of(Event Player), 15, + To World, Cancel Contrary Motion); + Apply Impulse(Event Player, Vector(0, 8, 15), 15, To Player, Cancel Contrary Motion); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Closest Player To(Event Player, Opposite Team Of(Team Of( + Event Player))), 1); + Set Ability Cooldown(Event Player, Button(Melee), 0); + Press Button(Event Player, Button(Melee)); + Wait(1, Ignore Condition); + } +} + +rule("Torbjorn: Melting Point") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Event Player.abilities[8] == True; + (Is Using Ability 2(Event Player) || Is Using Ultimate(Event Player)) == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Event Player, 8); + Play Effect(All Players(All Teams), Bad Explosion, Color(Yellow), Event Player, 8); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 16); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, + 25); + Set Status(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Off), Null, Burning, 3); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player, 100); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Torbjorn: Roots of Magma") +{ + event + { + Player Dealt Damage; + Team 1; + Torbjörn; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Set Status(Victim, Null, Rooted, 1); + Wait(1, Ignore Condition); + } +} + +rule("Tracer: Vortex") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Heal(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, 0); + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 10); + Play Effect(All Players(All Teams), Ring Explosion, Color(Red), Position Of(Event Player), 24); + Play Effect(All Players(All Teams), Ring Explosion, Color(Yellow), Position Of(Event Player), 18); + Play Effect(All Players(All Teams), Ring Explosion, Color(Green), Position Of(Event Player), 12); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player), 6); + Set Environment Credit Player(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player); + } +} + +rule("Tracer: Vortex 2") +{ + event + { + Player Received Healing; + Team 2; + All; + } + + conditions + { + Healer.abilities[8] == True; + Hero Of(Healer) == Hero(Tracer); + Is Using Ability 2(Healer) == True; + Event Ability == Null; + Event Damage <= 20; + } + + actions + { + Apply Impulse(Event Player, Up, 5, To World, Cancel Contrary Motion); + Wait(0.100, Ignore Condition); + Apply Impulse(Event Player, Direction Towards(Event Player, Healer), Distance Between(Event Player, Healer) * 3.500, To World, + Cancel Contrary Motion); + Set Status(Event Player, Null, Rooted, 1.300); + } +} + +rule("Tracer: Chain Reaction") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is True For Any(Filtered Array(All Players(Team Of(Event Player)), Current Array Element.chainReactionOn), Distance Between( + Event Player, Current Array Element) <= 8 && True) == True; + Event Player.chainReactionImmune == False; + Event Player.chainReactionOn == False; + Is Alive(Event Player) == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Event Player.chainReactionOn = True; + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player, 3); + } +} + +rule("Tracer: Chain Reaction 2") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Event Player.chainReactionOn == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Aqua), Event Player, 3); + Damage(Event Player, Players On Hero(Hero(Tracer), Opposite Team Of(Team Of(Event Player))), 200); + Wait(0.500, Ignore Condition); + Event Player.chainReactionImmune = True; + Event Player.chainReactionOn = False; + Wait(2, Ignore Condition); + Event Player.chainReactionImmune = False; + } +} + +rule("Tracer: Chain Reaction 3") +{ + event + { + Player Dealt Damage; + Team 1; + Tracer; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Damage > 20; + Event Player.abilities[12] == True; + } + + actions + { + Victim.chainReactionOn = True; + } +} + +rule("[Winston] Electric Field") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player.abilityProjectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 65); + Destroy Effect(Event Player.effects_[1]); + Event Player.abilityActive = True; + Create Effect(All Players(All Teams), Orb, Color(White), Event Player.abilityProjectile1, 1, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Stop Chasing Player Variable(Event Player, abilityResource); + Event Player.abilityProjectile1 = Eye Position(Event Player); + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Down * 1000, Null, + All Players(All Teams), False); + Wait(0.100, Ignore Condition); + Event Player.abilityResource = 5; + Wait(0.250, Ignore Condition); + Chase Player Variable At Rate(Event Player, abilityResource, 20, 7, Destination and Rate); + Chase Player Variable At Rate(Event Player, abilityProjectile1, Event Player.abilityEnd, Event Player.abilityResource, + Destination and Rate); + Wait(8.650, Restart When True); + Event Player.abilityActive = False; + } +} + +rule("[Winston] Electric Field 2") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Event Player.abilityActive == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Event Player.abilityProjectile1, 5); + Damage(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 33); + Play Effect(All Players(All Teams), Ring Explosion, Color(Blue), Event Player.abilityProjectile1, 10); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + Damage(Players Within Radius(Event Player.abilityProjectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 80); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Event Player.abilityProjectile1, 12); + Destroy Effect(Event Player.effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player.abilityProjectile1, 125); + } +} + +rule("Winston: Next Generation") +{ + event + { + Player Earned Elimination; + Team 1; + Winston; + } + + conditions + { + Ultimate Charge Percent(Event Player) <= 80; + Is Using Ultimate(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 15); + } +} + +rule("Pharah: Head Trauma") +{ + event + { + Player Dealt Knockback; + Team 1; + Pharah; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[8] == True; + Victim != Event Player; + } + + actions + { + Damage(Victim, Event Player, Max Health(Victim) * 0.300); + Set Status(Victim, Event Player, Knocked Down, 1); + Play Effect(All Players(All Teams), Good Explosion, Color(Team 1), Victim, 1); + } +} + +rule("Pharah: Thunderbird") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[12] == True; + Hero Of(Event Player) == Hero(Pharah); + } + + actions + { + Event Player.damageDealt *= 4; + Start Damage Modification(All Players(All Teams), Event Player, 25, Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Add Health Pool To Player(Event Player, Shields, 150, True, True); + Event Player.hpPool[1] = Last Created Health Pool; + Wait Until(!Event Player.abilities[12] || Hero Of(Event Player) != Hero(Pharah), 99999); + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Stop Damage Modification(Event Player.modificationDamage[1]); + Remove Health Pool From Player(Event Player.hpPool[1]); + } +} + +rule("Orisa: Unstoppable Force") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Event Player.genDirection = Facing Direction Of(Event Player); + Event Player.abilityActive = True; + Create Effect(All Players(All Teams), Sphere, Color(Green), Event Player.abilityProjectile1, 4, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Event Player.abilityProjectile1 = Eye Position(Event Player) + Facing Direction Of(Event Player) * 0.500; + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 100, Null, All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, abilityProjectile1, Event Player.abilityEnd, 25, Destination and Rate); + Wait(0.250, Ignore Condition); + Wait Until((!Event Player.genAvailable && Is Button Held(Event Player, Button(Secondary Fire))) || ( + Event Player.abilityProjectile1 == Event Player.abilityEnd), 99999); + Stop Chasing Player Variable(Event Player, abilityProjectile1); + Wait(0.500, Ignore Condition); + Damage(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, + 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Lime Green), Event Player.abilityProjectile1, 5); + Destroy Effect(Event Player.effects_[1]); + Event Player.abilityActive = False; + } +} + +rule("Orisa: Availability for Halt!") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Event Player.genAvailable = True; + Wait Until(!Is Button Held(Event Player, Button(Secondary Fire)), 99999); + Event Player.genAvailable = False; + } +} + +rule("Orisa: Drag effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Event Player.abilities[12] == True; + Event Player.abilityActive == True; + } + + actions + { + Apply Impulse(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Is Alive(Event Player) ? Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of( + Event Player)), Surfaces) : Empty Array, Event Player.abilityProjectile1), 8, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Event Player.abilityProjectile1, Event Player.abilityEnd), 20, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Up, 5, + To Player, Cancel Contrary Motion); + Wait(0.200, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Orisa: Immoveable Object - Reduce dmg") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Set Damage Received(Event Player, 100 * 0.003); + Wait Until(!Is Using Ability 1(Event Player), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Orisa: Immovable Object - Healing") +{ + event + { + Player Took Damage; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Heal(Event Player, Null, Event Damage * 3); + } +} + +rule("[Reaper] Shadow Streak (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.abilities[8] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Event Player.abilityPosition = Position Of(Event Player) + Vector(0, 1, 0); + Wait(2, Abort When False); + Event Player.abilityEnd = Position Of(Event Player) + Vector(0, 1, 0); + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.abilityEnd, Event Player.abilityPosition, Color(Black), + Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Event Player.abilityActive = True; + Wait Until(Is Dead(Event Player) || Is Using Ability 2(Event Player), 99999); + Destroy Effect(Event Player.effects_[1]); + Event Player.abilityActive = False; + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage start to end (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.abilities[8] == True; + Ray Cast Hit Player(Event Player.abilityPosition, Event Player.abilityEnd, All Living Players(Opposite Team Of(Team Of( + Event Player))), Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.abilityActive == True; + } + + actions + { + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.abilityPosition, + Event Player.abilityEnd, All Living Players(All Teams), Event Player, True), 1); + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.abilityPosition, Event Player.abilityEnd, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage end to start (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.abilities[8] == True; + Ray Cast Hit Player(Event Player.abilityEnd, Event Player.abilityPosition, All Players(Opposite Team Of(Team Of(Event Player))), + Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.abilityActive == True; + } + + actions + { + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.abilityEnd, Event Player.abilityPosition, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.abilityEnd, + Event Player.abilityPosition, All Living Players(All Teams), Event Player, True), 1); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Reaper: Loom") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Hacked, 1.500); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Rooted, 1.500); + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Event Player, 45); + } +} + +rule("Sigma: Gravity Well") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, 25); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Null, Rooted, 2); + Set Status(Event Player, Null, Invincible, 1); + Play Effect(Event Player, Ring Explosion, Color(Blue), Eye Position(Event Player), 50); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Sigma: Gravity Channels") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ultimate(Event Player)), Event Player, 150, + Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Wait Until(!Event Player.abilities[12], 99999); + Stop Damage Modification(Event Player.modificationDamage[1]); + } +} + +rule("Echo: Focusing Optics") +{ + event + { + Player Dealt Damage; + Team 1; + Echo; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[8] == True; + Normalized Health(Victim) > 0.500; + Normalized Health(Victim) <= 0.900; + Is Duplicating(Event Player) == False; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 3); + Play Effect(All Players(All Teams), Bad Explosion, Color(Violet), Victim, 0.500); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Wait(0.700, Abort When False); + Cancel Primary Action(Event Player); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Set Projectile Speed(Event Player, 100); + Wait(0.150, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Bomblets") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Is In Alternate Form(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Orange), Null + Ray Cast Hit Position(Eye Position(Event Player), + Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, All Living Players(Opposite Team Of(Team Of( + Event Player))), All Players(Team Of(Event Player)), True), 2); + Damage(Players Within Radius(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 2, + Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 12); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Taser - Loop damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is True For Any(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive(Current Array Element) + && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status(Current Array Element, + Phased Out) && Distance Between(Event Player, Current Array Element) <= 25) == True; + Is Alive(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Explosion Sound, Color(White), Event Player.abilityPlayer, 80); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Event Player.abilityPlayer, 1); + Event Player.abilityPlayer = Filtered Array(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive( + Current Array Element) && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status( + Current Array Element, Phased Out) && Distance Between(Event Player, Current Array Element) <= 25); + Damage(Players Within Radius(Event Player.abilityPlayer, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 30); + Wait(0.450, Ignore Condition); + Loop If Condition Is True; + Event Player.abilityPlayer = Null; + } +} + +rule("Bastion: Taser - Visual beam") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player + Vector(False, 1, False), + Event Player.abilityPlayer != Null ? Event Player.abilityPlayer : Event Player, Color(Aqua), + Visible To Position Radius and Color); + Event Player.effects_[1] = Last Created Entity; + Wait Until(!Event Player.abilities[12], 99999); + Destroy Effect(Event Player.effects_[1]); + } +} + +rule("Sombra: Malware") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, + Hacked) || Current Array Element.fearedUntil >= Total Time Elapsed), All Players(Team Of(Event Player)), 200, + Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Wait Until(!Event Player.abilities[8], 99999); + Stop Damage Modification(Event Player.modificationDamage[1]); + } +} + +rule("Sombra: Glitch") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Event Player.abilityActive = True; + Event Player.abilityPosition = Position Of(Event Player); + Create Effect(All Players(All Teams), Sphere, Color(Purple), Event Player.abilityPosition, 15, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Wait(8, Ignore Condition); + Destroy Effect(Event Player.effects_[1]); + Event Player.abilityActive = False; + } +} + +rule("Sombra: Glitch - Loop") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.abilityActive == True; + } + + actions + { + Set Status(Players Within Radius(Event Player.abilityPosition, 15, Opposite Team Of(Team Of(Event Player)), Off), Null, Hacked, + 0.750); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Mei: Cold Snap") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Event Player.abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Event Player, 1, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Wait Until(!Is Using Ability 1(Event Player), 99999); + Destroy Effect(Event Player.effects_[1]); + Damage(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Frozen, 2); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Rooted, 2); + Play Effect(All Players(All Teams), Ring Explosion, Color(White), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Sky Blue), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player) + Vector(0, 1, 0), 20); + } +} + +rule("Mei: Icebound") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Is Firing Secondary(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Aqua), Event Player, 0.400, Visible To Position and Radius); + Event Player.effects_[2] = Last Created Entity; + Set Projectile Speed(Event Player, 200); + Wait Until(!Is Firing Secondary(Event Player), 99999); + Destroy Effect(Event Player.effects_[2]); + Set Projectile Speed(Event Player, 100); + } +} + +rule("Mei: Icebound - Icicles hit") +{ + event + { + Player Dealt Damage; + Team 1; + Mei; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Is Using Ability 2(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 1.250); + Set Status(Victim, Null, Frozen, 1); + Set Status(Victim, Null, Rooted, 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Victim, 1); + } +} + +rule("Wrecking Ball: Mirror Ball") +{ + event + { + Player Took Damage; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 4.500, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage); + Wait(0.100, Ignore Condition); + } +} + +rule("Wrecking Ball: Distort") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Set Status(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Hacked, Count Of( + Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces)) * 1.500); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Violet), Position Of(Event Player), 125); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Sound, Color(Purple), Position Of(Event Player), 16); + Play Effect(All Players(All Teams), Explosion Sound, Color(Violet), Position Of(Event Player), 80); + } +} + +rule("Symmetra: High voltage") +{ + event + { + Player Dealt Final Blow; + Team 1; + Symmetra; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Victim, 10); + Play Effect(All Players(All Teams), Bad Explosion, Color(Aqua), Victim, 8); + Damage(Players Within Radius(Victim, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 150); + } +} + +rule("Symmetra: Energy Source") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is True For Any(Players On Hero(Hero(Symmetra), Team Of(Event Player)), Is Using Ultimate(Current Array Element) + && Current Array Element.abilities[12]) == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 1, 40); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Event Player, 0.100); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Junkrat: Pyromania") +{ + event + { + Player Dealt Knockback; + Team 1; + Junkrat; + } + + conditions + { + Event Player.abilities[8] == True; + Event Ability != Button(Melee); + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 2, 30); + Set Status(Victim, Null, Burning, 2); + } +} + +rule("Junkrat: Short Fused") +{ + event + { + Player Dealt Damage; + Team 1; + Junkrat; + } + + conditions + { + Event Player.abilities[12] == True; + Event Ability == Button(Ability 2); + } + + actions + { + Event Player.abilityCountdown = 4; + While(Event Player.abilityCountdown > 0); + Event Player.abilityCountdown -= 1; + Event Player.abilityPosition = Position Of(Victim) + Vector(Random Real(-2, 2), Random Real(-2, 2), Random Real(-2, 2)); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.abilityPosition, 4); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.abilityPosition, 4); + Damage(Players Within Radius(Event Player.abilityPosition, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 35); + Set Status(Players Within Radius(Event Player.abilityPosition, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player, Stunned, 0.800); + Wait(0.200, Ignore Condition); + End; + } +} + +rule("Zenyatta: Vigor") +{ + event + { + Player Dealt Healing; + Team 1; + Zenyatta; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Set Status(Healee, Null, Invincible, 1); + Wait(0.800, Ignore Condition); + } +} + +rule("Zenyatta: Perfect Balance") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Start Damage Over Time(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 0.750, 200); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player, 24); + Wait(0.600, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Stench") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Violet), Event Player, 8, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Wait Until(!Event Player.abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Destroy Effect(Event Player.effects_[1]); + } +} + +rule("Roadhog: Stench effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 8; + Event Player.abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 9); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Rusted Anchor") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ability 1(Event Player)), Event Player, 400, + Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Wait Until(!Event Player.abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Stop Damage Modification(Event Player.modificationDamage[1]); + } +} + +rule("Roadhog: Rusted Anchor - Reset cooldown") +{ + event + { + Player Earned Elimination; + Team 1; + Roadhog; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ability 1(Event Player), 3); + Set Ability Cooldown(Event Player, Button(Ability 1), False); + } +} + +rule("Zarya: Augment") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Start Scaling Barriers(Event Player, 2, True); + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5 + 50; + Set Max Health(Event Player, Event Player.playerHealth); + Wait Until(!Event Player.abilities[8] || Hero Of(Event Player) != Hero(Zarya), 99999); + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + Stop Scaling Barriers(Event Player); + } +} + +rule("Zarya: Perpetual Energy") +{ + event + { + Player Dealt Knockback; + Team 1; + Zarya; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Event Player.abilities[12] == True; + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 9999, 15); + Set Status(Victim, Null, Burning, 9999); + } +} + +rule("Doomfist: Phase Shifter") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + (Is Firing Secondary(Event Player) || Is Using Ability 1(Event Player) || Is Using Ability 2(Event Player)) == True; + Event Player.abilities[8] == True; + } + + actions + { + Set Status(Event Player, Null, Phased Out, 1); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ultimate(Event Player), 99999); + Event Player.abilityPosition = Position Of(Event Player); + Event Player.abilityActive = True; + Wait Until(Is Dead(Event Player), 8); + Event Player.abilityActive = False; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Event Player.abilityActive == True; + Event Player.abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player.abilityPosition, 8, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(Orange), Event Player.abilityPosition, 8, Visible To Position and Radius); + Event Player.effects_[2] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player.abilityPosition, 16); + While(Event Player.abilityActive == True); + Damage(Players Within Radius(Event Player.abilityPosition, 8, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 34); + Wait(0.235, Ignore Condition); + End; + Destroy Effect(Event Player.effects_[1]); + Destroy Effect(Event Player.effects_[2]); + } +} + +rule("Team 1 (perk): Sharpshooter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Global.perk[0] == True; + Event Ability != Null; + Distance Between(Event Player, Victim) >= 10; + } + + actions + { + Damage(Victim, Event Player, 50 / Event Player.damageDealt * Event Damage); + } +} + +rule("Team 1 (perk): Bulletstorm") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.perk[1] == True; + (Ammo(Event Player, 0) < Max Ammo(Event Player, 0) || Ammo(Event Player, 1) < Max Ammo(Event Player, 1)) == True; + } + + actions + { + Set Ammo(Event Player, 0, 1000); + Set Ammo(Event Player, 1, 1000); + } +} + +rule("Team 1 Challenges") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + If(Global.perk[2] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.abilityHUD[17] = Last Text ID; + End; + If(Global.perk[0] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.abilityHUD[18] = Last Text ID; + End; + If(Global.perk[1] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.abilityHUD[19] = Last Text ID; + End; + If(Global.maxHealthDone == 50); + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + End; + } +} + +rule("Remove Auto Repair when Player leaves") +{ + event + { + Player Left Match; + Team 1; + All; + } + + actions + { + Global.autoRepair -= Event Player.abilities[16]; + } +} + +rule("Refund") +{ + event + { + Subroutine; + Refund; + } + + actions + { + "Refund money" + Event Player.money[0] += Event Player.money[1]; + Event Player.money[1] = 0; + "Reset Headhunter" + Event Player.abilities[1] = 0; + "Reset Ambush" + Event Player.abilities[2] = 0; + "Reset QuickFix" + Event Player.abilities[3] = 0; + "Reset HeavyWeight" + Event Player.abilities[4] = 0; + "Reset Charged" + Event Player.abilities[5] = 0; + "Reset Haste" + Event Player.abilities[6] = 0; + "Reset HeavyImpact" + Event Player.abilities[7] = 0; + "Reset HeroTalent1" + Event Player.abilities[8] = 0; + "Reset SecondWind" + Event Player.abilities[9] = 0; + "Reset BindingHeal" + Event Player.abilities[10] = 0; + "Reset Resilience" + Event Player.abilities[11] = 0; + "Reset HeroTalent2" + Event Player.abilities[12] = 0; + "Reset Damage" + Event Player.abilities[13] = 0; + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.damageDealt); + "Reset Health" + Event Player.abilities[14] = 0; + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + If(Global.maxHealthDone == 0); + End; + "Reset Healing" + Event Player.abilities[15] = 0; + Set Healing Dealt(Event Player, 100 + Event Player.abilities[15] * 5); + "Reset autoRepair" + Global.autoRepair -= Event Player.abilities[16]; + Event Player.abilities[16] = 0; + } +} + +rule("Lucio Dash HUD Creation") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + } + + actions + { + If(Event Player.lucioDashActive == False); + Event Player.lucioDashActive = True; + Create HUD Text(Event Player, Null, Null, Custom String("{0} Slam on ground - Press: {1}", Ability Icon String(Hero(Wrecking Ball), + Button(Crouch)), Input Binding String(Button(Crouch))), Left, 1000, Color(White), Color(White), Color(White), + Visible To and String, Default Visibility); + Event Player.lucioDashIcon = Last Text ID; + End; + } +} + +rule("Lucio Dash Remove HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) != Hero(Lúcio); + Event Player.lucioDashActive == True; + } + + actions + { + Destroy HUD Text(Event Player.lucioDashIcon); + Event Player.lucioDashActive = False; + } +} + +rule("Lucio Dash") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + Event Player.lucioDashActive == True; + Is On Ground(Event Player) == False; + Is Button Held(Event Player, Button(Crouch)) == True; + } + + actions + { + Apply Impulse(Event Player, Down, 20, To World, Cancel Contrary Motion); + } +} + +rule("Ana Self-Nano") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + Ultimate Charge Percent(Event Player) == 100; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Abort If(Global.selfNanoWorkshopSetting == False && Number Of Players(Team 1) > 1); + Wait(0.100, Ignore Condition); + If(Is Using Ultimate(Event Player) == False); + Create Dummy Bot(Hero(Ana), Team Of(Event Player), -1, Position Of(Event Player) + Backward, Eye Position(Event Player)); + Event Player.anaEntityID = Last Created Entity; + Wait(0.100, Ignore Condition); + Set Ultimate Charge(Event Player.anaEntityID, 100); + Start Facing(Event Player.anaEntityID, Direction Towards(Eye Position(Event Player.anaEntityID), Position Of(Event Player) + Up), + 1000, To World, Direction and Turn Rate); + Set Invisible(Event Player.anaEntityID, All); + Set Status(Event Player.anaEntityID, Null, Phased Out, 9999); + Wait(0.150, Ignore Condition); + Press Button(Event Player.anaEntityID, Button(Ultimate)); + Set Ultimate Charge(Event Player, 0); + Wait(0.150, Ignore Condition); + Teleport(Event Player.anaEntityID, Position Of(First Of(Spawn Points(Team Of(Event Player))))); + Wait(10, Ignore Condition); + Destroy Dummy Bot(Team Of(Event Player), Slot Of(Event Player.anaEntityID)); + End; + } +} + +rule("Reinhard Charge Cancel") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + } + + actions + { + Wait(0.600, Ignore Condition); + Wait Until(Is Button Held(Event Player, Button(Ability 1)), 5); + Set Status(Event Player, Null, Rooted, 0.001); + Wait Until(Event Player.reinPin, 1); + If(Event Player.reinPin != 0); + Apply Impulse(Event Player.reinPin, Facing Direction Of(Event Player), 15, To World, Cancel Contrary Motion); + End; + } +} + +disabled rule("Map Editor Walls") +{ + event + { + Ongoing - Global; + } +} + +rule("Initial Global") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.allPositions = Empty Array; + Global.allDirections = Empty Array; + Global.wallFirstPosition = Empty Array; + Global.wallSecondPosition = Empty Array; + Global.wallFirstPoint = Empty Array; + Global.wallSecondPoint = Empty Array; + Global.second = Empty Array; + Global.z = Empty Array; + Global.wallId = Empty Array; + Global.BeamType = Empty Array; + } +} + +rule("Initial Player") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.filterPosition = 0; + Event Player.lastSavedPosition = 0; + Event Player.closestBodyPosition = 0; + Event Player.fullBodyPosition = 0; + Event Player.previousPositionIntersection = 0; + Event Player.activeWall = Empty Array; + Event Player.closestWall = Empty Array; + } +} + +rule("Collision Logic") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Event Player.lastSavedPosition = (Eye Position(Event Player) + Position Of(Event Player)) / 2; + Wait(0.016, Ignore Condition); + Event Player.closestWall = Filtered Array(Global.allPositions, Distance Between(Global.allPositions[Current Array Index], Event Player) + <= Distance Between(Global.allPositions[Current Array Index], Global.wallFirstPosition[Current Array Index]) + || Event Player.activeWall[Current Array Index] == 1 || (Dot Product(Direction Towards(Current Array Element, + Event Player.lastSavedPosition), Global.allDirections[Current Array Index]) > 0) != (Dot Product(Direction Towards(Current Array Element, + Event Player), Global.allDirections[Current Array Index]) > 0)); + For Player Variable(Event Player, x, 0, Count Of(Event Player.closestWall), 1); + Global.z = Index Of Array Value(Global.allPositions, Event Player.closestWall[Event Player.x]); + If(Global.wallId[Global.z] == 1 || Global.wallId[Global.z] == 3 || Global.wallId[Global.z] == 5); + If(Y Component Of(Global.wallFirstPosition[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.wallFirstPosition[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestBodyPosition = Global.wallFirstPosition[Global.z]; + Else If(Y Component Of(Global.wallSecondPosition[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.wallSecondPosition[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestBodyPosition = Global.wallSecondPosition[Global.z]; + Else; + Event Player.closestBodyPosition = Position Of(Event Player); + End; + Event Player.fullBodyPosition = Vector(X Component Of(Eye Position(Event Player)), Y Component Of(Event Player.closestBodyPosition), + Z Component Of(Eye Position(Event Player))); + Event Player.filterPosition = Event Player.fullBodyPosition + Global.allDirections[Global.z] * Dot Product( + Global.allPositions[Global.z] - Event Player.fullBodyPosition, Global.allDirections[Global.z]) / Dot Product(Global.allDirections[Global.z], + Global.allDirections[Global.z]); + If(Global.wallId[Global.z] == 1 || Global.wallId[Global.z] == 3); + If((Dot Product(Direction Towards(Global.allPositions[Global.z], Event Player.lastSavedPosition), Global.allDirections[Global.z]) > 0) != ( + Dot Product(Direction Towards(Global.allPositions[Global.z], Event Player.fullBodyPosition), Global.allDirections[Global.z]) > 0)); + Event Player.intersectionLength = Dot Product(Global.allPositions[Global.z] - Event Player.fullBodyPosition, Global.allDirections[Global.z]) + / Dot Product(Direction Towards(Event Player.lastSavedPosition, Event Player.fullBodyPosition), Global.allDirections[Global.z]); + Event Player.previousPositionIntersection = Event Player.fullBodyPosition + Direction Towards(Event Player.lastSavedPosition, + Event Player.fullBodyPosition) * Vector(1, Empty Array, 1) * Event Player.intersectionLength; + If(Dot Product(Direction Towards(Global.wallFirstPosition[Global.z], Vector(X Component Of(Global.wallSecondPosition[Global.z]), Y Component Of( + Global.wallFirstPosition[Global.z]), Z Component Of(Global.wallSecondPosition[Global.z]))), Direction Towards(Global.wallFirstPosition[Global.z], + Event Player.previousPositionIntersection)) >= 0 && Dot Product(Direction Towards(Global.wallFirstPosition[Global.z], Vector(X Component Of( + Global.wallFirstPosition[Global.z]), Y Component Of(Global.wallSecondPosition[Global.z]), Z Component Of(Global.wallFirstPosition[Global.z]))), + Direction Towards(Global.wallFirstPosition[Global.z], Event Player.previousPositionIntersection)) >= 0 && Dot Product(Direction Towards( + Global.wallSecondPosition[Global.z], Vector(X Component Of(Global.wallSecondPosition[Global.z]), Y Component Of(Global.wallFirstPosition[Global.z]), + Z Component Of(Global.wallSecondPosition[Global.z]))), Direction Towards(Global.wallSecondPosition[Global.z], Event Player.previousPositionIntersection)) + >= 0 && Dot Product(Direction Towards(Global.wallSecondPosition[Global.z], Vector(X Component Of(Global.wallFirstPosition[Global.z]), + Y Component Of(Global.wallSecondPosition[Global.z]), Z Component Of(Global.wallFirstPosition[Global.z]))), Direction Towards( + Global.wallSecondPosition[Global.z], Event Player.previousPositionIntersection)) >= 0); + Cancel Primary Action(Event Player); + Teleport(Event Player, Event Player.previousPositionIntersection + Direction Towards(Event Player.previousPositionIntersection, + Event Player.lastSavedPosition) * Vector(1, Empty Array, 1) * 2); + End; + End; + End; + Event Player.thickness = 0; + If(Global.wallId[Global.z] == 5); + Event Player.thickness = 4; + Else; + Event Player.thickness = 1; + End; + If(Distance Between(Event Player.fullBodyPosition, Event Player.filterPosition) <= Event Player.thickness && Dot Product(Direction Towards( + Global.wallFirstPosition[Global.z], Vector(X Component Of(Global.wallSecondPosition[Global.z]), Y Component Of(Global.wallFirstPosition[Global.z]), + Z Component Of(Global.wallSecondPosition[Global.z]))), Direction Towards(Global.wallFirstPosition[Global.z], Event Player.filterPosition)) + >= 0 && Dot Product(Direction Towards(Global.wallFirstPosition[Global.z], Vector(X Component Of(Global.wallFirstPosition[Global.z]), + Y Component Of(Global.wallSecondPosition[Global.z]), Z Component Of(Global.wallFirstPosition[Global.z]))), Direction Towards( + Global.wallFirstPosition[Global.z], Event Player.filterPosition)) >= 0 && Dot Product(Direction Towards(Global.wallSecondPosition[Global.z], Vector( + X Component Of(Global.wallSecondPosition[Global.z]), Y Component Of(Global.wallFirstPosition[Global.z]), Z Component Of( + Global.wallSecondPosition[Global.z]))), Direction Towards(Global.wallSecondPosition[Global.z], Event Player.filterPosition)) >= 0 && Dot Product( + Direction Towards(Global.wallSecondPosition[Global.z], Vector(X Component Of(Global.wallFirstPosition[Global.z]), Y Component Of( + Global.wallSecondPosition[Global.z]), Z Component Of(Global.wallFirstPosition[Global.z]))), Direction Towards(Global.wallSecondPosition[Global.z], + Event Player.filterPosition)) >= 0); + If(!Global.isGrounded); + Set Gravity(Event Player, 100); + End; + If(Event Player.activeWall[Global.z] == False); + Event Player.activeWall[Global.z] = 1; + If((Global.wallId[Global.z] == 1 || Global.wallId[Global.z] == 3) && Global.isGrounded == False); + Set Gravity(Event Player, 100); + Else If(Global.wallId[Global.z] == 5); + Disable Movement Collision With Environment(Event Player, False); + End; + End; + If(Global.wallId[Global.z] == 1); + Apply Impulse(Event Player, Direction Towards(Event Player.filterPosition, Event Player.fullBodyPosition) * Vector(1, Empty Array, 1), 0.001, + To World, Cancel Contrary Motion); + Set Move Speed(Event Player, 100 - Dot Product(Direction Towards(Eye Position(Event Player), Eye Position(Event Player) + + World Vector Of(Throttle Of(Event Player), Event Player, Rotation)), Direction Towards(Event Player.filterPosition, + Event Player.fullBodyPosition) * -1) * 100); + Else If(Global.wallId[Global.z] == 3); + Apply Impulse(Event Player, Direction Towards(Event Player.filterPosition, Event Player.fullBodyPosition), Speed Of(Event Player), To World, + Cancel Contrary Motion); + End; + Else; + Event Player.activeWall[Global.z] = 0; + Set Move Speed(Event Player, 100); + End; + End; + End; + Loop; + } +} + +rule("Reset") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Count Of(Filtered Array(Event Player.activeWall, Current Array Element != 0)) == 0; + } + + actions + { + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("Effect Creation") +{ + event + { + Ongoing - Global; + } + + actions + { + Wait(5, Ignore Condition); + If(Global.showWalls); + For Global Variable(x, 0, Count Of(Global.allPositions), 1); + If(Global.wallId[Global.x] == 5); + Create Beam Effect(All Players(Team 1), Good Beam, Global.wallFirstPosition[Global.x], Vector(X Component Of(Global.wallSecondPosition[Global.x]), + Y Component Of(Global.wallFirstPosition[Global.x]), Z Component Of(Global.wallSecondPosition[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.wallSecondPosition[Global.x]), Y Component Of( + Global.wallFirstPosition[Global.x]), Z Component Of(Global.wallSecondPosition[Global.x])), Global.wallSecondPosition[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.wallFirstPosition[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.wallFirstPosition[Global.x]), Y Component Of(Global.wallSecondPosition[Global.x]), Z Component Of( + Global.wallFirstPosition[Global.x])), Color(Red), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.wallFirstPosition[Global.x]), Y Component Of( + Global.wallSecondPosition[Global.x]), Z Component Of(Global.wallFirstPosition[Global.x])), Global.wallSecondPosition[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Red), None); + Else; + Skip(Array(14, 0, 5, 10)[Index Of Array Value(Array(1, 2, 3), Global.BeamType[Global.x]) + 1]); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.wallFirstPosition[Global.x], Vector(X Component Of(Global.wallSecondPosition[Global.x]), + Y Component Of(Global.wallFirstPosition[Global.x]), Z Component Of(Global.wallSecondPosition[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.wallSecondPosition[Global.x]), Y Component Of( + Global.wallFirstPosition[Global.x]), Z Component Of(Global.wallSecondPosition[Global.x])), Global.wallSecondPosition[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Global.wallFirstPosition[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.wallFirstPosition[Global.x]), Y Component Of(Global.wallSecondPosition[Global.x]), Z Component Of( + Global.wallFirstPosition[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Grapple Beam, Vector(X Component Of(Global.wallFirstPosition[Global.x]), Y Component Of( + Global.wallSecondPosition[Global.x]), Z Component Of(Global.wallFirstPosition[Global.x])), Global.wallSecondPosition[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(9); + Create Beam Effect(All Players(Team 1), Good Beam, Global.wallFirstPosition[Global.x], Vector(X Component Of(Global.wallSecondPosition[Global.x]), + Y Component Of(Global.wallFirstPosition[Global.x]), Z Component Of(Global.wallSecondPosition[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.wallSecondPosition[Global.x]), Y Component Of( + Global.wallFirstPosition[Global.x]), Z Component Of(Global.wallSecondPosition[Global.x])), Global.wallSecondPosition[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Global.wallFirstPosition[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.wallFirstPosition[Global.x]), Y Component Of(Global.wallSecondPosition[Global.x]), Z Component Of( + Global.wallFirstPosition[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Good Beam, Vector(X Component Of(Global.wallFirstPosition[Global.x]), Y Component Of( + Global.wallSecondPosition[Global.x]), Z Component Of(Global.wallFirstPosition[Global.x])), Global.wallSecondPosition[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Skip(4); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.wallFirstPosition[Global.x], Vector(X Component Of(Global.wallSecondPosition[Global.x]), + Y Component Of(Global.wallFirstPosition[Global.x]), Z Component Of(Global.wallSecondPosition[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.wallSecondPosition[Global.x]), Y Component Of( + Global.wallFirstPosition[Global.x]), Z Component Of(Global.wallSecondPosition[Global.x])), Global.wallSecondPosition[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Global.wallFirstPosition[Global.x] + Vector(0.001, Empty Array, Empty Array), Vector( + X Component Of(Global.wallFirstPosition[Global.x]), Y Component Of(Global.wallSecondPosition[Global.x]), Z Component Of( + Global.wallFirstPosition[Global.x])), Color(Aqua), None); + Create Beam Effect(All Players(Team 1), Bad Beam, Vector(X Component Of(Global.wallFirstPosition[Global.x]), Y Component Of( + Global.wallSecondPosition[Global.x]), Z Component Of(Global.wallFirstPosition[Global.x])), Global.wallSecondPosition[Global.x] + Vector(Empty Array, + Empty Array, 0.001), Color(Aqua), None); + End; + Wait(0.016, Ignore Condition); + End; + End; + } +} + +rule("Wall Data") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.allPositions = Array(Vector(155.968, 12.470, -30.507), Vector(155.962, 12.472, -62.500), Vector(81.153, 6.453, -103.851), Vector( + 69.148, 6.474, -104.548)); + Global.allDirections = Array(Vector(-1, 0, -0.002), Vector(1, 0, -0.001), Vector(0, 0, 1), Vector(0.001, 0, 1)); + Global.wallFirstPosition = Array(Vector(155.971, 11.047, -31.771), Vector(155.964, 11.050, -61.229), Vector(79.761, 5.030, -103.852), + Vector(67.738, 5.022, -104.547)); + Global.wallSecondPosition = Array(Vector(155.965, 13.894, -29.242), Vector(155.960, 13.894, -63.771), Vector(82.544, 7.876, -103.851), + Vector(70.558, 7.925, -104.550)); + Global.wallFirstPoint = Array(Vector(155.971, 13.894, -31.771), Vector(155.964, 13.894, -61.229), Vector(79.761, 7.876, -103.852), + Vector(67.738, 7.925, -104.547)); + Global.wallSecondPoint = Array(Vector(155.965, 11.047, -29.242), Vector(155.960, 11.050, -63.771), Vector(82.544, 5.030, -103.851), + Vector(70.558, 5.022, -104.550)); + Global.z = 3; + Global.BeamType = Array(1, 1, 1, 1); + Global.showWalls = True; + Global.wallId = Array(5, 5, 5, 5); + } +} + +disabled rule("NEW SHOP") +{ + event + { + Ongoing - Global; + } +} + +rule("Setting Shop Position") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.shopCamPosition = 900 * Up; + Global.shopPositionAngle[1] = Direction From Angles(Horizontal Angle From Direction(Forward), Vertical Angle From Direction(Forward) + - 90); + Global.shopPositionAngle[0] = Cross Product(Global.shopPositionAngle[1], Forward); + Global.shopBasePosition = Global.shopCamPosition - 9 * Global.shopPositionAngle[1] + 142 * Forward; + } +} + +rule("Create Shop Buttons") +{ + event + { + Ongoing - Global; + } + + actions + { + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.shopBasePosition - 41 * Global.shopPositionAngle[1] + 90 * Global.shopPositionAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), Global.shopBasePosition - 41 * Global.shopPositionAngle[1] - 90 * Global.shopPositionAngle[0], 2.500, + Do Not Clip, Visible To, Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Refund"), + Global.shopBasePosition + 45 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 3, Do Not Clip, Visible To, Color(Green), + Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("[{0}] Leave", + Input Binding String(Button(Reload))), Global.shopBasePosition + 45 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 3, + Do Not Clip, Visible To and String, Color(Green), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("{0}$\n", Local Player.money[0]), + Global.shopBasePosition + 36.500 * Global.shopPositionAngle[1], 3, Do Not Clip, Visible To and String, Color(White), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("▲"), Update Every Frame( + Global.shopBasePosition - (4 + Vertical Facing Angle Of(Local Player)) * Global.shopPositionAngle[1] + Horizontal Facing Angle Of( + Local Player) * Global.shopPositionAngle[0]), 4, Do Not Clip, Visible To Position and Color, Custom Color( + 245 + 10 * Sine From Radians(4 * Total Time Elapsed), 205 + 50 * Sine From Radians(4 * Total Time Elapsed), + 200 * Sine From Radians(4 * Total Time Elapsed), 255), Default Visibility); + "Headhunter" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[1] ? Custom String("Headhunter II\n  800$") : Custom String("Headhunter I\n  800$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[1] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Ambush" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[2] ? Custom String("Ambush II\n 800$") : Custom String("Ambush I\n 800$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[2] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Quick Fix" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[3] ? Custom String("Quick Fix II\n  700$") : Custom String("Quick Fix I\n  700$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[3] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavyweight" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[4] ? Custom String("Heavyweight II\n  1000$") : Custom String("Heavyweight I\n  1000$"), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[4] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Charged" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[5] ? Custom String("Charged II\n  700$") : Custom String("Charged I\n  700$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[5] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Haste" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[6] ? Custom String("Haste II\n 700$") : Custom String("Haste I\n 700$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[6] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavy Impact" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[7] ? Custom String("Heavy Impact II\n  1000$") : Custom String("Heavy Impact I\n  1000$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[7] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 1" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 1\n  1200$"), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[8] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "Second Wind" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[9] ? Custom String("Second Wind II\n   900$") : Custom String("Second Wind I\n   900$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[9] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Binding Heal" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[10] ? Custom String("Binding Heal II\n   700$") : Custom String("Binding Heal I\n   700$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[10] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Resilience" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[11] ? Custom String("Resilience II\n  800$") : Custom String("Resilience I\n  800$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[11] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 2" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 2\n  1200$"), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[12] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "PlusDamage" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Damage\n  400$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealth" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Health\n 400$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Healing\n  400$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, Visible To and String, + Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "+{0} Auto-Repair\n    400$", Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Global.autoRepair < 5 ? Color(Green) : Color(Gray), Default Visibility); + "Use Update Every Frame to avoid showing the String when the cursor is out of bounds, resulting in 0\r\n ROW 0" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -33.750 ? Array(Custom String("Leave Buy Menu\n"), Custom String( + ""), Custom String(""), Custom String("Refund your money\n"))[Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) + / 45, Down)] : Custom String("")), Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, Visible To and String, + Color(White), Default Visibility); + "ROW 1" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 22.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -11.250 ? Array(Custom String("Increase your damage by 5%\n"), + Local Player.abilities[9] ? Custom String( + "Second Wind II: 60% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds") + : Custom String( + "Second Wind I: 30% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds"), + Local Player.abilities[5] ? Custom String("Charged II: Ultimates cost 40% less\n") : Custom String( + "Charged I: Ultimates cost 20% less\n"), Local Player.abilities[1] ? Custom String( + "Headhunter II: Critical hits deal 80% more damage\n") : Custom String("Headhunter I: Critical hits deal 40% more damage\n")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 2" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 36.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 11.250 ? Array(Custom String("Increase your health by 5%\n"), + Local Player.abilities[10] ? Custom String("Binding Heal II: Heal yourself for 50% the amount when healing allies\n") + : Custom String("Binding Heal I: Heal yourself for 25% the amount when healing allies\n"), + Local Player.abilities[6] ? Custom String( + " Haste II: Ability cooldown is reduced by 50%\nDoes not affect abilities with multiple charges") : Custom String( + " Haste I: Ability cooldown is reduced by 25%\nDoes not affect abilities with multiple charges"), + Local Player.abilities[2] ? Custom String("Ambush II: Deal 60% more damage when attacking enemies from behind or above\n") + : Custom String("Ambush I: Deal 30% more damage when attacking enemies from behind or above\n"))[Round To Integer(( + Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 3" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 83.750) < 72.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 33.750 ? Array(Custom String("Increase your healing by 5%\n"), + Local Player.abilities[11] ? Custom String("Resilience II: Take 30% less damage while below 60% health\n") : Custom String( + "Resilience I: Take 30% less damage while below 30% health\n"), Local Player.abilities[7] ? Custom String( + "Heavy Impact II: Every hit has a chance to stun the enemy for 2 seconds\n") : Custom String( + "Heavy Impact I: Every hit has a chance to stun the enemy for 1 second\n"), Local Player.abilities[3] ? Custom String( + "Quick Fix II: Eliminations restore 100 HP and shortly increase speed by 40%\n") : Custom String( + "Quick Fix I: Eliminations restore 50 HP and shortly increase speed by 20%\n"))[Round To Integer((Horizontal Facing Angle Of( + Local Player) + 90) / 45, Down)] : Custom String("")), Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, + Visible To and String, Color(White), Default Visibility); + "ROW 4" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 133) < 99.250 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 56.250 ? Array(Custom String( + "Increase your auto-repair by {0}/5s\n", Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Custom String("{0}", Local Player.heroTalentText[2][1]), Custom String("{0}", Local Player.heroTalentText[1][1]), + Local Player.abilities[4] ? Custom String( + "Heavyweight II: Your knock back attacks deal 50% more damage and knock back\n            You receive 33% less knock back") + : Custom String( + "Heavyweight I: Your knock back attacks deal 25% more damage and knock back\n            You receive 20% less knock back")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), Default Visibility); + } +} + +rule("Toggle Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + !Is Dummy Bot(Event Player) == True; + Is Button Held(Event Player, Button(Reload)) == True; + !Is Communicating Any Emote(Event Player) == True; + } + + actions + { + If(Event Player.isInMenu == False); + Wait Until(!Is Button Held(Event Player, Button(Reload)), 0.500); + If(!Is Button Held(Event Player, Button(Reload))); + Abort; + End; + End; + Event Player.isInMenu = !Event Player.isInMenu; + } +} + +rule("Open Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == True; + } + + actions + { + Event Player.playerFacing = Facing Direction Of(Event Player); + Start Camera(Event Player, Global.shopCamPosition, Global.shopCamPosition + Forward, 0); + Disable Hero HUD(Event Player); + Call Subroutine(disablePlayer); + Set Aim Speed(Event Player, 200); + } +} + +rule("Close Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == False; + } + + actions + { + Stop Camera(Event Player); + Enable Hero HUD(Event Player); + Call Subroutine(EnablePlayer); + Set Aim Speed(Event Player, 100); + Set Facing(Event Player, Event Player.playerFacing, To World); + } +} + +rule("Subroutine: Disable Player") +{ + event + { + Subroutine; + disablePlayer; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + Set Primary Fire Enabled(Event Player, False); + Set Secondary Fire Enabled(Event Player, False); + Set Ability 1 Enabled(Event Player, False); + Set Ability 2 Enabled(Event Player, False); + Set Melee Enabled(Event Player, False); + Set Jump Enabled(Event Player, False); + Set Crouch Enabled(Event Player, False); + Disallow Button(Event Player, Button(Ultimate)); + } +} + +rule("Subroutine: Enable Player") +{ + event + { + Subroutine; + EnablePlayer; + } + + actions + { + Stop Forcing Throttle(Event Player); + Set Primary Fire Enabled(Event Player, True); + Set Secondary Fire Enabled(Event Player, True); + Set Ability 1 Enabled(Event Player, True); + Set Ability 2 Enabled(Event Player, True); + Set Melee Enabled(Event Player, True); + Set Jump Enabled(Event Player, True); + Set Crouch Enabled(Event Player, True); + Allow Button(Event Player, Button(Ultimate)); + } +} + +rule("Buy Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Primary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + Event Player.isInMenu = !Event Player.isInMenu; + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.money[1] != 0); + Call Subroutine(Refund); + Else; + Small Message(Local Player, Custom String("You don't have anything to refund!")); + End; + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Event Player.abilities[13] += 1; + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.damageDealt); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[9] != 2); + If(Event Player.money[0] >= 900); + Event Player.money[0] -= 900; + Event Player.money[1] += 900; + Event Player.abilities[9] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[5] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[5] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[1] != 2); + If(Event Player.money[0] >= 800); + Event Player.money[0] -= 800; + Event Player.money[1] += 800; + Event Player.abilities[1] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Event Player.abilities[14] += 1; + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[10] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[10] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[6] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[6] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[2] != 2); + If(Event Player.money[0] >= 800); + Event Player.money[0] -= 800; + Event Player.money[1] += 800; + Event Player.abilities[2] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Event Player.abilities[15] += 1; + Set Healing Dealt(Event Player, 100 + Event Player.abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[11] != 2); + If(Event Player.money[0] >= 800); + Event Player.money[0] -= 800; + Event Player.money[1] += 800; + Event Player.abilities[11] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[7] != 2); + If(Event Player.money[0] >= 1000); + Event Player.money[0] -= 1000; + Event Player.money[1] += 1000; + Event Player.abilities[7] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[3] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[3] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Global.autoRepair != 5); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Global.autoRepair += 1; + Event Player.abilities[16] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[12] != 1); + If(Event Player.money[0] >= 1200); + Event Player.money[0] -= 1200; + Event Player.money[1] += 1200; + Event Player.abilities[12] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[8] != 1); + If(Event Player.money[0] >= 1200); + Event Player.money[0] -= 1200; + Event Player.money[1] += 1200; + Event Player.abilities[8] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[4] != 2); + If(Event Player.money[0] >= 1000); + Event Player.money[0] -= 1000; + Event Player.money[1] += 1000; + Event Player.abilities[4] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + End; + } +} + +rule("Refund Single Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Secondary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[13] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Event Player.abilities[13] -= 1; + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.damageDealt); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[9] != 0); + Event Player.money[0] += 900; + Event Player.money[1] -= 900; + Event Player.abilities[9] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[5] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[5] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[1] != 0); + Event Player.money[0] += 800; + Event Player.money[1] -= 800; + Event Player.abilities[1] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[14] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Event Player.abilities[14] -= 1; + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[10] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[10] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[6] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[6] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[2] != 0); + Event Player.money[0] += 800; + Event Player.money[1] -= 800; + Event Player.abilities[2] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[15] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Event Player.abilities[15] -= 1; + Set Healing Dealt(Event Player, 100 + Event Player.abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[11] != 0); + Event Player.money[0] += 800; + Event Player.money[1] -= 800; + Event Player.abilities[11] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[7] != 0); + Event Player.money[0] += 1000; + Event Player.money[1] -= 1000; + Event Player.abilities[7] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[3] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[3] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[16] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Global.autoRepair -= 1; + Event Player.abilities[16] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[12] != 0); + Event Player.money[0] += 1200; + Event Player.money[1] -= 1200; + Event Player.abilities[12] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[8] != 0); + Event Player.money[0] += 1200; + Event Player.money[1] -= 1200; + Event Player.abilities[8] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[4] != 0); + Event Player.money[0] += 1000; + Event Player.money[1] -= 1000; + Event Player.abilities[4] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + End; + } +} + +rule("Create Player HUD") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Custom String("{0}{1}", + Event Player, Event Player.isInMenu ? Custom String("(In Shop)") : Custom String("")), Custom String("{0}{1}", Is Alive( + Event Player) ? Custom String("{0} HP", Round To Integer(Health(Event Player), Up)) : Custom String("Dead"), Custom String( + ", {0}$", Event Player.money)), Left, Local Player == Event Player ? -1 : Slot Of(Event Player), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), + Visible To Sort Order String and Color, Default Visibility); + Create HUD Text(Event Player.abilities[13] || Global.damageDealt ? Event Player : Null, Null, Null, Custom String("+{0}% Damage", + Global.damageDealt + Event Player.abilities[13] * 5), Left, 913, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[9] ? Event Player : Null, Null, Null, Custom String("Second Wind {0}", + Event Player.abilities[9] == 1 ? Custom String("I") : Custom String("II")), Left, 908, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[5] ? Event Player : Null, Null, Null, Custom String("Charged {0}", + Event Player.abilities[5] == 1 ? Custom String("I") : Custom String("II")), Left, 905, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[1] ? Event Player : Null, Null, Null, Custom String("Headhunter {0}", + Event Player.abilities[1] == 1 ? Custom String("I") : Custom String("II")), Left, 901, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[14] || Global.maxHealthDone ? Event Player : Null, Null, Null, Custom String("+{0}% Health", + Global.maxHealthDone + Event Player.abilities[14] * 5), Left, 914, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[10] ? Event Player : Null, Null, Null, Custom String("Binding Heal {0}", + Event Player.abilities[10] == 1 ? Custom String("I") : Custom String("II")), Left, 909, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[6] ? Event Player : Null, Null, Null, Custom String("Haste {0}", + Event Player.abilities[6] == 1 ? Custom String("I") : Custom String("II")), Left, 906, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[2] ? Event Player : Null, Null, Null, Custom String("Ambush {0}", + Event Player.abilities[2] == 1 ? Custom String("I") : Custom String("II")), Left, 902, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[15] ? Event Player : Null, Null, Null, Custom String("+{0}% Healing", + Event Player.abilities[15] * 5), Left, 915, Color(White), Color(White), Color(Turquoise), Visible To and String, + Default Visibility); + Create HUD Text(Event Player.abilities[11] ? Event Player : Null, Null, Null, Custom String("Resilience {0}", + Event Player.abilities[11] == 1 ? Custom String("I") : Custom String("II")), Left, 910, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[7] ? Event Player : Null, Null, Null, Custom String("Heavy Impact {0}", + Event Player.abilities[7] == 1 ? Custom String("I") : Custom String("II")), Left, 907, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[3] ? Event Player : Null, Null, Null, Custom String("Quick Fix {0}", + Event Player.abilities[3] == 1 ? Custom String("I") : Custom String("II")), Left, 903, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Global.autoRepair ? Event Player : Null, Null, Null, Custom String("{0} total Auto-Repair/5s", + Global.autoRepair * (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 10 : 5)), Left, 916, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[12] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.heroTalentText[2][0], Event Player.heroTalentText[2][1]), Top, 902, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[12] ? Event Player : Null, Null, Null, Custom String("Hero Talent 2"), Left, 912, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[8] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.heroTalentText[1][0], Event Player.heroTalentText[1][1]), Top, 901, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[8] ? Event Player : Null, Null, Null, Custom String("Hero Talent 1"), Left, 911, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[4] ? Event Player : Null, Null, Null, Custom String("Heavyweight {0}", + Event Player.abilities[4] == 1 ? Custom String("I") : Custom String("II")), Left, 904, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + } +} + +rule("Rein Pin detect") +{ + event + { + Player Dealt Knockback; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 1); + Has Status(Victim, Stunned) == True; + } + + actions + { + Event Player.reinPin = Victim; + Wait(1, Ignore Condition); + Event Player.reinPin = Null; + } +} + +rule("Boss Rotation") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.activeBoss == True; + } + + actions + { + If(Global.bossRotation == 0 || Global.bossRotation == 3); + Global.bossRotation = 1; + Global.lastBoss[1] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 1); + Global.bossRotation = 2; + Global.lastBoss[2] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 2); + Global.bossRotation = 3; + Global.lastBoss[3] = Hero Of(Global.activeBoss); + End; + } +} + +rule("BOSS HUD") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMin == 10; + } + + actions + { + Create HUD Text(All Players(Team 1), Global.activeBoss ? Custom String("Boss: {0}, HP: {1}/{2}", Hero Of(Global.activeBoss), + Health(Global.activeBoss), Max Health(Global.activeBoss)) : Custom String(""), Null, Null, Top, 900, Color(Red), Color(White), + Color(White), Visible To and String, Default Visibility); + } +} + +rule("DEBUG - SKIP TIME") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.isDebug == True; + (Is Button Held(Event Player, Button(Primary Fire)) && Is Button Held(Event Player, Button(Crouch))) == True; + } + + actions + { + Global.timeSec = 59; + } +} + +disabled rule("DEBUG COLLECTION - Make Invincible, Show Player Coords") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.isDebug == True; + } + + actions + { + Create HUD Text(Local Player, Custom String("{0}", Position Of(Local Player)), Null, Null, Left, 0, Color(Yellow), Color(White), + Color(White), Visible To and String, Default Visibility); + Set Status(Event Player, Null, Invincible, 9999); + Set Status(Event Player, Null, Phased Out, 9999); + } +} + +rule("OPTIONAL ENDING - CREATE EXFIL POINT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("Exfiltration available! (optional - ends the mode)"), Null, Null, Top, 50, + Color(Red), Color(White), Color(White), Visible To and String, Default Visibility); + Global.globalHUDs[1] = Last Text ID; + Create In-World Text(All Players(Team 1), Custom String( + "Exfiltration available! Gather here!\n{0}/{1} Players ready to exfiltrate!", Count Of(Filtered Array(All Players(Team 1), + Distance Between(Vector(186, 11, -46.500), Current Array Element) <= 9)), Count Of(All Players(Team 1))), Vector(186, 15, + -46.500), 1.200, Do Not Clip, Visible To and String, Color(Green), Default Visibility); + Wait(3, Ignore Condition); + Destroy HUD Text(Global.globalHUDs[1]); + } +} + +rule("OPTIONAL ENDING - EXFIL PLAYERS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + Count Of(Filtered Array(All Players(Team 1), Distance Between(Vector(186, 11, -46.500), All Players(Team 1)) <= 9)) >= Count Of(All Players(Team 1)) / 2; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GG! YOU DID IT!")); + Destroy All Dummy Bots; + Disable Movement Collision With Environment(All Players(Team 1), True); + Start Accelerating(All Players(Team 1), Up, 100, 5, To World, Direction Rate and Max Speed); + Wait(5, Ignore Condition); + Declare Team Victory(Team 1); + } +} + +rule("Team 1 (Ability): Second Wind save life") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + conditions + { + Event Player.abilities[9] == True; + Event Player.secondWindActive == True; + Health(Event Player) == 1; + } + + actions + { + Small Message(All Players(All Teams), Custom String("{0} received a second wind!", Event Player)); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Green), Event Player, 1); + Clear Status(Event Player, Unkillable); + Set Player Health(Event Player, Max Health(Event Player)); + Event Player.lastSecondWind = 30; + Event Player.secondWindActive = 0; + } +} + +rule("Team 1 (Ability): Second Wind after buying") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[9] == True; + Event Player.secondWindActive == False; + Event Player.lastSecondWind == 0; + } + + actions + { + If(Random Integer(1, 100) > Event Player.abilities[9] * 30); + Wait(30, Ignore Condition); + Loop; + End; + Set Status(Event Player, Null, Unkillable, 9999); + Event Player.secondWindActive = 1; + } +} + +rule("Team 1 (Ability): Second Wind counter") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Player.lastSecondWind > 0; + } + + actions + { + Wait(1, Ignore Condition); + Event Player.lastSecondWind -= 1; + Loop If Condition Is True; + } +} + +rule("Team 1: Change Hero") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Distance Between(Vector(149.000, 10, -62.000), Event Player) <= 2; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + Set Player Allowed Heroes(Event Player, Hero(Pharah)); + Set Player Allowed Heroes(Event Player, Hero(Ana)); + If(Global.isStoryHeroes); + Reset Player Hero Availability(Event Player); + Set Player Allowed Heroes(Event Player, Array(Hero(Ana), Hero(Brigitte), Hero(Mercy), Hero(Lúcio), Hero(Moira), Hero(Baptiste), + Hero(Ashe), Hero(D.Va), Hero(Genji), Hero(Hanzo), Hero(Widowmaker), Hero(Cassidy), Hero(Reinhardt), Hero(Soldier: 76), Hero( + Torbjörn), Hero(Tracer), Hero(Winston), Hero(Pharah))); + Else; + Reset Player Hero Availability(Event Player); + End; + Wait(0.500, Ignore Condition); + Wait Until(Has Spawned(Event Player), 99999); + Teleport(Event Player, Vector(149.000, 10, -62.000)); + } +} \ No newline at end of file diff --git a/defendTheCastleExtended/old_versions/c128.ow b/defendTheCastleExtended/old_versions/c128.ow new file mode 100644 index 0000000..1558e41 --- /dev/null +++ b/defendTheCastleExtended/old_versions/c128.ow @@ -0,0 +1,9311 @@ +settings +{ + main + { + Description: "Defend The Castle Extended v0.6.c128\nby ShuriZma#2349\nJ1K6F (Code Version: c126)\nOriginal mode by HuKuTa94#2589\n\nDefend the gate, kill enemies and don't allow them to damage the gate!\n\nSpecial Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents\n& Josbird for teaching me about Menus!\n\nFind this mode on: workshop.codes/defend-the-castle\nFind the Original Mode on: workshop.codes/BQEGS\nTell me what you think on Discord: discord.shurizma.de\n\nPS: SHINGEN PLS COME BACK" + Mode Name: "Defend The Castle Extended" + } + + lobby + { + Max Spectators: 0 + Max Team 1 Players: 4 + Max Team 2 Players: 0 + Return To Lobby: Never + Swap Teams After Match: No + } + + modes + { + Escort + { + enabled maps + { + Havana + } + } + + Team Deathmatch + { + enabled maps + { + } + } + + General + { + Game Mode Start: Immediately + Spawn Health Packs: Disabled + } + } + + workshop + { + Story Heroes: Off + } + + extensions + { + Beam Effects + Kinetic Explosion Effects + Energy Explosion Effects + Explosion Sounds + Play More Effects + Spawn More Dummy Bots + } +} + +variables +{ + global: + 0: gatePosition + 1: zenSpawnPositions + 2: spawnPositionMaxId + 3: loopIterator1 + 4: bigBossSpawnPositions + 5: playerSpawnPositions + 6: gateHealthChase + 7: gateHealth + 8: gateMaxHealth + 9: gateProgressBarColorCurrent + 10: gateProgressBarColorComponent + 11: gateHealthEvent + 12: bastionTargetPositions + 13: sniperPositions + 14: ballSpawnPositions + 15: zenRespawnTime + 16: timeSeconds + 17: timeMinutes + 18: defaultCurrentBot + 19: defaultHeroBotsPool + 20: defaultHeroBotsPoolCurrentId + 21: isDebug + 22: botOrisaParent + 23: isStoryHeroes + 24: botOrisaChild + 25: gateRepairPosition + 26: botOrisaTargetPosition + 27: botEchoRespawnPosition + 28: botEchoTeleportPositions + 29: upgradeGateMaxHealthValue + 30: upgradeGateMaxHealthHudId + 31: upgradePlayerMaxHealthValue + 32: upgradePlayerMaxHealthHudId + 33: upgradeCriticalDamageValue + 34: upgradeCriticalDamageHudId + 35: upgradeMaxAmmoValue + 36: upgradeMaxAmmoHudId + 37: upgradeMaxAmmoMaxValue + 38: upgradePlayerMaxHealthMaxValue + 39: upgradeCriticalDamageMaxValue + 40: upgradeGateMaxHealthMaxValue + 41: damageDealt + 42: isDebugAINavigation + 43: gameLogicCountOfUniqueHeroes + 44: isNewWaveGameLogicProcessing + 45: automaticRepair + 46: upgradePerkSharpshooterValue + 47: perk + 48: maxHealthDone + 49: startMoney + 50: time5Minutes + 51: selfNanoWorkshopSetting + 52: shopCamPosition + 53: shopBasePosition + 54: shopPositionAngle + 55: activeBoss + 56: bossTrigger + 57: bossRotation + 58: lastBoss + 59: time10Minutes + 60: moneyMultiplier + 61: challengeCount + 62: upgradeBossHealthValue + 63: globalHUDs + 112: allPositions + 113: allDirections + 114: firstPosition + 115: secondPosition + 116: firstPoint + 117: secondPoint + 118: second + 119: z + 120: wallId + 121: showWalls + 122: isGrounded + 123: beamType + 125: nodePositions + 126: nodeConnections + 127: distanceMatrix + + player: + 0: botSeePlayer + 1: botDoesUniqueBehaviour + 2: botEffects + 3: botRayCastHitPosition + 4: botEventPosition + 5: currentHero + 6: isDead + 7: isRespawning + 8: botBastionArtilleryDidShotsCount + 9: botCounter + 10: hasBadStatus + 11: eventHealth + 12: healOverTimeId + 13: botIsOrisaChild + 14: botEchoCapturedPlayer + 15: botPlayersInRadius + 16: botLoopIterator2 + 17: botWidowShotTime + 18: botWidowTeleportTime + 19: isNanoed + 20: abilityHUD + 21: lucioDashActive + 22: lucioDashIcon + 23: anaEntityID + 24: abilities + 25: money + 26: heroTalentText + 27: damageDealt + 28: playerHealth + 29: abilityCountdown + 30: hpPool + 31: effects_ + 32: abilityProjectile1 + 33: abilityEnd + 34: stormProjectile + 35: stormEndPoint + 36: stormEffects + 37: fearedUntil + 38: modificationDamage + 39: abilityProjectile2 + 40: abilityPosition + 41: chainReactionOn + 42: chainReactionImmune + 43: abilityActive + 44: abilityResource + 45: secondWindActive + 46: isInMenu + 47: reinPin + 48: playerFacing + 49: isBoss + 50: genDirection + 51: genAvailable + 52: abilityPlayer + 53: deathPosition + 54: lastSecondWind + 105: filterPosition + 106: lastSavedPosition + 107: closestBodyPosition + 108: fullBodyPosition + 109: previousPositionIntersection + 110: activeWall + 111: closestWall + 112: x + 113: intersectionLength + 114: thickness + 115: botCancelPathFinding + 116: botLoopIterator1 + 117: botTempArray + 118: botTargetPlayer + 119: botTargetPosition + 120: botClosestNodeIdToTarget + 121: botClosestNodeIdToBot + 122: botPreviousNodeId + 123: botNextNodeId + 124: botNextNodePosition + 125: botCurrentDistanceToTarget + 126: botShortestDistanceToTarget + 127: botIsPathFinding +} + +subroutines +{ + 0: BotBastionArtilleryDamage + 1: BotBastionFlameGunDamage + 2: BotBastionRespawn + 3: GateProgressBarColor + 4: BotZenyattaRespawn + 5: BotWidowRespawn + 6: BotBallRespawn + 7: GameLogicAddNextHeroInGame + 8: BotOrisaRespawn + 9: BotLandingFromSky + 10: BotEchoRespawn + 11: BotEchoDetachPlayer + 12: BotEchoFlyToPlayer + 13: BotEchoFlyToPortal + 14: GameLogicSetBotProperties + 15: DisablePlayer + 16: BotAppearFromUnderground + 17: BotReinRespawn + 18: PlayerInit + 19: BotInit + 20: PlayerRespawn + 21: BotRespawn + 22: BotWidowBadStatus + 23: GameLogicWave0 + 24: Refund + 25: EnablePlayer + 26: GateRepair + 124: BotStartPathFinding + 125: BotGetClosestNodeIdToTarget + 126: BotGetNextNodeIdAndPosition + 127: BotResetPathFinding +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("MAP: HAVANA") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Havana); + } + + actions + { + Global.nodePositions = Array(Vector(147.588, 6.425, -46.749), Vector(136.181, 6.425, -57.159), Vector(130.189, 6.425, -63.781), + Vector(123.305, 6.425, -57.983), Vector(125.678, 6.504, -46.633), Vector(114.485, 7.471, -46.699), Vector(138.743, 6.425, + -32.974), Vector(126.498, 6.425, -39.920), Vector(124.572, 10.434, -34.300), Vector(138.605, 5.359, -18.647), Vector(119.009, + 2.331, -31.024), Vector(121.138, 5.228, -19.933), Vector(126.722, 6.425, -29.505), Vector(102.762, 3.157, -33.609), Vector( + 76.030, 7.418, -74.087), Vector(83.720, 9.425, -33.744), Vector(97.439, 7.238, -42.379), Vector(86.252, 12.416, -47.261), + Vector(65.178, 11.425, -73.187), Vector(97.466, 7.269, -50.596), Vector(113.039, 7.424, -37.337), Vector(106.179, 7.450, + -46.143), Vector(90.086, 7.411, -44.653), Vector(78.752, 7.418, -62.140), Vector(82.124, 7.428, -44.229), Vector(90.675, 7.231, + -51.234), Vector(85.717, 4.692, -63.446), Vector(90.830, 4.330, -70.697), Vector(102.425, 2.387, -72.817), Vector(81.443, + 4.425, -81.648), Vector(70.743, 6.418, -81.495), Vector(69.738, 6.419, -96.344), Vector(127.586, 12.643, -63.344), Vector( + 118.911, 13.468, -58.008), Vector(102.885, 1.092, -56.579), Vector(100.009, 2.967, -67.139), Vector(106.703, 0.465, -44.628), + Vector(81.695, 7.418, -52.140), Vector(126.979, 12.393, -55.079), Vector(153.720, 18.578, -21.745), Vector(155.301, 18.619, + -17.595), Vector(133.043, 10.425, -26.625), Vector(114.646, 7.278, -57.336), Vector(95.160, 3.688, -81.194), Vector(78.456, + 5.418, -93.581), Vector(75.455, 5.418, -101.492), Vector(148.071, 9.432, -32.123), Vector(146.706, 9.425, -27.858), Vector( + 144.273, 9.445, -63.119), Vector(144.278, 9.454, -58.447)); + Global.nodeConnections = Array(Array(1, 6, 4, 7), Array(2, 1, 4, 6, 7, 0, 49), Array(1, 3), Array(2, 4, 42), Array(3, 1, 5, 7, 6, + 1, 0), Array(4, 7, 20, 21, 19, 16, 42), Array(7, 1, 4, 1, 9, 12, 0, 46), Array(4, 5, 6, 1, 1, 12, 0), Array(7, 41), Array(6, + 11), Array(11, 13), Array(9, 10, 13), Array(6, 7, 10), Array(10, 16, 36), Array(18, 23, 30), Array(17, 24), Array(13, 19, 22, + 21, 25, 5), Array(15, 22, 25, 23), Array(14), Array(16, 21, 22, 26, 27, 35, 25, 5), Array(5, 13, 10), Array(19, 16, 5, 13, 22, + 34), Array(16, 19, 21, 24, 25), Array(14, 25, 26, 37), Array(22, 15, 37), Array(23, 22, 19, 16, 26, 27, 35, 37), Array(25, 19, + 27, 35, 29), Array(19, 26, 25, 29, 35, 43), Array(35, 34, 43), Array(27, 26, 30, 43, 44), Array(29, 14, 31), Array(30, 29, 45), + Array(33, 38, 1, 48), Array(32, 38, 42), Array(35, 36, 28), Array(28, 19, 25, 27, 26, 34), Array(13, 34), Array(25, 23, 24), + Array(5, 4, 1, 6, 1, 32, 33, 0), Array(40), Array(39), Array(6, 8, 47, 46), Array(3, 5, 34), Array(28, 27, 29, 44), Array(29, + 43, 45), Array(44, 31), Array(6, 47), Array(46, 41), Array(49, 32), Array(1, 0, 6, 48)); + Global.distanceMatrix = Array(Array(0, 1, 2, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, + 4, 5, 4, 4, 5, 5, 5, 0, 0, 4, 3, 5, 6, 7, 2, 3, 3, 2), Array(1, 0, 1, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, + 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 3, 4, 4, 4, 5, 5, 4, 0, 0, 4, 3, 5, 6, 7, 2, 3, 2, 1), Array(2, 1, 0, 1, 2, 3, 2, 2, 6, 3, 4, 4, + 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 4, 6, 7, 8, 4, 5, 3, 4, 4, 6, 5, 0, 0, 5, 2, 5, 6, 7, 3, 4, 3, 2), Array(2, 2, + 1, 0, 1, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, 5, 6, 2, 3, 3, 5, 6, 0, 0, 5, 1, 4, + 5, 6, 3, 4, 4, 3), Array(1, 1, 2, 1, 0, 1, 1, 1, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, + 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, 2, 3, 3, 2), Array(2, 2, 3, 2, 1, 0, 2, 1, 6, 3, 2, 3, 2, 2, 4, 4, 1, 5, 5, 1, 1, 1, 2, 3, + 3, 2, 2, 2, 3, 3, 4, 5, 5, 6, 2, 2, 3, 3, 6, 0, 0, 5, 1, 3, 4, 5, 3, 4, 4, 3), Array(1, 1, 2, 2, 1, 2, 0, 1, 4, 1, 2, 2, 1, 3, + 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 4, 5, 4, 4, 4, 5, 5, 0, 0, 3, 3, 5, 6, 7, 1, 2, 3, 2), Array(1, 1, 2, 2, + 1, 1, 1, 0, 5, 2, 2, 3, 1, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, + 2, 3, 3, 2), Array(2, 2, 3, 3, 2, 2, 2, 1, 0, 3, 3, 4, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, + 5, 5, 6, 0, 0, 1, 3, 5, 6, 7, 2, 2, 4, 3), Array(2, 2, 3, 3, 2, 3, 1, 2, 5, 0, 2, 1, 2, 2, 6, 6, 3, 7, 7, 4, 4, 4, 4, 5, 5, 4, + 5, 5, 5, 6, 7, 8, 5, 6, 4, 5, 3, 5, 6, 0, 0, 4, 4, 6, 7, 8, 2, 3, 4, 3), Array(4, 4, 5, 5, 4, 3, 3, 4, 7, 2, 0, 1, 4, 1, 5, 5, + 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 7, 8, 3, 4, 2, 4, 8, 0, 0, 6, 4, 5, 6, 7, 4, 5, 6, 5), Array(3, 3, 4, 4, 3, 3, + 2, 3, 6, 1, 1, 0, 3, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 6, 7, 3, 4, 2, 4, 7, 0, 0, 5, 4, 5, 6, 7, 3, 4, + 5, 4), Array(2, 2, 3, 3, 2, 2, 1, 1, 5, 2, 1, 2, 0, 2, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, 3, 5, + 6, 0, 0, 4, 3, 5, 6, 7, 2, 3, 4, 3), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 3, 1, 2, 4, 0, 4, 4, 1, 5, 5, 2, 3, 2, 2, 3, 3, 2, 3, 3, + 3, 4, 5, 6, 7, 8, 2, 3, 1, 3, 8, 0, 0, 7, 3, 4, 5, 6, 5, 6, 6, 5), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 5, 6, 6, 4, 0, 4, 3, 5, + 1, 3, 5, 4, 3, 1, 3, 2, 2, 3, 4, 2, 1, 2, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 3, 3, 3, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, + 5, 10, 7, 5, 6, 6, 4, 3, 0, 3, 1, 4, 3, 5, 3, 2, 2, 1, 2, 3, 3, 4, 4, 4, 5, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 4, 5, 6, 7, 8, + 8, 7), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 3, 3, 0, 4, 4, 1, 2, 1, 1, 2, 2, 1, 2, 2, 3, 3, 4, 5, 6, 7, 2, 2, 2, 2, + 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 1, 2, 0, 3, 2, 4, 2, 1, 1, 2, 1, 2, 2, + 3, 3, 3, 4, 8, 9, 3, 2, 4, 2, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 6, 7, 7, 5, 1, 5, 4, 6, + 0, 4, 6, 5, 4, 2, 4, 3, 3, 4, 5, 3, 2, 3, 10, 11, 5, 4, 6, 3, 11, 0, 0, 10, 6, 4, 4, 4, 8, 9, 9, 8), Array(3, 3, 4, 3, 2, 1, 3, + 2, 7, 4, 3, 4, 3, 2, 3, 3, 1, 4, 4, 0, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 3, 4, 6, 7, 2, 1, 3, 2, 7, 0, 0, 6, 2, 2, 3, 4, 4, 5, 5, + 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 3, 1, 2, 3, 1, 5, 5, 2, 6, 6, 2, 0, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 6, 7, 3, 3, 2, 4, 7, + 0, 0, 6, 2, 4, 5, 6, 4, 5, 5, 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 4, 3, 1, 4, 5, 1, 2, 0, 1, 3, 2, 2, 2, 2, 2, + 3, 4, 5, 6, 7, 1, 2, 2, 3, 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 3, 2, 1, 3, 4, + 1, 3, 1, 0, 2, 1, 1, 2, 2, 3, 3, 4, 5, 7, 8, 2, 2, 3, 2, 8, 0, 0, 7, 3, 3, 4, 5, 5, 6, 6, 5), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, + 6, 4, 5, 5, 3, 1, 3, 2, 4, 2, 2, 4, 3, 2, 0, 2, 1, 1, 2, 3, 2, 2, 3, 8, 9, 3, 2, 4, 1, 9, 0, 0, 8, 4, 3, 3, 4, 6, 7, 7, 6), + Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 3, 1, 2, 2, 4, 2, 4, 2, 1, 2, 0, 2, 3, 3, 4, 4, 4, 5, 8, 9, 3, 3, 4, 1, 9, 0, + 0, 8, 4, 4, 5, 6, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 2, 3, 1, 4, 3, 1, 3, 2, 1, 1, 2, 0, 1, 1, 2, 2, + 3, 4, 7, 8, 2, 1, 3, 1, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, + 3, 2, 2, 2, 3, 1, 0, 1, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 2, 2, 3, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, + 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 0, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 1, 2, 3, 5, 6, 6, 5), Array( + 5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 4, 5, 3, 6, 5, 2, 4, 3, 3, 3, 4, 2, 2, 2, 0, 2, 3, 4, 8, 9, 1, 1, 2, 3, 9, 0, 0, 8, + 4, 1, 2, 3, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 2, 5, 3, 6, 3, 2, 4, 3, 3, 3, 4, 2, 1, 1, 2, 0, 1, 2, + 8, 9, 3, 2, 4, 3, 9, 0, 0, 8, 4, 1, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 1, 5, 4, 6, 2, 3, 5, 4, + 4, 2, 4, 3, 2, 2, 3, 1, 0, 1, 9, 10, 4, 3, 5, 3, 10, 0, 0, 9, 5, 2, 2, 2, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, + 7, 6, 5, 2, 6, 4, 7, 3, 3, 5, 4, 4, 3, 5, 3, 2, 2, 3, 1, 1, 0, 9, 10, 4, 3, 5, 4, 10, 0, 0, 9, 5, 2, 2, 1, 7, 8, 8, 7), Array( + 2, 1, 2, 3, 2, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 4, 5, 6, 7, 0, 1, 3, 4, 4, 5, 1, 0, 0, 5, + 2, 5, 6, 7, 3, 4, 1, 2), Array(2, 2, 3, 2, 2, 2, 2, 3, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, + 1, 0, 2, 3, 3, 5, 1, 0, 0, 5, 1, 4, 5, 6, 3, 4, 2, 3), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 5, 3, 4, 5, 2, 4, 5, 3, 6, 5, 2, 4, 3, + 3, 3, 4, 2, 2, 2, 1, 3, 4, 5, 8, 9, 0, 1, 1, 3, 9, 0, 0, 8, 4, 2, 3, 4, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, + 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 1, 1, 2, 3, 4, 7, 8, 1, 0, 2, 2, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(5, 5, + 6, 5, 4, 3, 5, 4, 9, 4, 2, 3, 5, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 8, 9, 1, 2, 0, 4, 9, 0, 0, 8, 4, 3, + 4, 5, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 2, 2, 3, 3, 2, 4, 3, 2, 1, 1, 1, 2, 2, 3, 3, 3, 4, 8, 9, + 3, 2, 4, 0, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(1, 1, 2, 2, 1, 1, 1, 2, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, + 4, 3, 3, 3, 4, 4, 5, 6, 1, 1, 3, 3, 4, 4, 0, 0, 0, 4, 2, 4, 5, 6, 2, 3, 2, 2), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(2, 2, 3, 3, 2, 3, 1, 2, 1, 2, 3, 3, 2, + 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 0, 4, 6, 7, 8, 1, 1, 4, 3), Array(3, 3, 2, + 1, 2, 1, 3, 2, 7, 4, 3, 4, 3, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 6, 7, 1, 2, 2, 4, 7, 0, 0, 6, 0, 3, 4, + 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 3, 5, 3, 6, 4, 2, 4, 3, 3, 3, 4, 2, 2, 1, 1, 1, 2, 3, 8, 9, 2, + 2, 3, 3, 9, 0, 0, 8, 4, 0, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 3, 6, 4, 7, 4, 3, 5, 4, 4, 4, 5, + 3, 2, 2, 2, 1, 2, 2, 9, 10, 3, 3, 4, 4, 10, 0, 0, 9, 5, 1, 0, 1, 7, 8, 8, 7), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 7, 8, 7, 6, + 3, 7, 5, 8, 4, 4, 6, 5, 5, 4, 6, 4, 3, 3, 3, 2, 2, 1, 10, 11, 4, 4, 5, 5, 11, 0, 0, 10, 6, 2, 1, 0, 8, 9, 9, 8), Array(2, 2, 3, + 3, 2, 3, 1, 2, 3, 2, 3, 3, 2, 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 2, 4, 6, 7, + 8, 0, 1, 4, 3), Array(3, 3, 4, 4, 3, 4, 2, 3, 2, 3, 4, 4, 3, 5, 8, 8, 5, 9, 9, 5, 5, 5, 6, 7, 7, 6, 6, 6, 7, 7, 8, 9, 6, 7, 6, + 6, 6, 7, 7, 0, 0, 1, 5, 7, 8, 9, 1, 0, 5, 4), Array(2, 2, 3, 4, 3, 3, 2, 3, 6, 3, 4, 4, 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, + 5, 5, 5, 5, 6, 7, 8, 1, 2, 4, 5, 5, 6, 2, 0, 0, 5, 3, 6, 7, 8, 3, 4, 0, 1), Array(1, 1, 2, 3, 2, 3, 1, 2, 5, 2, 3, 3, 2, 4, 7, + 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 2, 3, 5, 5, 5, 6, 3, 0, 0, 4, 4, 6, 7, 8, 2, 3, 1)); + } +} + +rule("SUBROUTINE: BOT - RESET PATH FINDING") +{ + event + { + Subroutine; + BotResetPathFinding; + } + + actions + { + Event Player.botTargetPlayer = -1; + Event Player.botTargetPosition = -1; + Event Player.botPreviousNodeId = -1; + Event Player.botClosestNodeIdToTarget = -1; + Event Player.botNextNodeId = -1; + Event Player.botNextNodePosition = -1; + Event Player.botIsPathFinding = False; + Event Player.botCancelPathFinding = False; + Stop Throttle In Direction(Event Player); + disabled Stop Facing(Event Player); + } +} + +rule("SUBROUTINE: BOT - START PATH FINDING") +{ + event + { + Subroutine; + BotStartPathFinding; + } + + actions + { + disabled Abort If(Event Player.botIsPathFinding == True); + Call Subroutine(BotGetNextNodeIdAndPosition); + disabled Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Event Player.botIsPathFinding = True; + } +} + +rule("SUBROUTINE: BOT - GET NEXT NODE ID AND POSITION") +{ + event + { + Subroutine; + BotGetNextNodeIdAndPosition; + } + + actions + { + "BOT JUST START FOLLOW PATH OR LOST NEXT NODE" + If(Event Player.botPreviousNodeId == -1); + Event Player.botClosestNodeIdToBot = Index Of Array Value(Global.nodePositions, Sorted Array(Filtered Array(Global.nodePositions, + Is In Line of Sight(Position Of(Event Player) + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS) == True), + Distance Between(Position Of(Event Player), Current Array Element))[0]); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + "NEXT NODE IS TARGET (DISTANCE TO TARGET NODE = 1)" + If(Global.distanceMatrix[Event Player.botClosestNodeIdToBot][Event Player.botClosestNodeIdToTarget] == 1); + Event Player.botNextNodeId = Event Player.botClosestNodeIdToTarget; + "CHECK CONNECTIONS OF REACHED NODE" + Else; + Event Player.botShortestDistanceToTarget = 999; + Event Player.botCurrentDistanceToTarget = Event Player.botShortestDistanceToTarget; + Event Player.botTempArray = Global.nodeConnections[Event Player.botClosestNodeIdToBot]; + For Player Variable(Event Player, botLoopIterator1, 0, Count Of(Event Player.botTempArray), 1); + Event Player.botCurrentDistanceToTarget = Global.distanceMatrix[Event Player.botTempArray[Event Player.botLoopIterator1]][Event Player.botClosestNodeIdToTarget]; + If(Event Player.botCurrentDistanceToTarget < Event Player.botShortestDistanceToTarget); + Event Player.botShortestDistanceToTarget = Event Player.botCurrentDistanceToTarget; + Event Player.botNextNodeId = Event Player.botTempArray[Event Player.botLoopIterator1]; + End; + End; + End; + "NEXT NODE IS HIGHER THAN BOT AND BOT DIDN'T REACH CLOSEST NODE" + If(Y Component Of(Position Of(Event Player)) - Y Component Of(Global.nodePositions[Event Player.botNextNodeId]) + < -3 && Event Player.botPreviousNodeId != Event Player.botClosestNodeIdToBot); + Event Player.botPreviousNodeId = Event Player.botClosestNodeIdToBot; + Event Player.botNextNodeId = Event Player.botClosestNodeIdToBot; + "BOT CAN SEE TARGET POSITION AND NEXT NODE IS TARGET" + Else If( + Global.distanceMatrix[Event Player.botClosestNodeIdToBot][Event Player.botClosestNodeIdToTarget] == 1 && Is In Line of Sight( + Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.botTargetPosition + Vector(0, 2, 0), Barriers Do Not Block LOS)); + Event Player.botNextNodePosition = Event Player.botTargetPosition; + Abort; + "BOT CAN'T SEE NEXT NODE AND PREV NODE != REACHED NODE" + Else If(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), + Global.nodePositions[Event Player.botNextNodeId] + Vector(0, 2, 0), Barriers Do Not Block LOS) + == False && Event Player.botPreviousNodeId != Event Player.botClosestNodeIdToBot); + Event Player.botPreviousNodeId = Event Player.botClosestNodeIdToBot; + Event Player.botNextNodeId = Event Player.botClosestNodeIdToBot; + End; + Event Player.botNextNodePosition = Global.nodePositions[Event Player.botNextNodeId]; + } +} + +rule("SUBROUTINE: BOT - GET CLOSEST NODE ID AND POSITION TO TARGET") +{ + event + { + Subroutine; + BotGetClosestNodeIdToTarget; + } + + actions + { + Event Player.botTargetPosition = Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) + : Event Player.botTargetPosition; + Event Player.botClosestNodeIdToTarget = Index Of Array Value(Global.nodePositions, Sorted Array(Filtered Array( + Global.nodePositions, Is In Line of Sight(Event Player.botTargetPosition + Vector(0, 2, 0), Current Array Element, + Barriers Do Not Block LOS) == True), Distance Between(Event Player.botTargetPosition, Current Array Element))[0]); + } +} + +rule("BOT: PATH FINDING - START") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + (Event Player.botTargetPosition != -1 || Event Player.botTargetPlayer != -1) == True; + } + + actions + { + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - CANCEL") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.botIsPathFinding == True; + Event Player.botCancelPathFinding == True; + } + + actions + { + Start Rule(BotResetPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - LOST THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.botIsPathFinding == True; + (Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.botNextNodePosition + Vector(0, 2.500, 0), + Barriers Do Not Block LOS) == False && Speed Of In Direction(Event Player, Throttle Of(Event Player)) < 2) == True; + } + + actions + { + Wait(0.500, Abort When False); + "RESET PREV NODE ID TO INFORM BOT THAT IT LOST NEXT NODE" + Event Player.botPreviousNodeId = -1; + "TRY FIND NEW NEXT NODE" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodeId), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +rule("BOT: PATH FINDING - REACHED THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.botIsPathFinding == True; + Event Player.botClosestNodeIdToTarget >= 0; + (Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.botNextNodePosition), 0, Z Component Of(Event Player.botNextNodePosition))) < 0.850) == True; + } + + actions + { + Event Player.botPreviousNodeId = Event Player.botNextNodeId; + Event Player.botClosestNodeIdToBot = Event Player.botNextNodeId; + "BOT'S TARGET IS PLAYER" + If(Event Player.botTargetPlayer != -1); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + Event Player.botCurrentDistanceToTarget = Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of( + Position Of(Event Player))), Vector(X Component Of(Event Player.botTargetPosition), 0, Z Component Of( + Event Player.botTargetPosition))); + "BOT REACHED THE TARGET NODE OR TARGET POSITION" + If(Event Player.botNextNodeId == Event Player.botClosestNodeIdToTarget || Event Player.botCurrentDistanceToTarget <= 0.850); + "BOT DIDN'T REACH TARGET POSITION" + If(Event Player.botCurrentDistanceToTarget > 0.850); + Event Player.botNextNodePosition = Event Player.botTargetPosition; + Skip(6); + "BOT REACHED TARGET" + Else; + Call Subroutine(BotResetPathFinding); + Abort; + End; + End; + "CONTINUE FOLLOW PATH" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: GAME MODE INIT - WORKSHOP SETTINGS") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.isDebug = False; + Global.isDebugAINavigation = False; + Global.gateMaxHealth = Workshop Setting Integer(Custom String("Defend The Castle Extended"), Custom String("GATE MAX HEALTH"), 500, + 100, 1000, 0); + Global.moneyMultiplier = Workshop Setting Real(Custom String("Defend The Castle Extended"), Custom String("Money Multiplicator"), + 1, 0.500, 2, 0); + Global.isStoryHeroes = Workshop Setting Toggle(Custom String("Defend The Castle Extended"), Custom String("Story Heroes"), True, + 0); + Global.selfNanoWorkshopSetting = Workshop Setting Toggle(Custom String("Ana Self Nano"), Custom String( + "Ana can nano herself even if there are other players (only if no player targeted)"), False, 0); + } +} + +rule("GLOBAL: GAME MODE INIT - COMMON PROPERTIES") +{ + event + { + Ongoing - Global; + } + + actions + { + Create HUD Text(All Players(All Teams), Null, Null, Custom String( + "Defend The Castle Extended v0.6.c128 BY ShuriZma#2349\r\nOriginal mode by HUKUTA94#2589\r\nDiscord: discord.shurizma.de\r\n{0}", + Custom String( + "Special Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents &\nJosbird for teaching me about Menus{0}", + Custom String(" \nPS: SHINGEN PLS COME BACK"))), Right, -1000, Null, Null, Color(White), Visible To, Default Visibility); + Global.gateRepairPosition = Vector(153, 8, -46.500); + Global.gatePosition = Vector(148.800, 6, -46.400); + Global.ballSpawnPositions = Array(Vector(104, 7, -46), Vector(106, 2, -31)); + Global.sniperPositions = Array(Vector(154, 18, -22.600), Vector(86, 12, -46.600), Vector(80.880, 11.300, -71.600), Vector(98, 9, + -19)); + Global.zenSpawnPositions = Array(Vector(79.500, 5, -100), Vector(90, 4, -88), Vector(65, 11, -70), Vector(85, 4, -68), Vector(96, + 2, -73), Vector(84, 7, -47), Vector(95, 9, -34), Vector(108, 1.700, -28), Vector(113, 7, -37), Vector(123, 5, -19), Vector(144, + 5, -19), Vector(123, 6, -39), Vector(123, 6, -61), Vector(129, 6, -30.500), Vector(135, 6, -63)); + Global.playerSpawnPositions = Array(Vector(160, 10, -53), Vector(158, 10, -53), Vector(160, 10, -39), Vector(158, 10, -39)); + Global.bigBossSpawnPositions = Array(Vector(78, 4, -84), Vector(95, 4, -82)); + Global.bastionTargetPositions = Array(Vector(131, 12, -62), Vector(115, 7, -46), Objective Position(2), Vector(136, 10, -27)); + Global.spawnPositionMaxId = 2; + Global.botOrisaTargetPosition = Vector(104, 7, -46); + Global.botEchoRespawnPosition = Vector(130, 23, -44); + Global.botEchoTeleportPositions = Array(Vector(88, 23, -79), Vector(108, 18, -27)); + Global.defaultHeroBotsPool = Array(Hero(Zenyatta), Hero(Widowmaker), Null, Hero(Bastion), Hero(Echo), Hero(Bastion)); + Global.zenRespawnTime = 10; + Global.gameLogicCountOfUniqueHeroes = 5; + Global.lastBoss = Array(Null, Null, Null, Null); + Create Effect(All Players(Team 1), Ring, Color(Sky Blue), Vector(186, 11, -46.500), 9, Visible To Position and Radius); + Create Effect(All Players(Team 1), Ring, Color(Yellow), Vector(159, 11, -46.500), 2, Visible To Position and Radius); + } +} + +disabled rule("PLAYER: DEBUG - PRESS INTERACT") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Host Player == True; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + disabled Modify Player Score(Event Player, 10); + disabled Global.gateHealth -= 5; + disabled Start Rule(GateProgressBarColor, Restart Rule); + Global.timeSeconds = 59; + Set Status(Event Player, Null, Phased Out, 9999); + disabled Set Ultimate Charge(Event Player, 100); + disabled Kill(Event Player, Null); + disabled Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: DEBUG - AI NAVIGATION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.isDebugAINavigation == True; + } + + actions + { + For Global Variable(loopIterator1, 0, Count Of(Global.nodePositions), 1); + Create Effect(All Players(All Teams), Sphere, Color(Red), Global.nodePositions[Global.loopIterator1], 0.850, Visible To); + Create In-World Text(All Players(All Teams), Custom String("NODE {0}", Global.loopIterator1), + Global.nodePositions[Global.loopIterator1], 1.200, Clip Against Surfaces, Visible To, Color(White), Default Visibility); + End; + } +} + +disabled rule("GLOBAL: DEBUG - CREATE BOTS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + Create Dummy Bot(Hero(Bastion), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + Create Dummy Bot(Hero(Orisa), Team 2, -1, Objective Position(2), Vector(0, 0, 0)); + } +} + +disabled rule("PLAYER: DEBUG - INFOS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.isDebug == True; + Host Player == Event Player; + Has Spawned(Event Player) == True; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Create HUD Text(Event Player, Custom String("POS {0}\r\nFACING {1}", Position Of(Event Player), Facing Direction Of(Event Player)), + Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + Create HUD Text(Event Player, Custom String("SERVER PERFORMANCE\r\nLOAD {0}%\r\nPEAK {1}%\r\nAVG {2}%", Server Load, + Server Load Peak, Server Load Average), Null, Null, Left, -99, Color(White), Color(White), Color(White), Visible To and String, + Default Visibility); + disabled Create Progress Bar HUD Text(Event Player, 45, Custom String("45 / 100 KILLS"), Left, -99, Color(Blue), Color(White), + Visible To Values and Color, Default Visibility); + disabled Create HUD Text(Event Player, Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Null, Custom String( + "LEVEL 1 - 50 AMMO CLIP"), Left, -99, Color(White), Color(White), Color(White), Visible To and String, Default Visibility); + "ЭФФЕКТ С ОФФСЕТОМ ОТ ПОЗИЦИИ ГЛАЗ" + disabled Create Beam Effect(All Players(All Teams), Bad Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + Facing Direction Of( + Event Player) * 3, Eye Position(Event Player) + Facing Direction Of(Event Player) * 50, Color(Purple), + Visible To Position and Radius); + } +} + +disabled rule("=== TEAM UPGRADES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: TEAM UPGRADES - INIT") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.upgradeMaxAmmoMaxValue[0] = 250; + Global.upgradeMaxAmmoMaxValue[1] = 500; + Global.upgradeMaxAmmoMaxValue[2] = 1000; + Global.upgradeCriticalDamageMaxValue[0] = 10; + Global.upgradeCriticalDamageMaxValue[1] = 5; + Global.upgradeCriticalDamageMaxValue[2] = 5; + Global.upgradePlayerMaxHealthMaxValue[0] = 2500; + Global.upgradePlayerMaxHealthMaxValue[1] = 5000; + Global.upgradePlayerMaxHealthMaxValue[2] = 10000; + Global.upgradeGateMaxHealthMaxValue[0] = Round To Integer(Global.gateMaxHealth + Global.gateMaxHealth * 0.500, Up); + Global.upgradeGateMaxHealthMaxValue[1] = Global.upgradeGateMaxHealthMaxValue[0] + Global.upgradeGateMaxHealthMaxValue[0]; + Global.upgradeGateMaxHealthMaxValue[2] = Global.upgradeGateMaxHealthMaxValue[1] + Global.upgradeGateMaxHealthMaxValue[1]; + Abort If(Global.isDebug == False); + Global.upgradeMaxAmmoMaxValue[0] = 1; + Global.upgradeCriticalDamageMaxValue[0] = 1; + Global.upgradePlayerMaxHealthMaxValue[0] = 1; + Global.upgradeGateMaxHealthMaxValue[0] = 1; + Global.upgradeMaxAmmoMaxValue[1] = 1; + Global.upgradeCriticalDamageMaxValue[1] = 1; + Global.upgradePlayerMaxHealthMaxValue[1] = 1; + Global.upgradeGateMaxHealthMaxValue[1] = 1; + Global.upgradeMaxAmmoMaxValue[2] = 1; + Global.upgradeCriticalDamageMaxValue[2] = 1; + Global.upgradePlayerMaxHealthMaxValue[2] = 1; + Global.upgradeGateMaxHealthMaxValue[2] = 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GATE'S MAX HEALTH UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.gatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.gatePosition, 100); + Global.gateMaxHealth = Global.upgradeGateMaxHealthMaxValue[0]; + Global.gateHealth = Global.gateMaxHealth; + Destroy HUD Text(Global.upgradeGateMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("GATE'S MAX HEALTH: {0} HP", Global.upgradeGateMaxHealthMaxValue[0]), Right, 1, Color( + Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeGateMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X GATE REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.upgradeGateMaxHealthValue, Global.upgradeGateMaxHealthMaxValue[1]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.upgradeGateMaxHealthHudId[1] = Last Text ID; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X GATE REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.gatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.gatePosition, 100); + Destroy HUD Text(Global.upgradeGateMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X GATE REPAIR"), Right, 2, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.upgradeGateMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X AUTO-REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.upgradeGateMaxHealthValue, Global.upgradeGateMaxHealthMaxValue[2]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.upgradeGateMaxHealthHudId[2] = Last Text ID; + Global.gateHealth = Global.gateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 3 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X AUTO-REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.gatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.gatePosition, 100); + Destroy HUD Text(Global.upgradeGateMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X AUTO-REPAIR"), Right, 3, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.upgradeGateMaxHealthHudId[2] = Last Text ID; + Global.gateHealth = Global.gateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - PLAYER'S MAX HEALTH - DEALT HEALING") +{ + event + { + Player Received Healing; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + disabled Healer != Event Player; + Global.upgradePlayerMaxHealthValue < Global.upgradePlayerMaxHealthMaxValue[2]; + } + + actions + { + Global.upgradePlayerMaxHealthValue += Event Healing; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH UNLOCKED!")); + Destroy HUD Text(Global.upgradePlayerMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +50%"), Right, 4, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradePlayerMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("Up You Go: You respawn twice as fast"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.upgradePlayerMaxHealthValue, Down), + Global.upgradePlayerMaxHealthMaxValue[1]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.upgradePlayerMaxHealthHudId[1] = Last Text ID; + For Global Variable(loopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 100); + End; + Global.maxHealthDone = 50; + All Players(Team 1).playerHealth = 100 + Global.maxHealthDone + All Players(Team 1).abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).playerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK UP YOU GO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("UP YOU GO UNLOCKED!")); + Destroy HUD Text(Global.upgradePlayerMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String("Up You Go"), + Right, 5, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradePlayerMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +100%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.upgradePlayerMaxHealthValue, Down), + Global.upgradePlayerMaxHealthMaxValue[2]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.upgradePlayerMaxHealthHudId[2] = Last Text ID; + Set Respawn Max Time(All Players(Team 1), 5); + Heal(All Players(Team 1), Null, 9999); + For Global Variable(loopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 100); + End; + Global.perk[2] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).abilityHUD[17] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH 2 UNLOCKED!")); + Destroy HUD Text(Global.upgradePlayerMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +100%"), Right, 6, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradePlayerMaxHealthHudId[2] = Last Text ID; + For Global Variable(loopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 100); + End; + Global.maxHealthDone = 150; + All Players(Team 1).playerHealth = 100 + Global.maxHealthDone + All Players(Team 1).abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).playerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Hero Of(Victim) == Hero(Widowmaker); + Global.upgradeCriticalDamageValue < Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.upgradeCriticalDamageValue += 1; + Small Message(All Players(Team 1), Custom String("CRITICAL DAMAGE CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - CRITICAL DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.upgradeCriticalDamageValue >= Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("CRITICAL DAMAGE 150% UNLOCKED!")); + Destroy HUD Text(Global.upgradeCriticalDamageHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "CRITICAL DAMAGE 150%"), Right, 7, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeCriticalDamageHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String( + "Sharpshooter: Deal 40% more damage to enemies that are further than 15 meters away"), Custom String("KILL ECHO {0}/{1}", + Global.upgradePerkSharpshooterValue, Global.upgradeCriticalDamageMaxValue[1]), Left, 14, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.upgradeCriticalDamageHudId[1] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - UNLOCKED") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Global.upgradeCriticalDamageValue >= Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.500); + } +} + +rule("PLAYER: UPGRADE - PERK SHARPSHOOTER - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Echo); + Global.upgradePerkSharpshooterValue < Global.upgradeCriticalDamageMaxValue[1]; + Global.upgradeCriticalDamageValue >= Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.upgradePerkSharpshooterValue += 1; + Small Message(All Players(Team 1), Custom String("SHARPSHOOTER CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - PERK SHARPSHOOTER - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.upgradePerkSharpshooterValue >= Global.upgradeCriticalDamageMaxValue[1]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("SHARPSHOOTER UNLOCKED!")); + Destroy HUD Text(Global.upgradeCriticalDamageHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Sharpshooter"), Right, 8, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeCriticalDamageHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("-10% BOSS HEALTH"), Custom String("KILL Bosses {0}/{1}", + Global.upgradeBossHealthValue, Global.upgradeCriticalDamageMaxValue[2]), Left, 14, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.upgradeCriticalDamageHudId[2] = Last Text ID; + Global.perk[0] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).abilityHUD[18] = Last Text ID; + Global.challengeCount += 1; + } +} + +disabled rule("PLAYER: UPGRADE - -10% BOSS HEALTH - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Global.upgradePerkSharpshooterValue >= Global.upgradeCriticalDamageMaxValue[1]; + Global.upgradeBossHealthValue < Global.upgradeCriticalDamageMaxValue[2]; + Victim.isBoss == 1; + } + + actions + { + Global.upgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - -10% BOSS HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("-10% BOSS HEALTH UNLOCKED!")); + Destroy HUD Text(Global.upgradeCriticalDamageHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "-10% BOSS HEALTH"), Right, 9, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeCriticalDamageHudId[2] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - MAX AMMO - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Zenyatta); + Global.upgradeMaxAmmoValue < Global.upgradeMaxAmmoMaxValue[2]; + } + + actions + { + If(Event Player.isBoss == 1); + Global.upgradeMaxAmmoValue += 10; + Else; + Global.upgradeMaxAmmoValue += 1; + End; + } +} + +rule("GLOBAL: UPGRADE - MAX AMMO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("MAX AMMO 200% UNLOCKED!")); + Destroy HUD Text(Global.upgradeMaxAmmoHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "MAX AMMO 200%"), Right, 10, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("Bulletstorm: Your weapon can hold unlimited ammo"), + Custom String("KILL {2}: {0}/{1}", Global.upgradeMaxAmmoValue, Global.upgradeMaxAmmoMaxValue[1], Hero(Zenyatta)), Left, 15, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.upgradeMaxAmmoHudId[1] = Last Text ID; + For Global Variable(loopIterator1, 0, Count Of(All Players(Team 1)), 1); + Set Max Ammo(All Players(Team 1)[Global.loopIterator1], 0, Max Ammo(All Players(Team 1)[Global.loopIterator1], 0) * 2); + Set Max Ammo(All Players(Team 1)[Global.loopIterator1], 1, Max Ammo(All Players(Team 1)[Global.loopIterator1], 1) * 2); + Set Ammo(All Players(Team 1)[Global.loopIterator1], 0, Max Ammo(All Players(Team 1)[Global.loopIterator1], 0)); + Set Ammo(All Players(Team 1)[Global.loopIterator1], 1, Max Ammo(All Players(Team 1)[Global.loopIterator1], 1)); + End; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK BULLETSTORM - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("BULLETSTORM UNLOCKED!")); + Destroy HUD Text(Global.upgradeMaxAmmoHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Bulletstorm"), Right, 11, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeMaxAmmoHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("+50% DAMAGE"), Custom String("KILL {2}: {0}/{1}", + Global.upgradeMaxAmmoValue, Global.upgradeMaxAmmoMaxValue[2], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.upgradeMaxAmmoHudId[2] = Last Text ID; + Global.perk[1] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).abilityHUD[19] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - +50% DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("+50% DAMAGE UNLOCKED!")); + Destroy HUD Text(Global.upgradeMaxAmmoHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "+50% DAMAGE"), Right, 12, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeMaxAmmoHudId[2] = Last Text ID; + Global.damageDealt = 50; + All Players(Team 1).damageDealt = 100 + Global.damageDealt + All Players(Team 1).abilities[13] * 5; + Set Damage Dealt(All Players(Team 1), All Players(Team 1).damageDealt); + Global.challengeCount += 1; + } +} + +disabled rule("=== GAME PHASES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: ASEMBLING PHASE - MAKE CHALLENGES HUDS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Assembling Heroes == True; + } + + actions + { + If(Global.isDebug); + Set Match Time(1); + Else; + Disable Inspector Recording; + Set Match Time(20); + End; + Create In-World Text(All Players(Team 1), Custom String(" {0}\r\nREPAIR\r\n {1}", Hero Icon String(Hero(Torbjörn)), + Ability Icon String(Hero(Bastion), Button(Secondary Fire))), Global.gatePosition + Vector(0, 1.400, 0), 1.200, Do Not Clip, + Visible To, Color(White), Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("TEAM CHALLENGES"), Left, 11, Color(White), Color(Blue), Color( + White), Visible To, Default Visibility); + "UPGRADE - GATE'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String( + "GATE'S MAX HEALTH: {0} HP", Global.upgradeGateMaxHealthMaxValue[0]), Custom String("REPAIR GATE {0}/{1} HP", + Global.upgradeGateMaxHealthValue, Global.upgradeGateMaxHealthMaxValue[0]), Left, 12, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.upgradeGateMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 2, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - PLAYER'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +50%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.upgradePlayerMaxHealthValue, Down), + Global.upgradePlayerMaxHealthMaxValue[0]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.upgradePlayerMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 4, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - CRITICAL DAMAGE" + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("CRITICAL DAMAGE 150%"), Custom String( + "KILL WIDOW WITH HEADSHOT: {0}/{1}", Global.upgradeCriticalDamageValue, Global.upgradeCriticalDamageMaxValue[0]), Left, 14, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.upgradeCriticalDamageHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 6, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - MAX AMMO" + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("MAX AMMO 200%"), Custom String("KILL {2}: {0}/{1}", + Global.upgradeMaxAmmoValue, Global.upgradeMaxAmmoMaxValue[0], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.upgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Custom String("HOLD {0} - Reload to open the shop", Input Binding String(Button(Reload))), + Null, Null, Top, 1000, Color(Yellow), Color(White), Color(White), Visible To and String, Default Visibility); + } +} + +rule("GLOBAL: SETUP PHASE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + If(Global.isDebug); + Set Match Time(1); + Else; + Pause Match Time; + Create HUD Text(All Players(Team 1), Custom String("PRESS {0} TO START", Button(Interact)), Null, Null, Top, 50, Color(Red), Color( + White), Color(White), Visible To and String, Default Visibility); + Global.globalHUDs[0] = Last Text ID; + Set Match Time(20); + Wait Until(Is True For Any(All Players(Team 1), Is Button Held(Current Array Element, Button(Interact))), 99999); + Destroy HUD Text(Global.globalHUDs[0]); + Unpause Match Time; + End; + Set Objective Description(All Players(All Teams), Custom String("DEFEND GATE"), Visible To and String); + } +} + +rule("GLOBAL: GAME IN PROGRESS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + } + + actions + { + Set Match Time(3599); + Pause Match Time; + Disable Built-In Game Mode Scoring; + Disable Built-In Game Mode Announcer; + Disable Built-In Game Mode Completion; + Disable Game Mode HUD(All Players(All Teams)); + Disable Game Mode In-World UI(All Players(All Teams)); + Global.gateHealth = Global.gateMaxHealth; + Global.gateHealthChase = Global.gateHealth; + Global.gateProgressBarColorComponent = 255; + Global.gateProgressBarColorCurrent = Color(White); + Create Progress Bar HUD Text(All Players(Team 1), Global.gateHealthChase * 100 / Global.gateMaxHealth, Custom String( + "GATE {0}/{1}", Global.gateHealth, Global.gateMaxHealth), Top, 1, Global.gateProgressBarColorCurrent, Color(White), + Visible To Values and Color, Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("SURVIVED TIME: {0}:{1}", Global.timeMinutes, + Global.timeSeconds < 10 ? Custom String("0{0}", Global.timeSeconds) : Global.timeSeconds), Top, 2, Color(White), Color(White), + Color(White), Visible To and String, Default Visibility); + Start Rule(GameLogicWave0, Do Nothing); + } +} + +disabled rule("=== GAME - MAIN LOGIC ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: DEFEAT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.isDebug == False; + Global.gateHealth <= 0; + } + + actions + { + Declare Team Victory(Team 2); + } +} + +rule("GLOBAL: TIMER - MAIN GAME LOOP") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + disabled Global.gateHealth > 0; + } + + actions + { + Wait(1, Ignore Condition); + Global.timeSeconds += 1; + If(Global.timeSeconds == 60); + Global.timeSeconds = 0; + Global.timeMinutes += 1; + Global.time5Minutes = Round To Integer(Global.timeMinutes / 5, Down); + Global.time10Minutes = Round To Integer(Global.timeMinutes / 10, Down); + Global.spawnPositionMaxId += 1; + disabled Start Rule(GameLogicAddNextHeroInGame, Restart Rule); + Else If(Global.timeSeconds == 30); + Global.spawnPositionMaxId += 1; + End; + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GAME LOGIC - ADD NEXT HERO IN GAME") +{ + event + { + Subroutine; + GameLogicAddNextHeroInGame; + } + + actions + { + "REDUCE RESPAWN TIME FOR ZENS" + disabled Global.zenRespawnTime -= 1.500; + disabled Global.zenRespawnTime = Max(1, Global.zenRespawnTime); + disabled Set Respawn Max Time(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Global.defaultHeroBotsPool[0]), + Global.zenRespawnTime); + "ALL HEROES WAS ADDED IN GAME" + Abort If(Global.defaultHeroBotsPoolCurrentId == Count Of(Global.defaultHeroBotsPool) - 1); + Global.defaultHeroBotsPoolCurrentId += 1; + "ВРЕМЕННЫЙ КОСТЫЛЬ ЧТОБЫ ЭХО ЗАМЕНИЛА ХАМСТЕРА" + If(Global.defaultHeroBotsPool[Global.defaultHeroBotsPoolCurrentId] == Hero(Echo)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Abort; + End; + "ABORT IF NEXT HERO IN ARRAY ORDER IS NULL" + Abort If(Global.defaultHeroBotsPool[Global.defaultHeroBotsPoolCurrentId] == Null); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Global.defaultHeroBotsPool[Global.defaultHeroBotsPoolCurrentId], Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("SUBROUTINE: GAME LOGIC - SET BOT PROPERTIES") +{ + event + { + Subroutine; + GameLogicSetBotProperties; + } + + actions + { + Abort If(Event Player.botIsOrisaChild == True); + If(Global.timeMinutes >= 10); + If(Filtered Array(Global.lastBoss, Current Array Element == Hero Of(Event Player)) == False); + If(Global.activeBoss == False); + If(Global.bossTrigger < Global.timeMinutes); + Global.bossTrigger = Global.timeMinutes; + Global.activeBoss = Event Player; + Event Player.isBoss = 1; + Big Message(All Players(Team 1), Custom String("BOSS SPAWNED - {0}", Hero Of(Event Player))); + End; + End; + End; + End; + "PROPERTIES BY DEFAULT" + Set Gravity(Event Player, 100); + Set Damage Dealt(Event Player, 100); + Set Respawn Max Time(Event Player, 10); + Start Scaling Player(Event Player, 1, False); + "INDIVIDUAL HERO'S PROPERTIES" + If(Hero Of(Event Player) == Hero(Zenyatta)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 30); + Set Max Health(Event Player, 10 * (100 + 10 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 1.500, False); + Else; + If(20 + 3 * Number Of Players(Team 1) + 3 * Global.timeMinutes > 75); + Set Move Speed(Event Player, 75); + Else; + Set Move Speed(Event Player, 20 + 3 * Count Of(All Players(Team 1)) + 3 * Global.timeMinutes); + End; + Set Max Health(Event Player, 100 + 10 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 20); + Set Max Health(Event Player, 5 * (70 + 20 * Count Of(All Players(Team 1)) + + 10 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + If(30 + Global.timeMinutes + 2.500 * Global.time5Minutes > 40); + Set Move Speed(Event Player, 40); + Else; + Set Move Speed(Event Player, 30 + Global.timeMinutes + 2.500 * Global.time5Minutes); + End; + Set Ultimate Charge(Event Player, 0); + Set Max Health(Event Player, 70 + 20 * Count Of(All Players(Team 1)) + + 10 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + If(Event Player.isBoss == 1); + Set Damage Dealt(Event Player, 2 * (85 + 15 * Count Of(All Players(Team 1)) + + 25 * Global.time5Minutes + 50 * Global.time10Minutes)); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 5 * (100 + 25 * Count Of(All Players(Team 1)) + + 5 * Global.timeMinutes + 15 * Global.time5Minutes + 40 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Event Player.botCounter = 0; + Set Damage Dealt(Event Player, 85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.time5Minutes + 50 * Global.time10Minutes); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 100 + 25 * Count Of(All Players(Team 1)) + + 5 * Global.timeMinutes + 15 * Global.time5Minutes + 40 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Bastion)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 50); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Minutes + 10 * Global.time10Minutes); + Start Scaling Player(Event Player, 3, False); + Set Max Health(Event Player, 5 * (155 + 150 * Count Of(All Players(Team 1)) + + 20 * Global.timeMinutes + 40 * Global.time5Minutes + 65 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Else; + Set Move Speed(Event Player, 80); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Minutes + 10 * Global.time10Minutes); + Start Scaling Player(Event Player, 2, False); + Set Max Health(Event Player, 155 + 150 * Count Of(All Players(Team 1)) + + 20 * Global.timeMinutes + 40 * Global.time5Minutes + 65 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Orisa)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 5 * (220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.time5Minutes + 100 * Global.time10Minutes) + * (Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Set Move Speed(Event Player, 30 + 5 * Global.time5Minutes); + Else; + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.time5Minutes + 100 * Global.time10Minutes); + Set Move Speed(Event Player, 90 + 5 * Global.time5Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Echo)); + If(Event Player.isBoss == 1); + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 70 + 5 * Global.time5Minutes); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 5 * (90 + 25 * Count Of(All Players(Team 1)) + + 15 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 130 + 5 * Global.time5Minutes); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 90 + 25 * Count Of(All Players(Team 1)) + + 15 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.500, False); + Set Move Speed(Event Player, 70); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Minutes + 10 * Global.time10Minutes); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 5 * (55 + 25 * Count Of(All Players(Team 1)) + + 15 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Else; + disabled Start Scaling Player(Event Player, 0.850, False); + Set Move Speed(Event Player, 110); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Minutes + 10 * Global.time10Minutes); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 55 + 25 * Count Of(All Players(Team 1)) + + 15 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes); + End; + End; + Wait(0.250, Ignore Condition); + "FILL HEALTH" + Heal(Event Player, Null, 100000); + } +} + +disabled rule("=== GATE ===") +{ + event + { + Ongoing - Global; + } +} + +rule("Subroutine: GATE REPAIR") +{ + event + { + Subroutine; + GateRepair; + } + + actions + { + Small Message(Event Player, Custom String("REPAIR +2% ULTIMATE")); + "UPGRADE - GATE'S MAX HEALTH" + If(Global.upgradeGateMaxHealthValue < Global.upgradeGateMaxHealthMaxValue[2]); + If(Event Player.isNanoed == 1); + If(Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1]); + Global.upgradeGateMaxHealthValue += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.upgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1]); + Global.upgradeGateMaxHealthValue += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.upgradeGateMaxHealthValue += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + End; + End; + "HEAL GATE" + If(Event Player.isNanoed == 1); + If(Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1]); + Global.gateHealth += 100 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 20; + Else; + Global.gateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + End; + Else; + If(Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1]); + Global.gateHealth += 50 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 10; + Else; + Global.gateHealth += 25 - (Number Of Players(Team 1) <= 3 ? Number Of Players(Team 1) : 3) * 5; + End; + If(Global.gateHealth > Global.gateMaxHealth); + Global.gateHealth = Global.gateMaxHealth; + "CHARGE ULTIMATE" + Else; + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + End; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + } +} + +rule("TORB: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Has Spawned(Event Player) == True; + Weapon(Event Player) == 2; + Is Firing Primary(Event Player) == True; + Global.gateHealth < Global.gateMaxHealth; + Is In View Angle(Event Player, Global.gateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.gatePosition) < 3.500; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(Is Using Ability 2(Event Player) == True ? 0.350 : 0.700, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Brig: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.gateHealth < Global.gateMaxHealth; + Is In View Angle(Event Player, Global.gateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.gatePosition) < 5; + Is Game In Progress == True; + } + + actions + { + Call Subroutine(GateRepair); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Rein: GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Firing Primary(Event Player) == True; + Global.gateHealth < Global.gateMaxHealth; + Is In View Angle(Event Player, Global.gateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.gatePosition) < 3; + Is Game In Progress == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Call Subroutine(GateRepair); + Wait(0.850, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GATE PROGRESS BAR COLOR") +{ + event + { + Subroutine; + GateProgressBarColor; + } + + actions + { + Stop Chasing Global Variable(gateHealthChase); + Chase Global Variable Over Time(gateHealthChase, Global.gateHealth, 0.100, Destination and Duration); + "GATE WAS DAMAGED" + If(Global.gateHealth < Global.gateHealthEvent); + For Global Variable(loopIterator1, 0, 3, 1); + Global.gateProgressBarColorCurrent = Color(Red); + Wait(0.030, Ignore Condition); + Global.gateProgressBarColorCurrent = Color(White); + Wait(0.030, Ignore Condition); + End; + "GATE WAS REPAIRED" + Else; + Global.gateProgressBarColorCurrent = Color(Green); + Wait(0.030, Ignore Condition); + Global.gateProgressBarColorCurrent = Color(Yellow); + Wait(0.030, Ignore Condition); + End; + Global.gateHealthEvent = Global.gateHealth; + Global.gateProgressBarColorComponent = Global.gateHealth * 255 / Global.gateMaxHealth; + Global.gateProgressBarColorCurrent = Custom Color(255, Global.gateProgressBarColorComponent, Global.gateProgressBarColorComponent, + 255); + } +} + +disabled rule("=== COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("ALL: INIT") +{ + event + { + Player Joined Match; + All; + All; + } + + actions + { + "ALL (COMMON) INIT" + Event Player.isDead = True; + Disable Kill Feed(Event Player); + Disable Game Mode In-World UI(Event Player); + Disable Death Spectate Target HUD(Event Player); + "BOT INIT" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotInit); + "PLAYER INIT" + Else; + Call Subroutine(PlayerInit); + End; + } +} + +rule("SUBROUTINE: BOT - INIT") +{ + event + { + Subroutine; + BotInit; + } + + actions + { + "INIT VARS" + Event Player.hasBadStatus = False; + Event Player.isRespawning = False; + Event Player.botDoesUniqueBehaviour = False; + Event Player.botEventPosition = Vector(9999, 999, 9999); + "DISABLE ALL FOR BOT" + Disable Hero HUD(Event Player); + Disable Messages(Event Player); + Disable Text Chat(Event Player); + Disable Scoreboard(Event Player); + Disable Game Mode HUD(Event Player); + Disable Death Spectate All Players(Event Player); + Disable Voice Chat(Event Player, True, True, True); + "INIT AI NAVIGATION VARS" + Call Subroutine(BotResetPathFinding); + } +} + +rule("SUBROUTINE: PLAYER - INIT") +{ + event + { + Subroutine; + PlayerInit; + } + + actions + { + "STORY HEROES" + If(Global.isStoryHeroes); + Reset Player Hero Availability(Event Player); + Set Player Allowed Heroes(Event Player, Array(Hero(Ana), Hero(Brigitte), Hero(Mercy), Hero(Lúcio), Hero(Moira), Hero(Baptiste), + Hero(Ashe), Hero(D.Va), Hero(Genji), Hero(Hanzo), Hero(Widowmaker), Hero(Cassidy), Hero(Reinhardt), Hero(Soldier: 76), Hero( + Torbjörn), Hero(Tracer), Hero(Winston), Hero(Pharah))); + End; + "TEAM CHALLENGE - PLAYER'S MAX HEALTH" + If(Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[0]); + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + End; + If(Is Game In Progress); + Disable Game Mode HUD(Event Player); + End; + } +} + +rule("ALL: RESPAWN") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + (Hero Of(Event Player) != Event Player.currentHero || Event Player.isDead == True) == True; + } + + actions + { + Event Player.isDead = False; + "BOT RESPAWN" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotRespawn); + If(Global.isDebugAINavigation); + Create Beam Effect(All Players(All Teams), Good Beam, Eye Position(Event Player), Event Player.botNextNodePosition, Color(Green), + Visible To Position and Radius); + End; + "PLAYER RESPAWN" + Else; + Call Subroutine(PlayerRespawn); + End; + "MUST BE AFTER ALL RESPAWN SUBROUTINES!" + Event Player.currentHero = Hero Of(Event Player); + } +} + +rule("SUBROUTINE: BOT - RESPAWN") +{ + event + { + Subroutine; + BotRespawn; + } + + actions + { + "RESET COMMON PROPERTIES" + Event Player.isRespawning = True; + Enable Nameplates(Event Player, All Players(Team 1)); + Call Subroutine(BotResetPathFinding); + disabled If(Hero Of(Event Player) != Event Player.currentHero); + Call Subroutine(GameLogicSetBotProperties); + disabled End; + "INDIVIDUAL HERO'S RESPAWN SCRIPTS" + If(Hero Of(Event Player) == Hero(Bastion)); + Call Subroutine(BotBastionRespawn); + Else If(Hero Of(Event Player) == Hero(Zenyatta)); + Call Subroutine(BotZenyattaRespawn); + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + Call Subroutine(BotWidowRespawn); + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Call Subroutine(BotBallRespawn); + Else If(Hero Of(Event Player) == Hero(Orisa)); + Call Subroutine(BotOrisaRespawn); + Else If(Hero Of(Event Player) == Hero(Echo)); + Call Subroutine(BotEchoRespawn); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Call Subroutine(BotReinRespawn); + End; + Event Player.isRespawning = False; + } +} + +rule("SUBROUTINE: PLAYER - RESPAWN") +{ + event + { + Subroutine; + PlayerRespawn; + } + + actions + { + "TEAM CHALLENGE - MAX AMMO" + If(Hero Of(Event Player) != Event Player.currentHero && Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[0]); + Set Max Ammo(Event Player, 0, Ammo(Event Player, 0) * 2); + Set Max Ammo(Event Player, 1, Ammo(Event Player, 1) * 2); + Set Ammo(Event Player, 0, Max Ammo(Event Player, 0)); + Set Ammo(Event Player, 1, Max Ammo(Event Player, 1)); + End; + "MUST BE AFTER TEAM CHALLENGE MAX AMMO!" + disabled Event Player.currentHero = Hero Of(Event Player); + "PLAYER RESPAWN" + Set Status(Event Player, Null, Phased Out, 3); + Set Facing(Event Player, Vector(-1, 0, 0), To World); + If(Ability Cooldown(Players On Hero(Hero(Mercy), Team 1), Button(Ability 2)) >= (1 - 0.250 * Players On Hero(Hero(Mercy), Team 1) + .abilities[6]) * Ability Cooldown(Players On Hero(Hero(Mercy), Team 1), Button(Ability 2)) - 1); + Wait(0.250, Ignore Condition); + Teleport(Event Player, Event Player.deathPosition); + Else; + Teleport(Event Player, Global.playerSpawnPositions[Slot Of(Event Player) == Count Of(Global.playerSpawnPositions) ? Random Integer( + 0, Count Of(Global.playerSpawnPositions) - 1) : Slot Of(Event Player)]); + End; + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + } +} + +rule("PLAYER: DEATH") +{ + event + { + Player Died; + Team 1; + All; + } + + actions + { + If(Hero Of(Event Player) == Hero(Roadhog)); + Event Player.abilities[8] -= 1; + Wait(Global.perk[2] ? 5 : 10, Ignore Condition); + Event Player.abilities[8] += 1; + End; + Event Player.deathPosition = Position Of(Event Player); + disabled If(Event Player.lastSecondWind > 0); + disabled Event Player.lastSecondWind = 0; + disabled End; + Event Player.isDead = True; + } +} + +rule("BOT: DEATH") +{ + event + { + Player Died; + Team 2; + All; + } + + actions + { + If(Event Player.isBoss == 1); + If(Global.upgradePerkSharpshooterValue >= Global.upgradeCriticalDamageMaxValue[1]); + If(Global.upgradeBossHealthValue < Global.upgradeCriticalDamageMaxValue[2]); + Global.upgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + End; + End; + Event Player.isBoss = 0; + Global.activeBoss = Null; + Big Message(All Players(Team 1), Custom String("BOSS DIED - {0}", Hero Of(Event Player))); + End; + Event Player.isDead = True; + Event Player.hasBadStatus = False; + Event Player.botDoesUniqueBehaviour = False; + Disable Nameplates(Event Player, All Players(Team 1)); + disabled Stop Holding Button(Event Player, Button(Ability 1)); + disabled Stop Holding Button(Event Player, Button(Primary Fire)); + disabled Stop Holding Button(Event Player, Button(Secondary Fire)); + "BOT HAS 1 EFFECT IN VAR (NOT ARRAY)" + Skip If(!Entity Exists(Event Player.botEffects), 1); + Destroy Effect(Event Player.botEffects); + "BOT HAS MORE THEN 1 EFFECT IN VAR (ARRAY)" + Skip If(Count Of(Event Player.botEffects) == 0, 3); + For Player Variable(Event Player, botLoopIterator1, 0, Count Of(Event Player.botEffects), 1); + Destroy Effect(Event Player.botEffects[Event Player.botLoopIterator1]); + End; + } +} + +disabled rule("=== BOT COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BAD STATUS") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.hasBadStatus == False; + (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + Event Player.hasBadStatus = True; + "PROCESS BAD STATUS" + If(Hero Of(Event Player) == Hero(Widowmaker)); + Start Rule(BotWidowBadStatus, Do Nothing); + End; + Wait Until(!Has Status(Event Player, Knocked Down) && !Has Status(Event Player, Asleep) && !Has Status(Event Player, Frozen) + && !Has Status(Event Player, Stunned), 15); + Event Player.hasBadStatus = False; + } +} + +rule("SUBROUTINE: BOT - LANDING FROM SKY") +{ + event + { + Subroutine; + BotLandingFromSky; + } + + actions + { + Stop Throttle In Direction(Event Player); + "SET RESPAWN POSITION" + Event Player.botEventPosition = Random Value In Array(Global.bigBossSpawnPositions); + "CREATE EFFECTS" + disabled Create Effect(All Players(All Teams), Light Shaft, Color(Red), Event Player.botEventPosition, 3, Visible To); + disabled Event Player.botEffects = Last Created Entity; + "RESPAWN IN LIGHT SHAFT EFFECT" + Teleport(Event Player, Event Player.botEventPosition + Vector(0, 25, 0)); + Wait(0.020, Ignore Condition); + "SLOW LANDING" + Set Gravity(Event Player, 50); + While(Is In Air(Event Player) == True); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Position Of(Event Player) + Vector(0, -2.700, 0), 2); + Wait(0.250, Ignore Condition); + End; + Set Gravity(Event Player, 100); + disabled Destroy Effect(Event Player.botEffects); + "LANDING EFFECTS" + Play Effect(All Players(All Teams), Wrecking Ball Piledriver Impact Effect, Custom Color(105, 87, 46, 255), Position Of( + Event Player), 8); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Sound, Color(White), Position Of(Event Player), 150); + } +} + +rule("SUBROUTINE: BOT - APPEAR FROM UNDERGROUND") +{ + event + { + Subroutine; + BotAppearFromUnderground; + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1); + Wait(0.200, Ignore Condition); + Set Gravity(Event Player, 20); + Disable Movement Collision With Environment(Event Player, True); + Teleport(Event Player, Global.zenSpawnPositions[Random Integer(Min(Global.timeMinutes, Count Of(Global.zenSpawnPositions) - 10), + Min(Global.spawnPositionMaxId, Count Of(Global.zenSpawnPositions) - 4))] + Vector(0, -1.500, 0)); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Sigma Accretion Impact Effect, Custom Color(220, 175, 100, 255), Eye Position(Event Player), + 3); + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(Gray), Eye Position(Event Player), 50); + Apply Impulse(Event Player, Up, 3.500, To World, Cancel Contrary Motion); + Wait(0.400, Ignore Condition); + Clear Status(Event Player, Knocked Down); + Set Gravity(Event Player, 100); + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("=== PLAYER MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("PLAYER: DARKNESS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + !Entity Exists(Event Player.botEffects) == True; + } + + actions + { + Disable Nameplates(Event Player, All Players(All Teams)); + Start Forcing Player Outlines(Event Player, All Players(All Teams), False, Color(White), Default); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 14), 25, Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(-5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + } +} + +rule("PLAYER: HEALTH REGEN") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + actions + { + Stop Heal Over Time(Event Player.healOverTimeId); + Event Player.eventHealth = Health(Event Player); + Wait(4, Ignore Condition); + "TOOK DAMAGE, RESET REGENERATION TIMER" + Loop If(Is Alive(Event Player) && Event Player.eventHealth > Health(Event Player)); + Start Heal Over Time(Event Player, Null, 3, Max Health(Event Player) / 3); + Event Player.healOverTimeId = Last Heal Over Time ID; + } +} + +disabled rule("=== NERFS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("REINHARDT: ANTI-CHARGE FOR BASTION & ORISA") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Using Ability 1(Event Player) == True; + Hero Of(Ray Cast Hit Player(Eye Position(Event Player) + Vector(0, 2, 0), Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 2, All Living Players(Team 2), Event Player, True)) == (Hero(Bastion) == True || Hero( + Orisa) == True); + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1.500); + } +} + +rule("HOG: ANTI-HOOK FOR BASTION & ORISA") +{ + event + { + Player Dealt Damage; + Team 1; + Roadhog; + } + + conditions + { + Event Ability == Button(Ability 1); + (Hero Of(Victim) == Hero(Bastion) || Hero Of(Victim) == Hero(Orisa)) == True; + } + + actions + { + Set Status(Event Player, Null, Stunned, 0.005); + } +} + +disabled rule("=== ZENYATTA ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ZEN - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Zenyatta; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + } + + actions + { + Set Ammo(Event Player, 0, 0); + Communicate(Event Player, Hello); + disabled Call Subroutine(BotResetPathFinding); + Wait(1.500, Ignore Condition); + Abort If(Is Dead(Event Player) == True); + Kill(Event Player, Null); + } +} + +rule("BOT: ZEN - DEATH") +{ + event + { + Player Died; + Team 2; + Zenyatta; + } + + actions + { + "EFFECT" + Play Effect(All Players(All Teams), Junkrat Frag Launcher Explosion Effect, Color(Red), Eye Position(Event Player), 2.500); + Play Effect(All Players(All Teams), Ashe Dynamite Explosion Sound, Color(Red), Eye Position(Event Player), 70); + "DAMAGE AND APPLY IMPULSE TO PLAYERS" + Event Player.botPlayersInRadius = Players Within Radius(Position Of(Event Player), 2.500, All Teams, Surfaces And Enemy Barriers); + For Player Variable(Event Player, botLoopIterator1, 0, Count Of(Event Player.botPlayersInRadius), 1); + Apply Impulse(Event Player.botPlayersInRadius[Event Player.botLoopIterator1], Direction Towards(Position Of(Event Player), + Eye Position(Event Player.botPlayersInRadius[Event Player.botLoopIterator1])), 5, To World, Incorporate Contrary Motion); + If(Team Of(Event Player.botPlayersInRadius[Event Player.botLoopIterator1]) == Team 1); + Damage(Event Player.botPlayersInRadius[Event Player.botLoopIterator1], Event Player, 50); + End; + End; + "DAMAGE GATE" + If(Distance Between(Position Of(Event Player), Global.gatePosition) < 3 && Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.gateHealth -= 125; + Else; + Global.gateHealth -= 25; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Respawn(Event Player); + Abort; + End; + "KILLED BY PLAYER" + Teleport(Event Player, Vector(0, -999, 0)); + Wait(2, Ignore Condition); + Respawn(Event Player); + Wait(2, Ignore Condition); + } +} + +rule("SUBROUTINE: ZEN - RESPAWN") +{ + event + { + Subroutine; + BotZenyattaRespawn; + } + + actions + { + Call Subroutine(BotAppearFromUnderground); + Event Player.botTargetPosition = Global.gatePosition; + Event Player.botIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WRECKING BALL ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BALL - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + disabled Distance Between(Position Of(Event Player), Global.gatePosition) < 3; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Set Ammo(Event Player, 0, 0); + Wait(1, Ignore Condition); + Set Ultimate Charge(Event Player, 100); + Start Holding Button(Event Player, Button(Ultimate)); + Wait Until(Is Using Ultimate(Event Player), 0.600); + Abort If(Is Dead(Event Player)); + Kill(Event Player, Null); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Effect, Color(Orange), Eye Position(Event Player), 6); + Play Effect(All Players(All Teams), DVa Self Destruct Explosion Sound, Color(White), Eye Position(Event Player), 250); + If(Distance Between(Position Of(Event Player), Global.gatePosition) < 3.500 && Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.gateHealth -= 300; + Else; + Global.gateHealth -= 150; + End; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Damage(Players Within Radius(Eye Position(Event Player), 7, Team 1, Surfaces And All Barriers), Event Player, 200); + } +} + +rule("BOT: BALL - ALTERNATIVE FORM") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is In Alternate Form(Event Player) == False; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is In Alternate Form(Event Player), 10); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: BALL - DEATH") +{ + event + { + Player Died; + Team 2; + Wrecking Ball; + } + + actions + { + Stop Holding Button(Event Player, Button(Ability 1)); + Stop Holding Button(Event Player, Button(Ultimate)); + } +} + +rule("SUBROUTINE: BALL - RESPAWN") +{ + event + { + Subroutine; + BotBallRespawn; + } + + actions + { + "RESPAWN IN AIR" + Teleport(Event Player, Random Value In Array(Global.ballSpawnPositions) + Vector(0, 20, 0)); + Stop Holding Button(Event Player, Button(Ultimate)); + Wait(0.250, Ignore Condition); + "LANDING" + Start Holding Button(Event Player, Button(Crouch)); + Wait Until(Is On Ground(Event Player), 9999); + Stop Holding Button(Event Player, Button(Crouch)); + "LANDING IMPACT EFFECT" + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(White), Event Player, 150); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Effect, Color(Gray), Position Of(Event Player), 10); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Eye Position(Event Player), 1.500, Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + "PATH FINDING TO GATE" + Event Player.botTargetPosition = Global.gatePosition; + Event Player.botIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +disabled rule("=== ECHO ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ECHO - FLY ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Is Using Ability 1(Event Player) == False; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), 0); + Press Button(Event Player, Button(Ability 1)); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - BEAM ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Is Using Ability 1(Event Player) == False; + Event Player.botDoesUniqueBehaviour == True; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - BAD STATUS - RESET BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.hasBadStatus == True; + disabled (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + If(Event Player.botDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + Wait Until(Event Player.hasBadStatus, 7); + } +} + +rule("BOT: ECHO - CAN'T SEE PORTAL - APPLY IMPULSE") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == True; + Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Wait(0.300, Abort When False); + Apply Impulse(Event Player, Vector(Random Integer(-1, 1), 1, Random Integer(-1, 1)), 20, To World, Incorporate Contrary Motion); + Wait(1, Ignore Condition); + If(!Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS)); + Event Player.botTargetPosition = Global.botEchoRespawnPosition; + Start Rule(BotStartPathFinding, Restart Rule); + Else; + Call Subroutine(BotResetPathFinding); + End; + Loop If Condition Is True; + } +} + +disabled rule("BOT: ECHO - MAIN LOGIC - BACKUP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + } + + actions + { + If(!Event Player.botIsPathFinding); + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Is In Line of Sight(Eye Position(Event Player), + Eye Position(Current Array Element), Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), + Position Of(Current Array Element)))[0]; + End; + "NO PLAYERS IN VIEW RANGE" + disabled If(Event Player.botSeePlayer == Null); + disabled Stop Throttle In Direction(Event Player); + disabled End; + "FLY TO PLAYER" + If(Event Player.botSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) + > 4 && Event Player.botDoesUniqueBehaviour == False); + Event Player.botTargetPlayer = Event Player.botSeePlayer; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + "ACTIVATE FOCUS BEAM" + Else If(Event Player.botSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) + < 4 && Event Player.botDoesUniqueBehaviour == False && Event Player.hasBadStatus == False); + Event Player.botDoesUniqueBehaviour = True; + Set Status(Event Player.botSeePlayer, Event Player, Stunned, 1); + Set Status(Event Player.botSeePlayer, Event Player, Hacked, 99999); + Attach Players(Event Player.botSeePlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + "TELEPORT PLAYER TO AWAY" + Else If(Event Player.botDoesUniqueBehaviour && Distance Between(Position Of(Event Player.botSeePlayer), + Global.botEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.botEchoRespawnPosition, 1); + Teleport(Event Player.botSeePlayer, Random Value In Array(Global.botEchoTeleportPositions)); + Set Status(Event Player.botSeePlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + "BEGIN TO FLY TO THE PORTAL" + Else If(Event Player.botDoesUniqueBehaviour == True); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.botIsPathFinding); + Event Player.botTargetPlayer = Event Player.botSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + } + + actions + { + If(Event Player.botDoesUniqueBehaviour == False); + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + End; + "TELEPORT PLAYER SO FAR" + If(Event Player.botDoesUniqueBehaviour && Distance Between(Position Of(Event Player.botEchoCapturedPlayer), + Global.botEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.botEchoRespawnPosition, 1); + Teleport(Event Player.botEchoCapturedPlayer, Random Value In Array(Global.botEchoTeleportPositions)); + Set Status(Event Player.botEchoCapturedPlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + End; + "BEGIN TO FLY TO THE PORTAL WITH A PLAYER" + If(Event Player.botDoesUniqueBehaviour); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.botIsPathFinding); + Event Player.botTargetPlayer = Event Player.botEchoCapturedPlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - DEFEND PORTAL") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer == Null; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer), Barriers Do Not Block LOS) == True; + } + + actions + { + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPlayer); + } +} + +rule("BOT: ECHO - PATH FINDING TO PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Event Player.botDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer), Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.botTargetPlayer = Event Player.botSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Call Subroutine(BotStartPathFinding); + } +} + +rule("BOT: ECHO - ATTACH PLAYER BY BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.hasBadStatus == False; + Event Player.botSeePlayer != Null; + Event Player.isRespawning == False; + Event Player.botEchoCapturedPlayer == Null; + Event Player.botDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer), Barriers Do Not Block LOS) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) < 3; + } + + actions + { + Event Player.botDoesUniqueBehaviour = True; + Event Player.botEchoCapturedPlayer = Event Player.botSeePlayer; + Set Status(Event Player.botEchoCapturedPlayer, Event Player, Stunned, 0.700); + Set Status(Event Player.botEchoCapturedPlayer, Event Player, Hacked, 10); + Attach Players(Event Player.botEchoCapturedPlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - PLAYER DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Is Dead(Event Player.botEchoCapturedPlayer) != Null; + } + + actions + { + If(Event Player.botDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - DEATH") +{ + event + { + Player Died; + Team 2; + Echo; + } + + actions + { + Call Subroutine(BotEchoDetachPlayer); + Stop Holding Button(Event Player, Button(Jump)); + Wait(5, Ignore Condition); + Teleport(Event Player, Vector(0, 999, 0)); + Start Forcing Player To Be Hero(Event Player, Hero(Orisa)); + } +} + +rule("SUBROUTINE: ECHO - RESPAWN") +{ + event + { + Subroutine; + BotEchoRespawn; + } + + actions + { + Event Player.botCounter = 0; + Event Player.botEffects = Empty Array; + Create Effect(All Players(All Teams), Good Aura, Color(Sky Blue), Global.botEchoRespawnPosition, Event Player.botCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, botEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Global.botEchoRespawnPosition, Event Player.botCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, botEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Energy Sound, Color(White), Global.botEchoRespawnPosition, 200, Visible To); + Modify Player Variable(Event Player, botEffects, Append To Array, Last Created Entity); + Chase Player Variable Over Time(Event Player, botCounter, 3, 0.800, Destination and Duration); + Play Effect(All Players(All Teams), Sombra EMP Explosion Effect, Color(Sky Blue), Global.botEchoRespawnPosition, 12); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Null, Global.botEchoRespawnPosition, 100); + Wait(3, Ignore Condition); + Teleport(Event Player, Global.botEchoRespawnPosition); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Global.botEchoRespawnPosition, 2.500); + Play Effect(All Players(All Teams), Debuff Impact Sound, Null, Global.botEchoRespawnPosition, 100); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PLAYER") +{ + event + { + Subroutine; + BotEchoFlyToPlayer; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Stop Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PORTAL") +{ + event + { + Subroutine; + BotEchoFlyToPortal; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - DETACH PLAYER") +{ + event + { + Subroutine; + BotEchoDetachPlayer; + } + + actions + { + Detach Players(Event Player.botEchoCapturedPlayer); + Clear Status(Event Player.botEchoCapturedPlayer, Hacked); + "IF PLAYER INSIDE THE WALL" + If(Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botEchoCapturedPlayer), Barriers Do Not Block LOS)); + Teleport(Event Player.botEchoCapturedPlayer, Position Of(Event Player)); + End; + Event Player.botDoesUniqueBehaviour = False; + Event Player.botEchoCapturedPlayer = Null; + } +} + +disabled rule("=== REINHARDT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: REIN - SET PLAYER AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + disabled Event Player.botIsPathFinding == False; + "BOT IS FAR FROM GATES" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Global.gatePosition), 0, Z Component Of(Global.gatePosition))) > 20; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET CLOSEST PLAYER TO BOT AS TARGET AND FOLLOW HIM" + Event Player.botTargetPlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Position Of(Event Player.botTargetPlayer)), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - SET GATE AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + "BOT DOESN'T FOLLOW PLAYER" + Event Player.botTargetPlayer == -1; + "CAN'T SEE ANY PLAYER" + disabled Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), !Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET GATE AS TARGET" + Event Player.botTargetPosition = Global.gatePosition; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - TARGET DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botTargetPlayer != -1; + Is Dead(Event Player.botTargetPlayer) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + } +} + +rule("BOT: REIN - ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) + : Global.gatePosition) < 4; + "CAN ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) : Global.gatePosition), 0, + Z Component Of(Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) : Global.gatePosition))) < 4; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + "TARGET IS PLAYER" + Abort If(Event Player.botTargetPlayer != -1); + If(Event Player.isBoss == 1); + "TARGET IS GATE" + Global.gateHealth -= 25; + Else; + Global.gateHealth -= 5; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: REIN - STOP ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) + : Global.gatePosition) > 4; + "CAN'T ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) : Global.gatePosition), 0, + Z Component Of(Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) : Global.gatePosition))) > 4; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + } +} + +rule("BOT: REIN - USE SHIELD") +{ + event + { + Player Took Damage; + Team 2; + Reinhardt; + } + + conditions + { + Distance Between(Position Of(Event Player), Position Of(Event Player.botTargetPlayer)) > 3; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Attacker)), 200, To World, + Direction and Turn Rate); + Start Holding Button(Event Player, Button(Secondary Fire)); + Wait Until(Distance Between(Position Of(Event Player), Position Of(Event Player.botTargetPlayer)) < 3, 3); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("BOT: REIN - CHARGE IN GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botTargetPlayer == -1; + Is Using Ability 1(Event Player) == False; + Is In Line of Sight(Eye Position(Event Player), Global.gatePosition, Barriers Do Not Block LOS) == True; + Is In View Angle(Event Player, Global.gatePosition, 7.500) == True; + } + + actions + { + disabled Wait(0.800, Abort When False); + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is Using Ability 1(Event Player), 1); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: REIN - DEATH") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("SUBROUTINE: REIN - RESPAWN") +{ + event + { + Subroutine; + BotReinRespawn; + } + + actions + { + Call Subroutine(BotAppearFromUnderground); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WIDOW ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: WIDOW - SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.botSeePlayer == Null; + Event Player.hasBadStatus == False; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Event Player.botWidowShotTime = Total Time Elapsed + (Global.timeMinutes >= 9 ? Random Real(2, 5) : Random Real(5, 10)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), 9999, To World, + Direction and Turn Rate); + } +} + +rule("BOT: WIDOW - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.botSeePlayer != Null; + Event Player.hasBadStatus == False; + Total Time Elapsed >= Event Player.botWidowShotTime; + } + + actions + { + Press Button(Event Player, Button(Primary Fire)); + Stop Facing(Event Player); + Event Player.botSeePlayer = Null; + } +} + +rule("BOT: WIDOW - Aim Sound") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Alive(Event Player) == True; + Is In Line of Sight(Eye Position(Players On Hero(Hero(Widowmaker), Team 2)), Eye Position(Event Player), Barriers Do Not Block LOS) + == True; + Is Alive(Players On Hero(Hero(Widowmaker), Team 2)) == True; + Players On Hero(Hero(Widowmaker), Team 2).botSeePlayer == True; + } + + actions + { + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 100); + Wait(1, Abort When False); + Loop If Condition Is True; + } +} + +rule("BOT: WIDOW - TELEPORT TO NEW POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.hasBadStatus == False; + Total Time Elapsed >= Event Player.botWidowTeleportTime; + } + + actions + { + Event Player.botWidowTeleportTime = Total Time Elapsed + 28; + Event Player.botWidowShotTime = Total Time Elapsed + (Global.timeMinutes >= 9 ? Random Real(1, 3) : Random Real(3, 6)); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Event Player, 1); + Wait(0.016, Ignore Condition); + Teleport(Event Player, Filtered Array(Global.sniperPositions, Distance Between(Event Player.botEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.sniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.botEventPosition = Position Of(Event Player); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + } +} + +rule("BOT: WIDOW - DEATH") +{ + event + { + Player Died; + Team 2; + Widowmaker; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + Wait(0.250, Ignore Condition); + Destroy Effect(Event Player.botEffects); + } +} + +rule("SUBROUTINE: WIDOW - RESPAWN") +{ + event + { + Subroutine; + BotWidowRespawn; + } + + actions + { + "RESPAWN ON RANDOM SNIPER POSITION" + Teleport(Event Player, Filtered Array(Global.sniperPositions, Distance Between(Event Player.botEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.sniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.botEventPosition = Position Of(Event Player); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Wait(0.700, Ignore Condition); + Start Holding Button(Event Player, Button(Secondary Fire)); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + Wait Until(Is Dead(Event Player), 99999); + Destroy Effect(Event Player.botEffects); + } +} + +rule("SUBROUTINE: WIDOW - BAD STATUS") +{ + event + { + Subroutine; + BotWidowBadStatus; + } + + actions + { + Stop Facing(Event Player); + Destroy Effect(Event Player.botEffects); + Wait Until(!Event Player.hasBadStatus, 15); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + } +} + +disabled rule("=== BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("BOT: BASTION - FLAME GUN") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.botDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.botSeePlayer), 50) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) < 8; + } + + actions + { + Event Player.botDoesUniqueBehaviour = True; + Stop Holding Button(Event Player, Button(Primary Fire)); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Update Every Frame(Eye Position(Event Player) + World Vector Of( + Vector(-1, -1.200, 1.800), Event Player, Rotation)), 1, Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + Start Rule(BotBastionFlameGunDamage, Do Nothing); + Wait(1.100, Ignore Condition); + Destroy Effect(Event Player.botEffects); + Wait(4, Ignore Condition); + Loop If Condition Is True; + } +} + +disabled rule("BOT: BASTION - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + disabled Event Player.botSeePlayer == Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - CAN'T SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == False; + } + + actions + { + Event Player.botSeePlayer = Null; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - MOVE TO BASTION'S TARGET (POSITION)") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Event Player.botTargetPosition = Random Value In Array(Filtered Array(Global.bastionTargetPositions, Distance Between(Position Of( + Event Player), Current Array Element) > 3.500)); + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("BOT: BASTION - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + "SEE THE PLAYER" + If(Event Player.botSeePlayer != Null); + Stop Holding Button(Event Player, Button(Secondary Fire)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer) - Vector(0, 0.500, + 0)), 100, To World, Direction and Turn Rate); + "SELF REPAIRING" + Else If(!Is Firing Secondary(Event Player) && Health(Event Player) < Max Health(Event Player)); + Start Holding Button(Event Player, Button(Secondary Fire)); + End; + "START FOLLOW PATH" + disabled If(!Event Player.botIsPathFinding && !Event Player.botDoesUniqueBehaviour); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled Wait(0.050, Ignore Condition); + disabled Event Player.botTargetPosition = Random Value In Array(Global.bastionTargetPositions); + disabled Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Event Player.botTargetPosition + Vector(0, 2, 0)), 100, + To World, Direction and Turn Rate); + disabled Start Rule(BotStartPathFinding, Do Nothing); + "REACHED PATH TARGET" + disabled Else If(Distance Between(Position Of(Event Player), Event Player.botTargetPosition) <= 3); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled End; + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - ARTILLERY") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.botDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.botSeePlayer), 30) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) > 18; + Distance Between(Eye Position(Event Player), Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Up * 99, Null, Event Player, False)) >= 35; + } + + actions + { + "TRYING TO CAPTURE TARGET" + Wait(0.800, Abort When False); + "CAPTURE TARGET" + Event Player.botDoesUniqueBehaviour = True; + Stop Throttle In Direction(Event Player); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Update Every Frame(Eye Position(Event Player)), + Update Every Frame(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 1000, All Living Players(Team 1), Event Player, True)), Color(Sky Blue), Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + Wait(1.400, Ignore Condition); + Destroy Effect(Event Player.botEffects); + Abort If(Is Dead(Event Player)); + Event Player.botEventPosition = Position Of(Event Player.botSeePlayer); + "SHOOT FROM ARTILLERY" + Event Player.botBastionArtilleryDidShotsCount = 0; + For Player Variable(Event Player, botLoopIterator1, 0, 4, 1); + Event Player.botBastionArtilleryDidShotsCount += 1; + Play Effect(All Players(All Teams), Wrecking Ball Minefield Explosion Sound, Color(White), Eye Position(Event Player), 250); + Play Effect(All Players(All Teams), Pharah Barrage Explosion Effect, Color(Orange), Eye Position(Event Player) + World Vector Of( + Vector(0, 1.400, -0.700), Event Player, Rotation), 2); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) + World Vector Of(Vector(0, 1.400, + -0.700), Event Player, Rotation), Eye Position(Event Player) + World Vector Of(Vector(Random Real(-1, 1), Random Integer(40, + 80), Random Real(0.500, 1.500)), Event Player, Rotation), Color(Orange), Visible To); + Event Player.botEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.botEffects); + Wait(0.400, Ignore Condition); + If(Is Dead(Event Player)); + Break; + End; + End; + disabled Call Subroutine(BotResetPathFinding); + disabled Start Rule(BotStartPathFinding, Do Nothing); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Wait(1.500, Ignore Condition); + Start Rule(BotBastionArtilleryDamage, Do Nothing); + Wait(4, Ignore Condition); + } +} + +rule("BOT: BASTION - PRIMARY FIRE") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Event Player.botDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.botSeePlayer), 40) == True; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Stop Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Bastion; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + For Player Variable(Event Player, botLoopIterator1, 0, 3, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Effect, Color(White), Event Player, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player, 100); + Wait(0.250, Ignore Condition); + End; + } +} + +rule("SUBROUTINE: BASTION - RESPAWN") +{ + event + { + Subroutine; + BotBastionRespawn; + } + + actions + { + Abort If(Event Player.botIsOrisaChild == True); + Call Subroutine(BotLandingFromSky); + Set Ammo(Event Player, 0, 0); + Wait Until(!Is Reloading(Event Player), 99999); + Event Player.botTargetPosition = Objective Position(2); + } +} + +rule("SUBROUTINE: BASTION - ARTILLERY DAMAGE") +{ + event + { + Subroutine; + BotBastionArtilleryDamage; + } + + actions + { + Event Player.botDoesUniqueBehaviour = False; + "EXPLOSIONS OF ARTILLERY" + For Player Variable(Event Player, botLoopIterator2, 0, Event Player.botBastionArtilleryDidShotsCount, 1); + Event Player.botEventPosition = Ray Cast Hit Position(Event Player.botEventPosition + Vector(0, 50, 0), + Event Player.botEventPosition + Vector(Random Integer(-4, 4), -15, Random Integer(-4, 4)), Null, Event Player, True); + Damage(Players Within Radius(Event Player.botEventPosition, 8, Team 1, Surfaces And Enemy Barriers), Event Player, 50); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player.botEventPosition, 150); + Play Effect(All Players(All Teams), Pharah Rocket Launcher Explosion Effect, Color(Orange), Event Player.botEventPosition, 5); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Event Player.botEventPosition, + Event Player.botEventPosition + Vector(0, 60, 0), Color(Orange), Visible To); + Event Player.botEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.botEffects); + Wait(0.400, Ignore Condition); + End; + } +} + +disabled rule("SUBROUTINE: BASTION - FLAME GUN DAMAGE") +{ + event + { + Subroutine; + BotBastionFlameGunDamage; + } + + actions + { + Event Player.botRayCastHitPosition = Eye Position(Event Player) + World Vector Of(Vector(-1, -1.200, 1.800), Event Player, + Rotation); + "FIRE PARTICLES OF FLAME GUN" + For Player Variable(Event Player, botLoopIterator1, 1, 13, 3); + Event Player.botEventPosition = Ray Cast Hit Position(Event Player.botRayCastHitPosition, + Event Player.botRayCastHitPosition + Facing Direction Of(Event Player) * Event Player.botLoopIterator1, Null, Event Player, + True); + Damage(Players Within Radius(Event Player.botEventPosition, 4, Team 1, Surfaces And Enemy Barriers), Event Player, 20); + Set Status(Players Within Radius(Event Player.botEventPosition, 4, Team 1, Off), Event Player, Burning, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player.botEventPosition, 150); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.botEventPosition, 2.500); + Wait(0.200, Ignore Condition); + End; + Event Player.botDoesUniqueBehaviour = False; + } +} + +disabled rule("=== ORISA + BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ORISA-BASTION - REACHED TARGET POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botIsPathFinding == True; + Distance Between(Position Of(Event Player), Global.botOrisaTargetPosition) < 1.500; + } + + actions + { + Call Subroutine(BotResetPathFinding); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Vector(X Component Of(Global.gatePosition), -999, + Z Component Of(Global.gatePosition))), 80, To World, Direction and Turn Rate); + Start Facing(Global.botOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Barriers Do Not Block LOS) ? Global.gatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + disabled Start Facing(Global.botOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Barriers Do Not Block LOS) ? Global.gatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element) && Is In Line of Sight(Eye Position(Event Player), Position Of(Current Array Element), + Barriers Do Not Block LOS)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + Press Button(Event Player, Button(Ability 1)); + Wait Until(Y Component Of(Facing Direction Of(Event Player)) < -0.300, 99999); + Press Button(Event Player, Button(Ability 2)); + Wait(0.800, Ignore Condition); + Global.botOrisaChild.botDoesUniqueBehaviour = False; + Disallow Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ORISA-BASTION - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Event Player.botDoesUniqueBehaviour = True; + While(Is Alive(Event Player)); + disabled Create Effect(All Players(All Teams), Bad Aura, Color(Purple), Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3.200, 1, Visible To Position and Radius); + disabled Event Player.botEffects = Last Created Entity; + Wait(1.500, Ignore Condition); + disabled Destroy Effect(Event Player.botEffects); + Abort If(Is Dead(Event Player)); + Press Button(Event Player, Button(Primary Fire)); + Press Button(Event Player, Button(Reload)); + Event Player.botRayCastHitPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Facing Direction Of(Event Player) * 999, All Players(Team 1), All Players(Team 2), True); + "ANTI-SHIELD BUG" + Event Player.botRayCastHitPosition = Event Player.botRayCastHitPosition + Direction Towards(Event Player.botRayCastHitPosition, + Eye Position(Event Player)) * 0.200; + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3, Event Player.botRayCastHitPosition, Color(Purple), Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + Damage(Players Within Radius(Event Player.botRayCastHitPosition, 4, Team 1, Surfaces And All Barriers), Event Player, 0.040); + Play Effect(All Players(All Teams), Pharah Concussive Blast Effect, Color(Purple), Event Player.botRayCastHitPosition, 4); + Play Effect(All Players(All Teams), Pharah Concussive Blast Sound, Color(Purple), Event Player.botRayCastHitPosition, 250); + Play Effect(All Players(All Teams), Bad Explosion, Color(Purple), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 3.300, 2); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Color(Purple), Eye Position(Event Player), 170); + If(Distance Between(Event Player.botRayCastHitPosition, Global.gatePosition) < 4 && Is In Line of Sight( + Event Player.botRayCastHitPosition, Global.gatePosition, Enemy Barriers Block LOS)); + Global.gateHealth -= 80; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Wait(0.150, Ignore Condition); + Destroy Effect(Event Player.botEffects); + Wait(0.060, Ignore Condition); + Wait Until(!Is Reloading(Event Player), 2.500); + End; + } +} + +rule("BOT: ORISA-BASTION - CAN'T SEE THE TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Is In Line of Sight(Eye Position(Event Player), Global.gatePosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.botTargetPosition = Global.botOrisaTargetPosition; + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: ORISA-BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Orisa; + } + + actions + { + Allow Button(Event Player, Button(Ability 2)); + Kill(Global.botOrisaChild, Null); + Detach Players(Global.botOrisaChild); + Clear Status(Global.botOrisaChild, Phased Out); + Set Damage Dealt(Global.botOrisaChild, 100); + Global.botOrisaChild.botIsOrisaChild = False; + Global.botOrisaChild = Null; + Global.botOrisaParent = Null; + Start Forcing Player To Be Hero(Event Player, Hero(Widowmaker)); + } +} + +rule("SUBROUTINE: ORISA - RESPAWN") +{ + event + { + Subroutine; + BotOrisaRespawn; + } + + actions + { + Global.botOrisaParent = Event Player; + "WAITING FOR ANY BASTION TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero(Bastion)), + 99999); + "SETUP BASTION AS CHILD" + Global.botOrisaChild = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Bastion))[0]; + Global.botOrisaChild.botIsOrisaChild = True; + Global.botOrisaChild.botDoesUniqueBehaviour = True; + Wait(2, Ignore Condition); + Respawn(Global.botOrisaChild); + Start Scaling Player(Global.botOrisaChild, 1.800, False); + Set Damage Dealt(Global.botOrisaChild, 2000); + Set Status(Global.botOrisaChild, Null, Phased Out, 9999); + Disable Nameplates(Global.botOrisaChild, All Players(All Teams)); + Set Facing(Global.botOrisaChild, Vector(X Component Of(Facing Direction Of(Event Player)), 9999, Z Component Of( + Facing Direction Of(Event Player))), To World); + Start Holding Button(Global.botOrisaChild, Button(Ability 1)); + Wait Until(Is In Alternate Form(Global.botOrisaChild), 5); + Stop Holding Button(Global.botOrisaChild, Button(Ability 1)); + Teleport(Global.botOrisaChild, Position Of(Event Player)); + Attach Players(Global.botOrisaChild, Global.botOrisaParent, Vector(0, 1.800, 0.230)); + disabled Wait(1, Ignore Condition); + disabled Stop Holding Button(Global.botOrisaChild, Button(Primary Fire)); + disabled Wait(0.250, Ignore Condition); + Call Subroutine(BotLandingFromSky); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + Event Player.botTargetPosition = Global.botOrisaTargetPosition; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 0 - ZENS, REINS, BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 0; + } + + actions + { + "CREATE BOTS - ZEN" + While(Count Of(All Players(Team 2)) < 13); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "BALL" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "REPLACE DEAD ZEN TO REIN" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) != 3); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 1 - WIDOW") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 1; + } + + actions + { + Global.isNewWaveGameLogicProcessing = True; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Global.isNewWaveGameLogicProcessing = False; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 3 - BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 3; + } + + actions + { + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 5 - REINS WAVE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 5; + } + + actions + { + "PREPARE WAVE - DESTROY WIDOW AND BALLS" + Destroy Dummy Bot(Team 2, Slot Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))[0])); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))[0]; + Kill(Global.defaultCurrentBot, Null); + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + End; + "BOSS WAVE" + Big Message(All Players(All Teams), Custom String("BOSS WAVE - {1} {0}", Hero Icon String(Hero(Reinhardt)), Hero(Reinhardt))); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) < 6); + Wait Until(Is True For Any(All Players(Team 2), Distance Between(Position Of(Current Array Element), Global.gatePosition) + > 13 && Hero Of(Current Array Element) == Hero(Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + disabled Wait(0.200, Ignore Condition); + disabled Set Max Health(Global.defaultCurrentBot, 50); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) > 3); + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Reinhardt)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Reinhardt))[0]; + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(All Players(Team 2)) < 13); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Big Message(All Players(All Teams), Custom String("BOSS WAVE FINISHED!")); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 7 - BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 7; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 9 - ECHO, +1 BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 9; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Echo))) == 0); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + "FILL EMPTY SLOTS BY ZENS" + While(Count Of(All Players(Team 2)) < 12); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("Ana Nano Variable") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + } + + actions + { + Player Closest To Reticle(Event Player, Team 1).isNanoed = 1; + } +} + +rule("isNanoed") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isNanoed == True; + } + + actions + { + If(Is Dead(Event Player)); + Event Player.isNanoed = 0; + End; + Wait(8, Ignore Condition); + Event Player.isNanoed = 0; + } +} + +rule("money on kill") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + actions + { + If(Hero Of(Victim) == Hero(Zenyatta)); + All Players(Team 1).money[0] += 5 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 10 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Reinhardt)); + All Players(Team 1).money[0] += 15 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 20 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Wrecking Ball)); + All Players(Team 1).money[0] += 25 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 25 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Widowmaker)); + All Players(Team 1).money[0] += 30 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 30 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Bastion)); + All Players(Team 1).money[0] += 50 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 50 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Echo)); + All Players(Team 1).money[0] += 75 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 75 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Orisa)); + All Players(Team 1).money[0] += 100 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 100 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + } +} + +rule("Abilities and Hero Talents by Shingen and LemonAid") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.damageDealt = 100; + Event Player.playerHealth = 100; + Event Player.money[0] = 2400 + Global.startMoney; + If(Custom String("{0}", Event Player) == Custom String("ShuriZma")); + Create HUD Text(Event Player, Custom String("Serverload: {0}, AVG {1}, Peak {2}", Server Load, Server Load Average, + Server Load Peak), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + End; + } +} + +rule("Team 1 (Ability): Headhunter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.abilities[1] == True; + Event Was Critical Hit == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.abilities[1] * 40 / Event Player.damageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Ambush") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.abilities[2] == True; + Event Ability != Null; + (Y Component Of(Position Of(Event Player)) - Y Component Of(Position Of(Victim)) >= 3 || Absolute Value(Horizontal Angle Towards( + Victim, Event Player)) >= 90) == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.abilities[2] * 30 / Event Player.damageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Quick Fix") +{ + event + { + Player Earned Elimination; + Team 1; + All; + } + + conditions + { + Event Player.abilities[3] == True; + } + + actions + { + Heal(Event Player, Null, Event Player.abilities[3] * 50); + Set Move Speed(Event Player, 100 + Event Player.abilities[3] * 20); + Wait(5, Restart When True); + Set Move Speed(Event Player, 100); + } +} + +rule("Team 1 (Ability): Heavyweight") +{ + event + { + Player Dealt Knockback; + Team 1; + All; + } + + conditions + { + Event Player.abilities[4] == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.abilities[4] * 25 / Event Player.damageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Charged") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[5] == True; + Ultimate Charge Percent(Event Player) < Event Player.abilities[5] * 20; + } + + actions + { + Set Ultimate Charge(Event Player, Event Player.abilities[5] * 20); + If(Is Duplicating(Event Player)); + Wait(0.016, Ignore Condition); + Set Ultimate Charge(Event Player, Event Player.abilities[5] * 20); + End; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Team 1 (Ability): Haste Primary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Primary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Primary Fire), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Primary Fire))); + } +} + +rule("Team 1 (Ability): Haste Secondary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Secondary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Secondary Fire), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Secondary Fire))); + } +} + +rule("Team 1 (Ability): Haste Ability 1") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 1)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 1))); + } +} + +rule("Team 1 (Ability): Haste Ability 2") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 2)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 2))); + } +} + +rule("Team 1 (Ability): Haste Jump") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Jump)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Jump), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, Button( + Jump))); + } +} + +rule("Team 1 (Ability): Haste Crouch") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Crouch)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Crouch), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, Button( + Crouch))); + } +} + +rule("Team 1 (Ability): Heavy Impact") +{ + event + { + Player Took Damage; + Team 2; + All; + } + + conditions + { + Attacker.abilities[7] == True; + } + + actions + { + Abort If(Random Real(-0.020, 1) > Event Damage / Max Health(Event Player)); + Set Status(Event Player, Attacker, Stunned, 1 * Attacker.abilities[7]); + Wait(5, Ignore Condition); + } +} + +rule("Team 1 (Ability): Binding Heal") +{ + event + { + Player Dealt Healing; + Team 1; + All; + } + + conditions + { + Event Player.abilities[10] == True; + Healee != Event Player; + } + + actions + { + Set Player Health(Event Player, Health(Event Player) + Event Player.abilities[10] * 0.250 * Event Healing); + } +} + +rule("Team 1 (Ability): Resilience") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[11] == True; + Normalized Health(Event Player) < Event Player.abilities[11] * 0.300; + } + + actions + { + Set Damage Received(Event Player, 70); + Wait Until(!(Event Player.abilities[11] && Normalized Health(Event Player) < Event Player.abilities[11] * 0.300), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Auto Repair") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.automaticRepair == True; + Global.gateHealth < Global.gateMaxHealth; + } + + actions + { + If(Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2]); + Global.gateHealth += 10 * Global.automaticRepair; + Global.upgradeGateMaxHealthValue += 10 * Global.automaticRepair; + Else; + Global.gateHealth += 5 * Global.automaticRepair; + Global.upgradeGateMaxHealthValue += 5 * Global.automaticRepair; + End; + If(Global.gateHealth > Global.gateMaxHealth); + Global.gateHealth = Global.gateMaxHealth; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(5, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ana Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Ana), Button(Ability 1)), Custom String( + "Sleep Paralysis: Slept enemies cannot be woken up by damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Ana), Button(Ability 2)), Custom String( + "Multinade: Ana throws multiple Biotic Grenades")); + } +} + +rule("Brigitte Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Brigitte), Button(Ability 1)), Custom String( + "Heavy Iron: Hitting enemies with Whip Flail will root them in pace")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Brigitte), Button(Ultimate)), Custom String( + "Endeavor: Gain a health, damage and speed boost when your barrier breaks")); + } +} + +rule("Mercy Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Mercy), Button(Ability 2)), Custom String( + "Angelic blessing: Healing an ally slowly charges their ultimate")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Mercy), Button(Ultimate)), Custom String( + "Holy light missiles: Unleash blasts of holy light missiles during valkyrie")); + } +} + +rule("Lúcio Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Lúcio), Button(Secondary Fire)), Custom String( + "Healing Wave: Soundwave heals allies for 30% of their max HP")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Lúcio), Button(Ability 1)), Custom String( + "Reverse Amp: Amp It Up inflicts the opposite effect of the currently played song to enemies")); + } +} + +rule("Moira Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Moira), Button(Secondary Fire)), Custom String( + "Hose: Biotic Grasp primary will damage and push enemies back")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Moira), Button(Ability 2)), Custom String( + "Flourish: Biotic Orbs are 3x more effective")); + } +} + +rule("Baptiste Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + actions + { + Event Player.heroTalentText[1] = Array(Icon String(Poison), Custom String( + "Corrode: Regenerative Burst will damage and poison enemies")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Breakthrough: Immortality Field HP threshold increased to 100%; allies inside gain ultimate")); + } +} + +rule("Ashe Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Ashe), Button(Ability 2)), Custom String( + "Wildfire: Shooting a burning enemy ignites other nearby enemies")); + Event Player.heroTalentText[2] = Array(Icon String(Fire), Custom String( + "Flare trigger: Coach gun instantly damages all burning enemies")); + } +} + +rule("D.Va Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(D.Va), Button(Secondary Fire)), Custom String( + "Voltage Grid: Defense Matrix will damage and root enemies it's casted over")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(D.Va), Button(Ability 1)), Custom String( + "Shooting Star: Boosters set enemies on fire")); + } +} + +rule("Genji Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Genji), Button(Ability 1)), Custom String( + "Venomous Strike: Swift Strike poisons enemies; heal for poison damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Genji), Button(Ultimate)), Custom String( + "Dragon's Breath: Dragonblade fires large explosive energy charges")); + } +} + +rule("Hanzo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Hanzo; + } + + actions + { + Event Player.heroTalentText[1] = Array(Icon String(Bolt), Custom String( + "Stormbreak: Enemies eliminated by hanzo unleash a thundercloud")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Hanzo), Button(Ability 2)), Custom String( + "Punch II: Storm Arrows deal more damage and stun and knockback enemies")); + } +} + +rule("Widowmaker Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Widowmaker; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Widowmaker), Button(Ultimate)), Custom String( + "Kiss Of Death: Scoped critical hits against enemies below 30% health explode and instantly die")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Widowmaker), Button(Ability 2)), Custom String( + "Epidemic: Enemies hurt by Venom Mine unleash toxic pulses; heal for dealt damage")); + } +} + +rule("McCree Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Cassidy), Button(Ability 2)), Custom String( + "Panic: Flashbang puts enemies in fear; deal +120% more damage to enemies in fear")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Cassidy), Button(Ultimate)), Custom String( + "Clocked: Deadeye deals more damage and knocks enemies down")); + } +} + +rule("Reinhardt Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Reinhardt), Button(Ability 2)), Custom String( + "Fire Blast: Fire Strike explodes as it deals damage, setting enemies on fire")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Reinhardt), Button(Ultimate)), Custom String( + "Epicenter: Earthshatter travels in all directions")); + } +} + +rule("Soldier: 76 Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ultimate)), Custom String( + "Triple Threat: 2 more rockets are fired alongside Helix Rockets")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Soldier: 76), Button(Ability 1)), Custom String( + "Shoulder Check: Sprinting into enemies will damage and tackle them to the ground")); + } +} + +rule("Torbjörn Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Torbjörn), Button(Ability 2)), Custom String( + "Melting point: Unleash heatwaves during overload and molten core")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Torbjörn), Button(Ultimate)), Custom String( + "Roots Of Magma: Enemies trapped in Molten Core blots cannot move")); + } +} + +rule("Tracer Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Tracer), Button(Ability 2)), Custom String( + "Vortex: Recall pulls and roots enemies towards the activation point")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Tracer), Button(Ultimate)), Custom String( + "Chain Reaction: Pulse Bomb creates chain explosions on enemies damaged by it")); + } +} + +rule("Winston Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Winston), Button(Ability 2)), Custom String( + "Blast Barrier: Barrier Projector damages enemies inside the area")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Winston), Button(Ultimate)), Custom String( + "Next Generation: Eliminations during Primal Rage add +15% ultimate charge towards the next")); + } +} + +rule("Pharah Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Pharah; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ability 2)), Custom String( + "Head Trauma: Concussive Blast stuns and damages enemies for 25% of their max health")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Pharah), Button(Ability 1)), Custom String( + "Thunderbird: Gain 150 shields and deal 4x the damage to barriers and objects")); + } +} + +rule("Bastion Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Bomblets: Bullets shot during sentry configuration are explosive")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ability 1)), Custom String( + "Tesla: A powerful mounted laser will autmotically attack one enemy at a time")); + } +} + +rule("Doomfist Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Jump)), Custom String( + "Phase Shifter: Immune to damage while any ability is active")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Doomfist), Button(Ultimate)), Custom String( + "Fissure: Meteor Strike leaves a large fissure behind that burns enemies over it")); + } +} + +rule("Echo Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Focusing Optics: Focusing Beam damage ramp starts at 90% health")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Streamline: Fire many more sticky bombs per burst")); + } +} + +rule("Junkrat Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Junkrat; + } + + actions + { + Event Player.heroTalentText[1] = Array(Icon String(Fire), Custom String("Pyromania: All explosive attacks inflict fire damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Junkrat), Button(Ability 2)), Custom String( + "Short Fused: Steel Trap sets off violent explosions once triggered")); + } +} + +rule("Mei Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Mei), Button(Ultimate)), Custom String( + "Cold Snap: Instantly freeze neaerby enemies once Cryo-Freeze expires")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Mei), Button(Ability 2)), Custom String( + "Icebound: While Ice Wall is up, Icicles freeze and deal much more damage")); + } +} + +rule("Orisa Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Orisa), Button(Ability 1)), Custom String( + "Immovable Object: During Fortify, become immune and convert 50% of taken damage to healing")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Orisa), Button(Secondary Fire)), Custom String( + "Unstoppable Force: Halt! is much larger and pushes enemies. When triggered, it explodes violently")); + } +} + +rule("Reaper Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Reaper), Button(Ability 1)), Custom String( + "shadow streak: shadow step creates a beam that damages enemies who cross")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Reaper), Button(Ultimate)), Custom String( + "Loom: Traumatize enemies in front of you when using Wraith Form")); + } +} + +rule("Roadhog Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + actions + { + Event Player.heroTalentText[1] = Array(Icon String(Poison), Custom String("Stench: Roadhog constantly damages enemies nearby")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Roadhog), Button(Ability 1)), Custom String( + "Rusted Anchor: Hook deals more damage; Eliminations will reset hook cooldown")); + } +} + +rule("Sigma Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Sigma), Button(Ability 1)), Custom String( + "Gravity Well: Kinetic Grasp gives invincibility")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Sigma), Button(Ultimate)), Custom String( + "Gravity Channels: Gravitic Flux damages enemies for 75% of max hp instead of 50%")); + } +} + +rule("Sombra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Sombra), Button(Secondary Fire)), Custom String( + "Malware: Enemies hacked or in fear take +100% more damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Sombra), Button(Ultimate)), Custom String( + "Glitch: EMP leaves behind a large hack zone ")); + } +} + +rule("Symmetra Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Symmetra; + } + + actions + { + Event Player.heroTalentText[1] = Array(Icon String(Bolt), Custom String( + "High Voltage: Enemies eliminated by Symmetra explode and damage other enemies")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ultimate)), Custom String( + "Energy Source: While Photon Barrier is active, all players regenerate health and gain ultimate")); + } +} + +rule("Wrecking Ball Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ultimate)), Custom String( + "Mirror Ball: Reflect 100% of taken damage to nearby enemies")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ability 2)), Custom String( + "Distort: Adaptive Shields damages and hacks nearby enemies")); + } +} + +rule("Zarya Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zarya; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Zarya), Button(Ability 1)), Custom String( + "Augment: Health and barrier hp increased by 50%; barrier sized doubled")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Perpetual Energy: secondary inflicts burn damage that continues to last until the enemy dies")); + } +} + +rule("Zenyatta Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + actions + { + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Vigor: The ally under the effect of Harmony Orb is immune to damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Zenyatta), Button(Ultimate)), Custom String( + "Perfect Balance: Transcendence damages enemies in a large proximity")); + } +} + +rule("Ana: Sleep Paralysis") +{ + event + { + Player Dealt Damage; + Team 1; + Ana; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Black), Victim, 1); + Wait(0.250, Ignore Condition); + Set Status(Victim, Null, Knocked Down, 5); + } +} + +rule("Ana: Multinade") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Event Player.abilityCountdown = 4; + While(Event Player.abilityCountdown > 0); + Wait(0.030, Ignore Condition); + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Cancel Primary Action(Event Player); + Wait(0.050, Ignore Condition); + Press Button(Event Player, Button(Ability 2)); + Event Player.abilityCountdown -= 1; + End; + Wait(2, Ignore Condition); + } +} + +rule("Brigitte: Heavy Iron") +{ + event + { + Player Dealt Damage; + Team 1; + Brigitte; + } + + conditions + { + (Event Ability == Button(Primary Fire) || Event Ability == Button(Ability 1)) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Victim, 1.500); + Set Status(Victim, Null, Rooted, 0.500); + Set Environment Credit Player(Victim, Event Player); + } +} + +rule("Brigitte: Endeavor") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Ability Cooldown(Event Player, Button(Secondary Fire)) >= 0.100; + Event Player.abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player, 0.400, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Eye Position(Event Player), 15); + Heal(Players Within Radius(Event Player, 15, Team Of(Event Player), Off), Event Player, 200); + Event Player.damageDealt *= 2.500; + Set Move Speed(Event Player, 100 * 1.750); + Add Health Pool To Player(Event Player, Armor, Max Health(Event Player) / 2, False, True); + Event Player.hpPool[1] = Last Created Health Pool; + Wait Until(Is Dead(Event Player), 6); + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Set Move Speed(Event Player, 100); + Remove Health Pool From Player(Event Player.hpPool[1]); + Destroy Effect(Event Player.effects_[1]); + } +} + +rule("Mercy: Angelic Blessing") +{ + event + { + Player Dealt Healing; + All; + Mercy; + } + + conditions + { + Event Player.abilities[8] == True; + Healee != Event Player; + Normalized Health(Healee) < True; + } + + actions + { + Set Ultimate Charge(Healee, Ultimate Charge Percent(Healee) + 1); + Wait(0.400, Ignore Condition); + } +} + +rule("Mercy: Aurora") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ultimate(Event Player) == True; + } + + actions + { + Wait(1.500, Ignore Condition); + Event Player.abilityProjectile1 = Eye Position(Event Player); + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(All Teams), Event Player, True); + Create Beam Effect(All Players(All Teams), Mercy Heal Beam, Event Player, Event Player.abilityProjectile1, Color(White), + Visible To Position and Radius); + Event Player.effects_[3] = Last Created Entity; + Chase Player Variable At Rate(Event Player, abilityProjectile1, Event Player.abilityEnd, 70, Destination and Rate); + While(Event Player.abilityEnd != Event Player.abilityProjectile1); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Event Player.abilityProjectile1, 1); + Wait(0.032, Ignore Condition); + End; + Destroy Effect(Event Player.effects_[3]); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.abilityProjectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.abilityProjectile1, 5); + Damage(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 120); + Loop If Condition Is True; + } +} + +rule("Lucio: Healing Wave") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4); + Heal(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 4, 4, Team Of(Event Player), Surfaces), + Event Player, Max Health(Filtered Array(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4, Team Of(Event Player), Surfaces), Is Alive(Current Array Element))) * 0.300); + } +} + +rule("Lucio: Reverse Amp") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + If(Is Using Ability 1(Event Player)); + Set Status(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Rooted, 4); + Else; + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 16.250); + End; + Play Effect(All Players(All Teams), Ring Explosion, Is Using Ability 1(Event Player) ? Color(Green) : Color(Yellow), Event Player, + 1); + Wait(0.400, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Hose") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Event Player.abilities[8] == True; + Ability Resource(Event Player, Button(Primary Fire)) > False; + } + + actions + { + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Facing Direction Of(Event Player), 15, To World, + Cancel Contrary Motion); + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && !Is In Line of Sight(Current Array Element, Event Player, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Up, 8, To World, Cancel Contrary Motion); + Start Damage Over Time(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), + Distance Between(Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS)), Event Player, 1, 15); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Flourish - Damage") +{ + event + { + Player Dealt Damage; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("[Moira] Flourish - Healing") +{ + event + { + Player Dealt Healing; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[12] == True; + } + + actions + { + Heal(Healee, Event Player, Event Healing * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Healee, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("Baptiste: Corrode") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 20); + Wait(0.200, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 12); + } +} + +rule("Baptiste: Breakthrough") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Status(Event Player, Unkillable) == True; + (Event Player.abilities[12] ? Players On Hero(Hero(Baptiste), Team Of(Event Player)) : Empty Array).abilities[12] == True; + } + + actions + { + Heal(Event Player, Event Player, 10000); + Set Status(Event Player, Null, Invincible, 0.800); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ashe: Firebourne") +{ + event + { + Player Dealt Damage; + Team 1; + Ashe; + } + + conditions + { + Event Player.abilities[8] == True; + Event Ability == Button(Primary Fire); + Has Status(Victim, Burning) == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Null, Burning, 10); + Start Damage Over Time(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Event Player, 10, 15); + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 5); + Wait(0.250, Ignore Condition); + } +} + +rule("Ashe: Taunt") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Damage(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, Burning)), + Event Player, 125); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Frozen, + 0.016); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Stunned, + 2); + } +} + +rule("D.Va: Voltage Grid") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 2, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 5, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 8, 0.500); + Wait(0.300, Ignore Condition); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Wait(0.016, Ignore Condition); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Loop If Condition Is True; + } +} + +rule("D.Va: Shooting Star") +{ + event + { + Player Dealt Knockback; + Team 1; + D.Va; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, 40); + Set Status(Victim, Null, Burning, 3); + Start Damage Over Time(Victim, Event Player, 3, 35); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 1); + } +} + +rule("Genji: Venomous Strike") +{ + event + { + Player Dealt Damage; + Team 1; + Genji; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.abilities[8] == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 3, 25); + Start Damage Over Time(Victim, Event Player, 3, 25); + Damage(Victim, Event Player, 25); + Heal(Event Player, Event Player, 25); + } +} + +rule("Genji: Dragon's Breath") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is Firing Primary(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Good Aura, Color(Lime Green), Event Player.abilityProjectile1, 1, + Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Event Player.abilityProjectile1 = Eye Position(Event Player); + Chase Player Variable At Rate(Event Player, abilityProjectile1, Event Player.abilityEnd, 80, Destination and Rate); + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True); + Wait Until(Event Player.abilityEnd == Event Player.abilityProjectile1, 1); + Destroy Effect(Event Player.effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Green), Event Player.abilityProjectile1, 100); + Play Effect(All Players(All Teams), Bad Explosion, Color(Lime Green), Event Player.abilityProjectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Green), Event Player.abilityProjectile1, 5); + Damage(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 100); + } +} + +rule("[Hanzo] Stormbreak (stormEffects6)") +{ + event + { + Player Died; + Team 2; + All; + } + + conditions + { + Attacker.abilities[8] == True; + Hero Of(Attacker) == Hero(Hanzo); + } + + actions + { + Event Player.stormProjectile = Eye Position(Event Player); + Event Player.stormEndPoint = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Up * 12, Null, + All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, stormProjectile, Event Player.stormEndPoint, 4, Destination and Rate); + Create Effect(All Players(All Teams), Cloud, Color(White), Vector(False, -0.500, False) + Event Player.stormProjectile, 4, + Visible To Position and Radius); + Event Player.stormEffects[3] = Last Created Entity; + Create Effect(All Players(All Teams), Bad Aura, Color(White), Event Player.stormProjectile, 3, Visible To Position and Radius); + Event Player.stormEffects[4] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(White), Event Player.stormProjectile, 3.500, Visible To Position and Radius); + Event Player.stormEffects[5] = Last Created Entity; + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.stormProjectile, Ray Cast Hit Position( + Event Player.stormProjectile, Vector(0.100, 0, 0) + Event Player.stormProjectile + Down * 1000, Null, All Players(All Teams), + False), Color(Aqua), Visible To Position and Radius); + Event Player.stormEffects[6] = Last Created Entity; + While(Distance Between(Event Player.stormProjectile, Event Player.stormEndPoint) > 1); + Wait(0.600, Ignore Condition); + Damage(Players Within Radius(Ray Cast Hit Position(Event Player.stormProjectile, Event Player.stormProjectile + Down * 1000, Null, + All Players(All Teams), False), 3, Team Of(Event Player), Surfaces), Attacker, 50); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Ray Cast Hit Position(Event Player.stormProjectile, + Event Player.stormProjectile + Down * 1000, Null, All Players(All Teams), False), 3); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Ray Cast Hit Position(Event Player.stormProjectile, + Event Player.stormProjectile + Down * 1000, Null, All Players(All Teams), False), 3); + End; + Destroy Effect(Event Player.stormEffects[3]); + Destroy Effect(Event Player.stormEffects[4]); + Destroy Effect(Event Player.stormEffects[5]); + Destroy Effect(Event Player.stormEffects[6]); + } +} + +rule("Hanzo: Punch II") +{ + event + { + Player Dealt Damage; + Team 1; + Hanzo; + } + + conditions + { + Event Player.abilities[12] == True; + Event Ability == Button(Ability 2); + Hero Of(Victim) != Hero(Torbjörn); + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.800); + Apply Impulse(Victim, Facing Direction Of(Event Player), 12, To World, Cancel Contrary Motion); + Apply Impulse(Victim, Up, 5, To World, Cancel Contrary Motion); + Set Environment Credit Player(Victim, Event Player); + Set Status(Victim, Null, Stunned, 1); + } +} + +rule("Widowmaker: Kiss Of Death") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + (Normalized Health(Victim) <= 0.300 || Event Damage >= Normalized Health(Victim) + Event Damage) == True; + Is Firing Secondary(Event Player) == True; + Event Ability == Button(Primary Fire); + Event Player.abilities[8] == True; + Event Damage >= 40; + Event Was Critical Hit == True; + } + + actions + { + Kill(Victim, Event Player); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 2), Victim, 3); + Damage(Players Within Radius(Victim, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage * 1.500); + } +} + +rule("Widowmaker: Epidemic") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 8); + Play Effect(All Players(All Teams), Good Explosion, Color(Purple), Victim, 4); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Victim, 16); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Victim, 3); + Start Damage Over Time(Players Within Radius(Victim, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, 50); + Start Heal Over Time(Event Player, Event Player, 3, 50); + Wait(0.500, Ignore Condition); + } +} + +rule("McCree: Panic") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[8] == True; + } + + actions + { + Victim.fearedUntil = Total Time Elapsed + 3.500; + } +} + +rule("McCree: Panic - Damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), + Event Player.fearedUntil >= Total Time Elapsed), All Players(Team Of(Event Player)), 220, + Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Wait Until(!Event Player.abilities[8], 99999); + Stop Damage Modification(Event Player.modificationDamage[1]); + } +} + +rule("McCree: Clocked") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Damage(Victim, Event Player, Event Damage * 1.500); + Set Status(Victim, Null, Knocked Down, 3); + } +} + +rule("Reinhardt: Fire Blast") +{ + event + { + Player Dealt Damage; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Start Damage Over Time(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, 20); + Set Status(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Burning, 5); + } +} + +rule("Reinhardt: Epicenter") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is On Ground(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, Knocked Down, 2.500); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 10); + Damage(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, 50); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 20); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 30); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 40); + Wait(5, Ignore Condition); + } +} + +rule("[Soldier: 76] Rocket Assault Rifle") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Event Player.abilityProjectile2 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(-2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.abilityProjectile1 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.abilityPosition = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, + 0), Event Player, Rotation); + Event Player.abilityEnd = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, 0), + Event Player, Rotation); + Chase Player Variable At Rate(Event Player, abilityPosition, Event Player.abilityProjectile1, 60, Destination and Rate); + Chase Player Variable At Rate(Event Player, abilityEnd, Event Player.abilityProjectile2, 60, Destination and Rate); + Wait Until(Event Player.abilityPosition == 0 && Event Player.abilityEnd == 0, 2.500); + } +} + +rule("[Soldier: 76] First Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.abilityProjectile1 != Event Player.abilityPosition; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.abilityPosition, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.abilityPosition, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.abilityPosition, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.abilityPosition, 2.500); + Stop Chasing Player Variable(Event Player, abilityPosition); + Wait(0.016, Ignore Condition); + Damage(Players Within Radius(Event Player.abilityPosition, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 80); + Stop Chasing Player Variable(Event Player, abilityPosition); + Event Player.abilityPosition = 0; + Event Player.abilityProjectile1 = 0; + Wait(0.016, Ignore Condition); + } +} + +rule("[Soldier: 76] Second Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.abilityProjectile2 != Event Player.abilityEnd; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.abilityEnd, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.abilityEnd, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.abilityEnd, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.abilityEnd, 2.500); + Stop Chasing Player Variable(Event Player, abilityEnd); + Damage(Players Within Radius(Event Player.abilityEnd, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Event Player.abilityEnd = 0; + Event Player.abilityProjectile2 = 0; + } +} + +rule("Soldier: 76 - Init rockets") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Event Player.abilityProjectile1 = Event Player.abilityPosition; + Event Player.abilityProjectile2 = Event Player.abilityEnd; + } +} + +rule("[Soldier: 76] Shoulder Check") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[12] == True; + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 3; + Is Alive(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) == True; + } + + actions + { + Damage(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Event Player, 55); + Set Status(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Null, Knocked Down, 1.500); + Apply Impulse(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Facing Direction Of(Event Player), 15, + To World, Cancel Contrary Motion); + Apply Impulse(Event Player, Vector(0, 8, 15), 15, To Player, Cancel Contrary Motion); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Closest Player To(Event Player, Opposite Team Of(Team Of( + Event Player))), 1); + Set Ability Cooldown(Event Player, Button(Melee), 0); + Press Button(Event Player, Button(Melee)); + Wait(1, Ignore Condition); + } +} + +rule("Torbjorn: Melting Point") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Event Player.abilities[8] == True; + (Is Using Ability 2(Event Player) || Is Using Ultimate(Event Player)) == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Event Player, 8); + Play Effect(All Players(All Teams), Bad Explosion, Color(Yellow), Event Player, 8); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 16); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, + 25); + Set Status(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Off), Null, Burning, 3); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player, 100); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Torbjorn: Roots of Magma") +{ + event + { + Player Dealt Damage; + Team 1; + Torbjörn; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Set Status(Victim, Null, Rooted, 1); + Wait(1, Ignore Condition); + } +} + +rule("Tracer: Vortex") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Heal(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, 0); + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 10); + Play Effect(All Players(All Teams), Ring Explosion, Color(Red), Position Of(Event Player), 24); + Play Effect(All Players(All Teams), Ring Explosion, Color(Yellow), Position Of(Event Player), 18); + Play Effect(All Players(All Teams), Ring Explosion, Color(Green), Position Of(Event Player), 12); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player), 6); + Set Environment Credit Player(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player); + } +} + +rule("Tracer: Vortex 2") +{ + event + { + Player Received Healing; + Team 2; + All; + } + + conditions + { + Healer.abilities[8] == True; + Hero Of(Healer) == Hero(Tracer); + Is Using Ability 2(Healer) == True; + Event Ability == Null; + Event Damage <= 20; + } + + actions + { + Apply Impulse(Event Player, Up, 5, To World, Cancel Contrary Motion); + Wait(0.100, Ignore Condition); + Apply Impulse(Event Player, Direction Towards(Event Player, Healer), Distance Between(Event Player, Healer) * 3.500, To World, + Cancel Contrary Motion); + Set Status(Event Player, Null, Rooted, 1.300); + } +} + +rule("Tracer: Chain Reaction") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is True For Any(Filtered Array(All Players(Team Of(Event Player)), Current Array Element.chainReactionOn), Distance Between( + Event Player, Current Array Element) <= 8 && True) == True; + Event Player.chainReactionImmune == False; + Event Player.chainReactionOn == False; + Is Alive(Event Player) == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Event Player.chainReactionOn = True; + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player, 3); + } +} + +rule("Tracer: Chain Reaction 2") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Event Player.chainReactionOn == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Aqua), Event Player, 3); + Damage(Event Player, Players On Hero(Hero(Tracer), Opposite Team Of(Team Of(Event Player))), 200); + Wait(0.500, Ignore Condition); + Event Player.chainReactionImmune = True; + Event Player.chainReactionOn = False; + Wait(2, Ignore Condition); + Event Player.chainReactionImmune = False; + } +} + +rule("Tracer: Chain Reaction 3") +{ + event + { + Player Dealt Damage; + Team 1; + Tracer; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Damage > 20; + Event Player.abilities[12] == True; + } + + actions + { + Victim.chainReactionOn = True; + } +} + +rule("[Winston] Electric Field") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player.abilityProjectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 65); + Destroy Effect(Event Player.effects_[1]); + Event Player.abilityActive = True; + Create Effect(All Players(All Teams), Orb, Color(White), Event Player.abilityProjectile1, 1, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Stop Chasing Player Variable(Event Player, abilityResource); + Event Player.abilityProjectile1 = Eye Position(Event Player); + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Down * 1000, Null, + All Players(All Teams), False); + Wait(0.100, Ignore Condition); + Event Player.abilityResource = 5; + Wait(0.250, Ignore Condition); + Chase Player Variable At Rate(Event Player, abilityResource, 20, 7, Destination and Rate); + Chase Player Variable At Rate(Event Player, abilityProjectile1, Event Player.abilityEnd, Event Player.abilityResource, + Destination and Rate); + Wait(8.650, Restart When True); + Event Player.abilityActive = False; + } +} + +rule("[Winston] Electric Field 2") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Event Player.abilityActive == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Event Player.abilityProjectile1, 5); + Damage(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 33); + Play Effect(All Players(All Teams), Ring Explosion, Color(Blue), Event Player.abilityProjectile1, 10); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + Damage(Players Within Radius(Event Player.abilityProjectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 80); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Event Player.abilityProjectile1, 12); + Destroy Effect(Event Player.effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player.abilityProjectile1, 125); + } +} + +rule("Winston: Next Generation") +{ + event + { + Player Earned Elimination; + Team 1; + Winston; + } + + conditions + { + Ultimate Charge Percent(Event Player) <= 80; + Is Using Ultimate(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 15); + } +} + +rule("Pharah: Head Trauma") +{ + event + { + Player Dealt Knockback; + Team 1; + Pharah; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[8] == True; + Victim != Event Player; + } + + actions + { + Damage(Victim, Event Player, Max Health(Victim) * 0.300); + Set Status(Victim, Event Player, Knocked Down, 1); + Play Effect(All Players(All Teams), Good Explosion, Color(Team 1), Victim, 1); + } +} + +rule("Pharah: Thunderbird") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[12] == True; + Hero Of(Event Player) == Hero(Pharah); + } + + actions + { + Event Player.damageDealt *= 4; + Start Damage Modification(All Players(All Teams), Event Player, 25, Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Add Health Pool To Player(Event Player, Shields, 150, True, True); + Event Player.hpPool[1] = Last Created Health Pool; + Wait Until(!Event Player.abilities[12] || Hero Of(Event Player) != Hero(Pharah), 99999); + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Stop Damage Modification(Event Player.modificationDamage[1]); + Remove Health Pool From Player(Event Player.hpPool[1]); + } +} + +rule("Orisa: Unstoppable Force") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Event Player.genDirection = Facing Direction Of(Event Player); + Event Player.abilityActive = True; + Create Effect(All Players(All Teams), Sphere, Color(Green), Event Player.abilityProjectile1, 4, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Event Player.abilityProjectile1 = Eye Position(Event Player) + Facing Direction Of(Event Player) * 0.500; + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 100, Null, All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, abilityProjectile1, Event Player.abilityEnd, 25, Destination and Rate); + Wait(0.250, Ignore Condition); + Wait Until((!Event Player.genAvailable && Is Button Held(Event Player, Button(Secondary Fire))) || ( + Event Player.abilityProjectile1 == Event Player.abilityEnd), 99999); + Stop Chasing Player Variable(Event Player, abilityProjectile1); + Wait(0.500, Ignore Condition); + Damage(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Lime Green), Event Player.abilityProjectile1, 5); + Destroy Effect(Event Player.effects_[1]); + Event Player.abilityActive = False; + } +} + +rule("Orisa: Availability for Halt!") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Event Player.genAvailable = True; + Wait Until(!Is Button Held(Event Player, Button(Secondary Fire)), 99999); + Event Player.genAvailable = False; + } +} + +rule("Orisa: Drag effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Event Player.abilities[12] == True; + Event Player.abilityActive == True; + } + + actions + { + Apply Impulse(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Is Alive(Event Player) ? Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of( + Event Player)), Surfaces) : Empty Array, Event Player.abilityProjectile1), 8, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Event Player.abilityProjectile1, Event Player.abilityEnd), 20, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Up, 5, + To Player, Cancel Contrary Motion); + Wait(0.200, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Orisa: Immoveable Object - Reduce dmg") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Set Damage Received(Event Player, 100 * 0.003); + Wait Until(!Is Using Ability 1(Event Player), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Orisa: Immovable Object - Healing") +{ + event + { + Player Took Damage; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Heal(Event Player, Null, Event Damage * 3); + } +} + +rule("[Reaper] Shadow Streak (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.abilities[8] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Event Player.abilityPosition = Position Of(Event Player) + Vector(0, 1, 0); + Wait(2, Abort When False); + Event Player.abilityEnd = Position Of(Event Player) + Vector(0, 1, 0); + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.abilityEnd, Event Player.abilityPosition, Color(Black), + Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Event Player.abilityActive = True; + Wait Until(Is Dead(Event Player) || Is Using Ability 2(Event Player), 99999); + Destroy Effect(Event Player.effects_[1]); + Event Player.abilityActive = False; + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage start to end (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.abilities[8] == True; + Ray Cast Hit Player(Event Player.abilityPosition, Event Player.abilityEnd, All Living Players(Opposite Team Of(Team Of( + Event Player))), Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.abilityActive == True; + } + + actions + { + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.abilityPosition, + Event Player.abilityEnd, All Living Players(All Teams), Event Player, True), 1); + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.abilityPosition, Event Player.abilityEnd, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage end to start (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.abilities[8] == True; + Ray Cast Hit Player(Event Player.abilityEnd, Event Player.abilityPosition, All Players(Opposite Team Of(Team Of(Event Player))), + Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.abilityActive == True; + } + + actions + { + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.abilityEnd, Event Player.abilityPosition, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.abilityEnd, + Event Player.abilityPosition, All Living Players(All Teams), Event Player, True), 1); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Reaper: Loom") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Hacked, 1.500); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Rooted, 1.500); + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Event Player, 45); + } +} + +rule("Sigma: Gravity Well") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, 25); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Null, Rooted, 2); + Set Status(Event Player, Null, Invincible, 1); + Play Effect(Event Player, Ring Explosion, Color(Blue), Eye Position(Event Player), 50); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Sigma: Gravity Channels") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ultimate(Event Player)), Event Player, 150, + Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Wait Until(!Event Player.abilities[12], 99999); + Stop Damage Modification(Event Player.modificationDamage[1]); + } +} + +rule("Echo: Focusing Optics") +{ + event + { + Player Dealt Damage; + Team 1; + Echo; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[8] == True; + Normalized Health(Victim) > 0.500; + Normalized Health(Victim) <= 0.900; + Is Duplicating(Event Player) == False; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 3); + Play Effect(All Players(All Teams), Bad Explosion, Color(Violet), Victim, 0.500); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Wait(0.700, Abort When False); + Cancel Primary Action(Event Player); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Set Projectile Speed(Event Player, 100); + Wait(0.150, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Bomblets") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Is In Alternate Form(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Orange), Null + Ray Cast Hit Position(Eye Position(Event Player), + Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, All Living Players(Opposite Team Of(Team Of( + Event Player))), All Players(Team Of(Event Player)), True), 2); + Damage(Players Within Radius(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 2, + Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 12); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Taser - Loop damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is True For Any(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive(Current Array Element) + && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status(Current Array Element, + Phased Out) && Distance Between(Event Player, Current Array Element) <= 25) == True; + Is Alive(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Explosion Sound, Color(White), Event Player.abilityPlayer, 80); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Event Player.abilityPlayer, 1); + Event Player.abilityPlayer = Filtered Array(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive( + Current Array Element) && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status( + Current Array Element, Phased Out) && Distance Between(Event Player, Current Array Element) <= 25); + Damage(Players Within Radius(Event Player.abilityPlayer, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 30); + Wait(0.450, Ignore Condition); + Loop If Condition Is True; + Event Player.abilityPlayer = Null; + } +} + +rule("Bastion: Taser - Visual beam") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player + Vector(False, 1, False), + Event Player.abilityPlayer != Null ? Event Player.abilityPlayer : Event Player, Color(Aqua), + Visible To Position Radius and Color); + Event Player.effects_[1] = Last Created Entity; + Wait Until(!Event Player.abilities[12], 99999); + Destroy Effect(Event Player.effects_[1]); + } +} + +rule("Sombra: Malware") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, + Hacked) || Current Array Element.fearedUntil >= Total Time Elapsed), All Players(Team Of(Event Player)), 200, + Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Wait Until(!Event Player.abilities[8], 99999); + Stop Damage Modification(Event Player.modificationDamage[1]); + } +} + +rule("Sombra: Glitch") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Event Player.abilityActive = True; + Event Player.abilityPosition = Position Of(Event Player); + Create Effect(All Players(All Teams), Sphere, Color(Purple), Event Player.abilityPosition, 15, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Wait(8, Ignore Condition); + Destroy Effect(Event Player.effects_[1]); + Event Player.abilityActive = False; + } +} + +rule("Sombra: Glitch - Loop") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.abilityActive == True; + } + + actions + { + Set Status(Players Within Radius(Event Player.abilityPosition, 15, Opposite Team Of(Team Of(Event Player)), Off), Null, Hacked, + 0.750); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Mei: Cold Snap") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Event Player.abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Event Player, 1, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Wait Until(!Is Using Ability 1(Event Player), 99999); + Destroy Effect(Event Player.effects_[1]); + Damage(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Frozen, 2); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Rooted, 2); + Play Effect(All Players(All Teams), Ring Explosion, Color(White), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Sky Blue), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player) + Vector(0, 1, 0), 20); + } +} + +rule("Mei: Icebound") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Is Firing Secondary(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Aqua), Event Player, 0.400, Visible To Position and Radius); + Event Player.effects_[2] = Last Created Entity; + Set Projectile Speed(Event Player, 200); + Wait Until(!Is Firing Secondary(Event Player), 99999); + Destroy Effect(Event Player.effects_[2]); + Set Projectile Speed(Event Player, 100); + } +} + +rule("Mei: Icebound - Icicles hit") +{ + event + { + Player Dealt Damage; + Team 1; + Mei; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Is Using Ability 2(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 1.250); + Set Status(Victim, Null, Frozen, 1); + Set Status(Victim, Null, Rooted, 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Victim, 1); + } +} + +rule("Wrecking Ball: Mirror Ball") +{ + event + { + Player Took Damage; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 4.500, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage); + Wait(0.100, Ignore Condition); + } +} + +rule("Wrecking Ball: Distort") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Set Status(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Hacked, Count Of( + Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces)) * 1.500); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Violet), Position Of(Event Player), 125); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Sound, Color(Purple), Position Of(Event Player), 16); + Play Effect(All Players(All Teams), Explosion Sound, Color(Violet), Position Of(Event Player), 80); + } +} + +rule("Symmetra: High voltage") +{ + event + { + Player Dealt Final Blow; + Team 1; + Symmetra; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Victim, 10); + Play Effect(All Players(All Teams), Bad Explosion, Color(Aqua), Victim, 8); + Damage(Players Within Radius(Victim, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 150); + } +} + +rule("Symmetra: Energy Source") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is True For Any(Players On Hero(Hero(Symmetra), Team Of(Event Player)), Is Using Ultimate(Current Array Element) + && Current Array Element.abilities[12]) == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 1, 40); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Event Player, 0.100); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Junkrat: Pyromania") +{ + event + { + Player Dealt Knockback; + Team 1; + Junkrat; + } + + conditions + { + Event Player.abilities[8] == True; + Event Ability != Button(Melee); + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 2, 30); + Set Status(Victim, Null, Burning, 2); + } +} + +rule("Junkrat: Short Fused") +{ + event + { + Player Dealt Damage; + Team 1; + Junkrat; + } + + conditions + { + Event Player.abilities[12] == True; + Event Ability == Button(Ability 2); + } + + actions + { + Event Player.abilityCountdown = 4; + While(Event Player.abilityCountdown > 0); + Event Player.abilityCountdown -= 1; + Event Player.abilityPosition = Position Of(Victim) + Vector(Random Real(-2, 2), Random Real(-2, 2), Random Real(-2, 2)); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.abilityPosition, 4); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.abilityPosition, 4); + Damage(Players Within Radius(Event Player.abilityPosition, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 35); + Set Status(Players Within Radius(Event Player.abilityPosition, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Stunned, 0.800); + Wait(0.200, Ignore Condition); + End; + } +} + +rule("Zenyatta: Vigor") +{ + event + { + Player Dealt Healing; + Team 1; + Zenyatta; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Set Status(Healee, Null, Invincible, 1); + Wait(0.800, Ignore Condition); + } +} + +rule("Zenyatta: Perfect Balance") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Start Damage Over Time(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 0.750, 200); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player, 24); + Wait(0.600, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Stench") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Violet), Event Player, 8, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Wait Until(!Event Player.abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Destroy Effect(Event Player.effects_[1]); + } +} + +rule("Roadhog: Stench effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 8; + Event Player.abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 9); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Rusted Anchor") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ability 1(Event Player)), Event Player, 400, + Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Wait Until(!Event Player.abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Stop Damage Modification(Event Player.modificationDamage[1]); + } +} + +rule("Roadhog: Rusted Anchor - Reset cooldown") +{ + event + { + Player Earned Elimination; + Team 1; + Roadhog; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ability 1(Event Player), 3); + Set Ability Cooldown(Event Player, Button(Ability 1), False); + } +} + +rule("Zarya: Augment") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Start Scaling Barriers(Event Player, 2, True); + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5 + 50; + Set Max Health(Event Player, Event Player.playerHealth); + Wait Until(!Event Player.abilities[8] || Hero Of(Event Player) != Hero(Zarya), 99999); + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + Stop Scaling Barriers(Event Player); + } +} + +rule("Zarya: Perpetual Energy") +{ + event + { + Player Dealt Knockback; + Team 1; + Zarya; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Event Player.abilities[12] == True; + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 9999, 15); + Set Status(Victim, Null, Burning, 9999); + } +} + +rule("Doomfist: Phase Shifter") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + (Is Firing Secondary(Event Player) || Is Using Ability 1(Event Player) || Is Using Ability 2(Event Player)) == True; + Event Player.abilities[8] == True; + } + + actions + { + Set Status(Event Player, Null, Phased Out, 1); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ultimate(Event Player), 99999); + Event Player.abilityPosition = Position Of(Event Player); + Event Player.abilityActive = True; + Wait Until(Is Dead(Event Player), 8); + Event Player.abilityActive = False; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Event Player.abilityActive == True; + Event Player.abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player.abilityPosition, 8, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(Orange), Event Player.abilityPosition, 8, Visible To Position and Radius); + Event Player.effects_[2] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player.abilityPosition, 16); + While(Event Player.abilityActive == True); + Damage(Players Within Radius(Event Player.abilityPosition, 8, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 34); + Wait(0.235, Ignore Condition); + End; + Destroy Effect(Event Player.effects_[1]); + Destroy Effect(Event Player.effects_[2]); + } +} + +rule("Team 1 (perk): Sharpshooter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Global.perk[0] == True; + Event Ability != Null; + Distance Between(Event Player, Victim) >= 10; + } + + actions + { + Damage(Victim, Event Player, 50 / Event Player.damageDealt * Event Damage); + } +} + +rule("Team 1 (perk): Bulletstorm") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.perk[1] == True; + (Ammo(Event Player, 0) < Max Ammo(Event Player, 0) || Ammo(Event Player, 1) < Max Ammo(Event Player, 1)) == True; + } + + actions + { + Set Ammo(Event Player, 0, 1000); + Set Ammo(Event Player, 1, 1000); + } +} + +rule("Team 1 Challenges") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + If(Global.perk[2] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.abilityHUD[17] = Last Text ID; + End; + If(Global.perk[0] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.abilityHUD[18] = Last Text ID; + End; + If(Global.perk[1] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.abilityHUD[19] = Last Text ID; + End; + If(Global.maxHealthDone == 50); + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + End; + } +} + +rule("Remove Auto Repair when Player leaves") +{ + event + { + Player Left Match; + Team 1; + All; + } + + actions + { + Global.automaticRepair -= Event Player.abilities[16]; + } +} + +rule("Refund") +{ + event + { + Subroutine; + Refund; + } + + actions + { + "Refund Money" + Event Player.money[0] += Event Player.money[1]; + Event Player.money[1] = 0; + "Reset Headhunter" + Event Player.abilities[1] = 0; + "Reset Ambush" + Event Player.abilities[2] = 0; + "Reset QuickFix" + Event Player.abilities[3] = 0; + "Reset HeavyWeight" + Event Player.abilities[4] = 0; + "Reset Charged" + Event Player.abilities[5] = 0; + "Reset Haste" + Event Player.abilities[6] = 0; + "Reset HeavyImpact" + Event Player.abilities[7] = 0; + "Reset HeroTalent1" + Event Player.abilities[8] = 0; + "Reset SecondWind" + Event Player.abilities[9] = 0; + "Reset BindingHeal" + Event Player.abilities[10] = 0; + "Reset Resilience" + Event Player.abilities[11] = 0; + "Reset HeroTalent2" + Event Player.abilities[12] = 0; + "Reset Damage" + Event Player.abilities[13] = 0; + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.damageDealt); + "Reset Health" + Event Player.abilities[14] = 0; + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + If(Global.maxHealthDone == 0); + End; + "Reset Healing" + Event Player.abilities[15] = 0; + Set Healing Dealt(Event Player, 100 + Event Player.abilities[15] * 5); + "Reset automaticRepair" + Global.automaticRepair -= Event Player.abilities[16]; + Event Player.abilities[16] = 0; + } +} + +rule("Lucio Dash HUD Creation") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + } + + actions + { + If(Event Player.lucioDashActive == False); + Event Player.lucioDashActive = True; + Create HUD Text(Event Player, Null, Null, Custom String("{0} Slam on ground - Press: {1}", Ability Icon String(Hero(Wrecking Ball), + Button(Crouch)), Input Binding String(Button(Crouch))), Left, 1000, Color(White), Color(White), Color(White), + Visible To and String, Default Visibility); + Event Player.lucioDashIcon = Last Text ID; + End; + } +} + +rule("Lucio Dash Remove HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) != Hero(Lúcio); + Event Player.lucioDashActive == True; + } + + actions + { + Destroy HUD Text(Event Player.lucioDashIcon); + Event Player.lucioDashActive = False; + } +} + +rule("Lucio Dash") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + Event Player.lucioDashActive == True; + Is On Ground(Event Player) == False; + Is Button Held(Event Player, Button(Crouch)) == True; + } + + actions + { + Apply Impulse(Event Player, Down, 20, To World, Cancel Contrary Motion); + } +} + +rule("Ana Self-Nano") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + Ultimate Charge Percent(Event Player) == 100; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Abort If(Global.selfNanoWorkshopSetting == False && Number Of Players(Team 1) > 1); + Wait(0.100, Ignore Condition); + If(Is Using Ultimate(Event Player) == False); + Create Dummy Bot(Hero(Ana), Team Of(Event Player), -1, Position Of(Event Player) + Backward, Eye Position(Event Player)); + Event Player.anaEntityID = Last Created Entity; + Wait(0.100, Ignore Condition); + Set Ultimate Charge(Event Player.anaEntityID, 100); + Start Facing(Event Player.anaEntityID, Direction Towards(Eye Position(Event Player.anaEntityID), Position Of(Event Player) + Up), + 1000, To World, Direction and Turn Rate); + Set Invisible(Event Player.anaEntityID, All); + Set Status(Event Player.anaEntityID, Null, Phased Out, 9999); + Wait(0.150, Ignore Condition); + Press Button(Event Player.anaEntityID, Button(Ultimate)); + Set Ultimate Charge(Event Player, 0); + Wait(0.150, Ignore Condition); + Teleport(Event Player.anaEntityID, Position Of(First Of(Spawn Points(Team Of(Event Player))))); + Wait(10, Ignore Condition); + Destroy Dummy Bot(Team Of(Event Player), Slot Of(Event Player.anaEntityID)); + End; + } +} + +rule("Reinhard Charge Cancel") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + } + + actions + { + Wait(0.600, Ignore Condition); + Wait Until(Is Button Held(Event Player, Button(Ability 1)), 5); + Set Status(Event Player, Null, Rooted, 0.001); + Wait Until(Event Player.reinPin, 1); + If(Event Player.reinPin != 0); + Apply Impulse(Event Player.reinPin, Facing Direction Of(Event Player), 15, To World, Cancel Contrary Motion); + End; + } +} + +disabled rule("Map Editor Walls") +{ + event + { + Ongoing - Global; + } +} + +rule("Initial Global") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.allPositions = Empty Array; + Global.allDirections = Empty Array; + Global.firstPosition = Empty Array; + Global.secondPosition = Empty Array; + Global.firstPoint = Empty Array; + Global.secondPoint = Empty Array; + Global.second = Empty Array; + Global.z = Empty Array; + Global.wallId = Empty Array; + Global.beamType = Empty Array; + } +} + +rule("Initial Player") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.filterPosition = 0; + Event Player.lastSavedPosition = 0; + Event Player.closestBodyPosition = 0; + Event Player.fullBodyPosition = 0; + Event Player.previousPositionIntersection = 0; + Event Player.activeWall = Empty Array; + Event Player.closestWall = Empty Array; + } +} + +rule("Collision Logic") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Event Player.lastSavedPosition = (Eye Position(Event Player) + Position Of(Event Player)) / 2; + Wait(0.016, Ignore Condition); + Event Player.closestWall = Filtered Array(Global.allPositions, Distance Between(Global.allPositions[Current Array Index], + Event Player) <= Distance Between(Global.allPositions[Current Array Index], Global.firstPosition[Current Array Index]) + || Event Player.activeWall[Current Array Index] == 1 || (Dot Product(Direction Towards(Current Array Element, + Event Player.lastSavedPosition), Global.allDirections[Current Array Index]) > 0) != (Dot Product(Direction Towards( + Current Array Element, Event Player), Global.allDirections[Current Array Index]) > 0)); + For Player Variable(Event Player, x, 0, Count Of(Event Player.closestWall), 1); + Global.z = Index Of Array Value(Global.allPositions, Event Player.closestWall[Event Player.x]); + If(Global.wallId[Global.z] == 1 || Global.wallId[Global.z] == 3 || Global.wallId[Global.z] == 5); + If(Y Component Of(Global.firstPosition[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.firstPosition[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestBodyPosition = Global.firstPosition[Global.z]; + Else If(Y Component Of(Global.secondPosition[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.secondPosition[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestBodyPosition = Global.secondPosition[Global.z]; + Else; + Event Player.closestBodyPosition = Position Of(Event Player); + End; + Event Player.fullBodyPosition = Vector(X Component Of(Eye Position(Event Player)), Y Component Of( + Event Player.closestBodyPosition), Z Component Of(Eye Position(Event Player))); + Event Player.filterPosition = Event Player.fullBodyPosition + Global.allDirections[Global.z] * Dot Product( + Global.allPositions[Global.z] - Event Player.fullBodyPosition, Global.allDirections[Global.z]) / Dot Product( + Global.allDirections[Global.z], Global.allDirections[Global.z]); + If(Global.wallId[Global.z] == 1 || Global.wallId[Global.z] == 3); + If((Dot Product(Direction Towards(Global.allPositions[Global.z], Event Player.lastSavedPosition), Global.allDirections[Global.z]) + > 0) != (Dot Product(Direction Towards(Global.allPositions[Global.z], Event Player.fullBodyPosition), + Global.allDirections[Global.z]) > 0)); + Event Player.intersectionLength = Dot Product(Global.allPositions[Global.z] - Event Player.fullBodyPosition, + Global.allDirections[Global.z]) / Dot Product(Direction Towards(Event Player.lastSavedPosition, Event Player.fullBodyPosition), + Global.allDirections[Global.z]); + Event Player.previousPositionIntersection = Event Player.fullBodyPosition + Direction Towards(Event Player.lastSavedPosition, + Event Player.fullBodyPosition) * Vector(1, Empty Array, 1) * Event Player.intersectionLength; + If(Dot Product(Direction Towards(Global.firstPosition[Global.z], Vector(X Component Of(Global.secondPosition[Global.z]), + Y Component Of(Global.firstPosition[Global.z]), Z Component Of(Global.secondPosition[Global.z]))), Direction Towards( + Global.firstPosition[Global.z], Event Player.previousPositionIntersection)) >= 0 && Dot Product(Direction Towards( + Global.firstPosition[Global.z], Vector(X Component Of(Global.firstPosition[Global.z]), Y Component Of( + Global.secondPosition[Global.z]), Z Component Of(Global.firstPosition[Global.z]))), Direction Towards( + Global.firstPosition[Global.z], Event Player.previousPositionIntersection)) >= 0 && Dot Product(Direction Towards( + Global.secondPosition[Global.z], Vector(X Component Of(Global.secondPosition[Global.z]), Y Component Of( + Global.firstPosition[Global.z]), Z Component Of(Global.secondPosition[Global.z]))), Direction Towards( + Global.secondPosition[Global.z], Event Player.previousPositionIntersection)) >= 0 && Dot Product(Direction Towards( + Global.secondPosition[Global.z], Vector(X Component Of(Global.firstPosition[Global.z]), Y Component Of( + Global.secondPosition[Global.z]), Z Component Of(Global.firstPosition[Global.z]))), Direction Towards( + Global.secondPosition[Global.z], Event Player.previousPositionIntersection)) >= 0); + Cancel Primary Action(Event Player); + Teleport(Event Player, Event Player.previousPositionIntersection + Direction Towards(Event Player.previousPositionIntersection, + Event Player.lastSavedPosition) * Vector(1, Empty Array, 1) * 2); + End; + End; + End; + Event Player.thickness = 0; + If(Global.wallId[Global.z] == 5); + Event Player.thickness = 4; + Else; + Event Player.thickness = 1; + End; + If(Distance Between(Event Player.fullBodyPosition, Event Player.filterPosition) <= Event Player.thickness && Dot Product( + Direction Towards(Global.firstPosition[Global.z], Vector(X Component Of(Global.secondPosition[Global.z]), Y Component Of( + Global.firstPosition[Global.z]), Z Component Of(Global.secondPosition[Global.z]))), Direction Towards( + Global.firstPosition[Global.z], Event Player.filterPosition)) >= 0 && Dot Product(Direction Towards( + Global.firstPosition[Global.z], Vector(X Component Of(Global.firstPosition[Global.z]), Y Component Of( + Global.secondPosition[Global.z]), Z Component Of(Global.firstPosition[Global.z]))), Direction Towards( + Global.firstPosition[Global.z], Event Player.filterPosition)) >= 0 && Dot Product(Direction Towards( + Global.secondPosition[Global.z], Vector(X Component Of(Global.secondPosition[Global.z]), Y Component Of( + Global.firstPosition[Global.z]), Z Component Of(Global.secondPosition[Global.z]))), Direction Towards( + Global.secondPosition[Global.z], Event Player.filterPosition)) >= 0 && Dot Product(Direction Towards( + Global.secondPosition[Global.z], Vector(X Component Of(Global.firstPosition[Global.z]), Y Component Of( + Global.secondPosition[Global.z]), Z Component Of(Global.firstPosition[Global.z]))), Direction Towards( + Global.secondPosition[Global.z], Event Player.filterPosition)) >= 0); + If(!Global.isGrounded); + Set Gravity(Event Player, 100); + End; + If(Event Player.activeWall[Global.z] == False); + Event Player.activeWall[Global.z] = 1; + If((Global.wallId[Global.z] == 1 || Global.wallId[Global.z] == 3) && Global.isGrounded == False); + Set Gravity(Event Player, 100); + Else If(Global.wallId[Global.z] == 5); + Disable Movement Collision With Environment(Event Player, False); + End; + End; + If(Global.wallId[Global.z] == 1); + Apply Impulse(Event Player, Direction Towards(Event Player.filterPosition, Event Player.fullBodyPosition) * Vector(1, Empty Array, + 1), 0.001, To World, Cancel Contrary Motion); + Set Move Speed(Event Player, 100 - Dot Product(Direction Towards(Eye Position(Event Player), Eye Position(Event Player) + + World Vector Of(Throttle Of(Event Player), Event Player, Rotation)), Direction Towards(Event Player.filterPosition, + Event Player.fullBodyPosition) * -1) * 100); + Else If(Global.wallId[Global.z] == 3); + Apply Impulse(Event Player, Direction Towards(Event Player.filterPosition, Event Player.fullBodyPosition), Speed Of(Event Player), + To World, Cancel Contrary Motion); + End; + Else; + Event Player.activeWall[Global.z] = 0; + Set Move Speed(Event Player, 100); + End; + End; + End; + Loop; + } +} + +rule("Reset") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Count Of(Filtered Array(Event Player.activeWall, Current Array Element != 0)) == 0; + } + + actions + { + Enable Movement Collision With Environment(Event Player); + } +} + +rule("Wall Data") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.allPositions = Array(Vector(155.968, 12.470, -30.507), Vector(155.962, 12.472, -62.500), Vector(81.153, 6.453, -103.851), + Vector(69.148, 6.474, -104.548)); + Global.allDirections = Array(Vector(-1, 0, -0.002), Vector(1, 0, -0.001), Vector(0, 0, 1), Vector(0.001, 0, 1)); + Global.firstPosition = Array(Vector(155.971, 11.047, -31.771), Vector(155.964, 11.050, -61.229), Vector(79.761, 5.030, -103.852), + Vector(67.738, 5.022, -104.547)); + Global.secondPosition = Array(Vector(155.965, 13.894, -29.242), Vector(155.960, 13.894, -63.771), Vector(82.544, 7.876, -103.851), + Vector(70.558, 7.925, -104.550)); + Global.firstPoint = Array(Vector(155.971, 13.894, -31.771), Vector(155.964, 13.894, -61.229), Vector(79.761, 7.876, -103.852), + Vector(67.738, 7.925, -104.547)); + Global.secondPoint = Array(Vector(155.965, 11.047, -29.242), Vector(155.960, 11.050, -63.771), Vector(82.544, 5.030, -103.851), + Vector(70.558, 5.022, -104.550)); + Global.z = 3; + Global.beamType = Array(1, 1, 1, 1); + Global.showWalls = True; + Global.wallId = Array(5, 5, 5, 5); + } +} + +disabled rule("NEW SHOP") +{ + event + { + Ongoing - Global; + } +} + +rule("Setting Shop Position") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.shopCamPosition = 900 * Up; + Global.shopPositionAngle[1] = Direction From Angles(Horizontal Angle From Direction(Forward), Vertical Angle From Direction( + Forward) - 90); + Global.shopPositionAngle[0] = Cross Product(Global.shopPositionAngle[1], Forward); + Global.shopBasePosition = Global.shopCamPosition - 9 * Global.shopPositionAngle[1] + 142 * Forward; + } +} + +rule("Create Shop Buttons") +{ + event + { + Ongoing - Global; + } + + actions + { + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), + Global.shopBasePosition - 41 * Global.shopPositionAngle[1] + 90 * Global.shopPositionAngle[0], 2.500, Do Not Clip, Visible To, + Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), + Global.shopBasePosition - 41 * Global.shopPositionAngle[1] - 90 * Global.shopPositionAngle[0], 2.500, Do Not Clip, Visible To, + Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Refund"), + Global.shopBasePosition + 45 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 3, Do Not Clip, Visible To, + Color(Green), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("[{0}] Leave", + Input Binding String(Button(Reload))), + Global.shopBasePosition + 45 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 3, Do Not Clip, + Visible To and String, Color(Green), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("{0}$\n", Local Player.money[0]), + Global.shopBasePosition + 36.500 * Global.shopPositionAngle[1], 3, Do Not Clip, Visible To and String, Color(White), + Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("▲"), Update Every Frame( + Global.shopBasePosition - (4 + Vertical Facing Angle Of(Local Player)) + * Global.shopPositionAngle[1] + Horizontal Facing Angle Of(Local Player) * Global.shopPositionAngle[0]), 4, Do Not Clip, + Visible To Position and Color, Custom Color(245 + 10 * Sine From Radians(4 * Total Time Elapsed), 205 + 50 * Sine From Radians( + 4 * Total Time Elapsed), 200 * Sine From Radians(4 * Total Time Elapsed), 255), Default Visibility); + "Headhunter" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[1] ? Custom String("Headhunter II\n  800$") : Custom String("Headhunter I\n  800$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[1] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Ambush" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[2] ? Custom String("Ambush II\n 800$") : Custom String("Ambush I\n 800$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[2] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Quick Fix" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[3] ? Custom String("Quick Fix II\n  700$") : Custom String("Quick Fix I\n  700$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[3] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavyweight" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[4] ? Custom String("Heavyweight II\n  1000$") : Custom String("Heavyweight I\n  1000$"), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[4] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Charged" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[5] ? Custom String("Charged II\n  700$") : Custom String("Charged I\n  700$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[5] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Haste" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[6] ? Custom String("Haste II\n 700$") : Custom String("Haste I\n 700$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[6] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavy Impact" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[7] ? Custom String("Heavy Impact II\n  1000$") : Custom String("Heavy Impact I\n  1000$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[7] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 1" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 1\n  1200$"), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[8] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "Second Wind" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[9] ? Custom String("Second Wind II\n   900$") : Custom String("Second Wind I\n   900$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[9] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Binding Heal" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[10] ? Custom String("Binding Heal II\n   700$") : Custom String("Binding Heal I\n   700$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[10] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Resilience" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[11] ? Custom String("Resilience II\n  800$") : Custom String("Resilience I\n  800$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[11] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 2" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 2\n  1200$"), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[12] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "PlusDamage" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Damage\n  400$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealth" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Health\n 400$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Healing\n  400$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To and String, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "+{0} Auto-Repair\n    400$", Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Global.automaticRepair < 5 ? Color(Green) : Color(Gray), Default Visibility); + "Use Update Every Frame to avoid showing the String when the cursor is out of bounds, resulting in 0\r\n ROW 0" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -33.750 ? Array(Custom String("Leave Buy Menu\n"), Custom String( + ""), Custom String(""), Custom String("Refund your money\n"))[Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) + / 45, Down)] : Custom String("")), Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, + Visible To and String, Color(White), Default Visibility); + "ROW 1" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 22.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -11.250 ? Array(Custom String("Increase your damage by 5%\n"), + Local Player.abilities[9] ? Custom String( + "Second Wind II: 60% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds") + : Custom String( + "Second Wind I: 30% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds"), + Local Player.abilities[5] ? Custom String("Charged II: Ultimates cost 40% less\n") : Custom String( + "Charged I: Ultimates cost 20% less\n"), Local Player.abilities[1] ? Custom String( + "Headhunter II: Critical hits deal 80% more damage\n") : Custom String("Headhunter I: Critical hits deal 40% more damage\n")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), + Default Visibility); + "ROW 2" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 36.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 11.250 ? Array(Custom String("Increase your health by 5%\n"), + Local Player.abilities[10] ? Custom String("Binding Heal II: Heal yourself for 50% the amount when healing allies\n") + : Custom String("Binding Heal I: Heal yourself for 25% the amount when healing allies\n"), + Local Player.abilities[6] ? Custom String( + " Haste II: Ability cooldown is reduced by 50%\nDoes not affect abilities with multiple charges") : Custom String( + " Haste I: Ability cooldown is reduced by 25%\nDoes not affect abilities with multiple charges"), + Local Player.abilities[2] ? Custom String("Ambush II: Deal 60% more damage when attacking enemies from behind or above\n") + : Custom String("Ambush I: Deal 30% more damage when attacking enemies from behind or above\n"))[Round To Integer(( + Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), + Default Visibility); + "ROW 3" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 83.750) < 72.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 33.750 ? Array(Custom String("Increase your healing by 5%\n"), + Local Player.abilities[11] ? Custom String("Resilience II: Take 30% less damage while below 60% health\n") : Custom String( + "Resilience I: Take 30% less damage while below 30% health\n"), Local Player.abilities[7] ? Custom String( + "Heavy Impact II: Every hit has a chance to stun the enemy for 2 seconds\n") : Custom String( + "Heavy Impact I: Every hit has a chance to stun the enemy for 1 second\n"), Local Player.abilities[3] ? Custom String( + "Quick Fix II: Eliminations restore 100 HP and shortly increase speed by 40%\n") : Custom String( + "Quick Fix I: Eliminations restore 50 HP and shortly increase speed by 20%\n"))[Round To Integer((Horizontal Facing Angle Of( + Local Player) + 90) / 45, Down)] : Custom String("")), Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, + Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 4" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 133) < 99.250 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 56.250 ? Array(Custom String( + "Increase your auto-repair by {0}/5s\n", Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Custom String("{0}", Local Player.heroTalentText[2][1]), Custom String("{0}", Local Player.heroTalentText[1][1]), + Local Player.abilities[4] ? Custom String( + "Heavyweight II: Your knock back attacks deal 50% more damage and knock back\n            You receive 33% less knock back") + : Custom String( + "Heavyweight I: Your knock back attacks deal 25% more damage and knock back\n            You receive 20% less knock back")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), + Default Visibility); + } +} + +rule("Toggle Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + !Is Dummy Bot(Event Player) == True; + Is Button Held(Event Player, Button(Reload)) == True; + !Is Communicating Any Emote(Event Player) == True; + } + + actions + { + If(Event Player.isInMenu == False); + Wait Until(!Is Button Held(Event Player, Button(Reload)), 0.500); + If(!Is Button Held(Event Player, Button(Reload))); + Abort; + End; + End; + Event Player.isInMenu = !Event Player.isInMenu; + } +} + +rule("Open Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == True; + } + + actions + { + Event Player.playerFacing = Facing Direction Of(Event Player); + Start Camera(Event Player, Global.shopCamPosition, Global.shopCamPosition + Forward, 0); + Disable Hero HUD(Event Player); + Call Subroutine(DisablePlayer); + Set Aim Speed(Event Player, 200); + } +} + +rule("Close Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == False; + } + + actions + { + Stop Camera(Event Player); + Enable Hero HUD(Event Player); + Call Subroutine(EnablePlayer); + Set Aim Speed(Event Player, 100); + Set Facing(Event Player, Event Player.playerFacing, To World); + } +} + +rule("Subroutine: Disable Player") +{ + event + { + Subroutine; + DisablePlayer; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + Set Primary Fire Enabled(Event Player, False); + Set Secondary Fire Enabled(Event Player, False); + Set Ability 1 Enabled(Event Player, False); + Set Ability 2 Enabled(Event Player, False); + Set Melee Enabled(Event Player, False); + Set Jump Enabled(Event Player, False); + Set Crouch Enabled(Event Player, False); + Disallow Button(Event Player, Button(Ultimate)); + } +} + +rule("Subroutine: Enable Player") +{ + event + { + Subroutine; + EnablePlayer; + } + + actions + { + Stop Forcing Throttle(Event Player); + Set Primary Fire Enabled(Event Player, True); + Set Secondary Fire Enabled(Event Player, True); + Set Ability 1 Enabled(Event Player, True); + Set Ability 2 Enabled(Event Player, True); + Set Melee Enabled(Event Player, True); + Set Jump Enabled(Event Player, True); + Set Crouch Enabled(Event Player, True); + Allow Button(Event Player, Button(Ultimate)); + } +} + +rule("Buy Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Primary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + Event Player.isInMenu = !Event Player.isInMenu; + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.money[1] != 0); + Call Subroutine(Refund); + Else; + Small Message(Local Player, Custom String("You don't have anything to refund!")); + End; + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Event Player.abilities[13] += 1; + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.damageDealt); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[9] != 2); + If(Event Player.money[0] >= 900); + Event Player.money[0] -= 900; + Event Player.money[1] += 900; + Event Player.abilities[9] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[5] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[5] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[1] != 2); + If(Event Player.money[0] >= 800); + Event Player.money[0] -= 800; + Event Player.money[1] += 800; + Event Player.abilities[1] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Event Player.abilities[14] += 1; + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[10] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[10] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[6] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[6] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[2] != 2); + If(Event Player.money[0] >= 800); + Event Player.money[0] -= 800; + Event Player.money[1] += 800; + Event Player.abilities[2] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Event Player.abilities[15] += 1; + Set Healing Dealt(Event Player, 100 + Event Player.abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[11] != 2); + If(Event Player.money[0] >= 800); + Event Player.money[0] -= 800; + Event Player.money[1] += 800; + Event Player.abilities[11] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[7] != 2); + If(Event Player.money[0] >= 1000); + Event Player.money[0] -= 1000; + Event Player.money[1] += 1000; + Event Player.abilities[7] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[3] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[3] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Global.automaticRepair != 5); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Global.automaticRepair += 1; + Event Player.abilities[16] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[12] != 1); + If(Event Player.money[0] >= 1200); + Event Player.money[0] -= 1200; + Event Player.money[1] += 1200; + Event Player.abilities[12] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[8] != 1); + If(Event Player.money[0] >= 1200); + Event Player.money[0] -= 1200; + Event Player.money[1] += 1200; + Event Player.abilities[8] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[4] != 2); + If(Event Player.money[0] >= 1000); + Event Player.money[0] -= 1000; + Event Player.money[1] += 1000; + Event Player.abilities[4] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + End; + } +} + +rule("Refund Single Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Secondary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[13] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Event Player.abilities[13] -= 1; + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.damageDealt); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[9] != 0); + Event Player.money[0] += 900; + Event Player.money[1] -= 900; + Event Player.abilities[9] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[5] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[5] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[1] != 0); + Event Player.money[0] += 800; + Event Player.money[1] -= 800; + Event Player.abilities[1] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[14] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Event Player.abilities[14] -= 1; + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[10] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[10] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[6] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[6] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[2] != 0); + Event Player.money[0] += 800; + Event Player.money[1] -= 800; + Event Player.abilities[2] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[15] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Event Player.abilities[15] -= 1; + Set Healing Dealt(Event Player, 100 + Event Player.abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[11] != 0); + Event Player.money[0] += 800; + Event Player.money[1] -= 800; + Event Player.abilities[11] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[7] != 0); + Event Player.money[0] += 1000; + Event Player.money[1] -= 1000; + Event Player.abilities[7] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[3] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[3] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[16] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Global.automaticRepair -= 1; + Event Player.abilities[16] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[12] != 0); + Event Player.money[0] += 1200; + Event Player.money[1] -= 1200; + Event Player.abilities[12] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[8] != 0); + Event Player.money[0] += 1200; + Event Player.money[1] -= 1200; + Event Player.abilities[8] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[4] != 0); + Event Player.money[0] += 1000; + Event Player.money[1] -= 1000; + Event Player.abilities[4] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + End; + } +} + +rule("Create Player HUD") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Custom String("{0}{1}", + Event Player, Event Player.isInMenu ? Custom String("(In Shop)") : Custom String("")), Custom String("{0}{1}", Is Alive( + Event Player) ? Custom String("{0} HP", Round To Integer(Health(Event Player), Up)) : Custom String("Dead"), Custom String( + ", {0}$", Event Player.money)), Left, Local Player == Event Player ? -1 : Slot Of(Event Player), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), + Visible To Sort Order String and Color, Default Visibility); + Create HUD Text(Event Player.abilities[13] || Global.damageDealt ? Event Player : Null, Null, Null, Custom String("+{0}% Damage", + Global.damageDealt + Event Player.abilities[13] * 5), Left, 913, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[9] ? Event Player : Null, Null, Null, Custom String("Second Wind {0}", + Event Player.abilities[9] == 1 ? Custom String("I") : Custom String("II")), Left, 908, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[5] ? Event Player : Null, Null, Null, Custom String("Charged {0}", + Event Player.abilities[5] == 1 ? Custom String("I") : Custom String("II")), Left, 905, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[1] ? Event Player : Null, Null, Null, Custom String("Headhunter {0}", + Event Player.abilities[1] == 1 ? Custom String("I") : Custom String("II")), Left, 901, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[14] || Global.maxHealthDone ? Event Player : Null, Null, Null, Custom String("+{0}% Health", + Global.maxHealthDone + Event Player.abilities[14] * 5), Left, 914, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[10] ? Event Player : Null, Null, Null, Custom String("Binding Heal {0}", + Event Player.abilities[10] == 1 ? Custom String("I") : Custom String("II")), Left, 909, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[6] ? Event Player : Null, Null, Null, Custom String("Haste {0}", + Event Player.abilities[6] == 1 ? Custom String("I") : Custom String("II")), Left, 906, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[2] ? Event Player : Null, Null, Null, Custom String("Ambush {0}", + Event Player.abilities[2] == 1 ? Custom String("I") : Custom String("II")), Left, 902, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[15] ? Event Player : Null, Null, Null, Custom String("+{0}% Healing", + Event Player.abilities[15] * 5), Left, 915, Color(White), Color(White), Color(Turquoise), Visible To and String, + Default Visibility); + Create HUD Text(Event Player.abilities[11] ? Event Player : Null, Null, Null, Custom String("Resilience {0}", + Event Player.abilities[11] == 1 ? Custom String("I") : Custom String("II")), Left, 910, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[7] ? Event Player : Null, Null, Null, Custom String("Heavy Impact {0}", + Event Player.abilities[7] == 1 ? Custom String("I") : Custom String("II")), Left, 907, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[3] ? Event Player : Null, Null, Null, Custom String("Quick Fix {0}", + Event Player.abilities[3] == 1 ? Custom String("I") : Custom String("II")), Left, 903, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Global.automaticRepair ? Event Player : Null, Null, Null, Custom String("{0} total Auto-Repair/5s", + Global.automaticRepair * (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 10 : 5)), Left, 916, + Color(White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[12] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.heroTalentText[2][0], Event Player.heroTalentText[2][1]), Top, 902, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[12] ? Event Player : Null, Null, Null, Custom String("Hero Talent 2"), Left, 912, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[8] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.heroTalentText[1][0], Event Player.heroTalentText[1][1]), Top, 901, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[8] ? Event Player : Null, Null, Null, Custom String("Hero Talent 1"), Left, 911, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[4] ? Event Player : Null, Null, Null, Custom String("Heavyweight {0}", + Event Player.abilities[4] == 1 ? Custom String("I") : Custom String("II")), Left, 904, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + } +} + +rule("Rein Pin detect") +{ + event + { + Player Dealt Knockback; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 1); + Has Status(Victim, Stunned) == True; + } + + actions + { + Event Player.reinPin = Victim; + Wait(1, Ignore Condition); + Event Player.reinPin = Null; + } +} + +rule("Boss Rotation") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.activeBoss == True; + } + + actions + { + If(Global.bossRotation == 0 || Global.bossRotation == 3); + Global.bossRotation = 1; + Global.lastBoss[1] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 1); + Global.bossRotation = 2; + Global.lastBoss[2] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 2); + Global.bossRotation = 3; + Global.lastBoss[3] = Hero Of(Global.activeBoss); + End; + } +} + +rule("BOSS HUD") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 10; + } + + actions + { + Create HUD Text(All Players(Team 1), Global.activeBoss ? Custom String("Boss: {0}, HP: {1}/{2}", Hero Of(Global.activeBoss), + Health(Global.activeBoss), Max Health(Global.activeBoss)) : Custom String(""), Null, Null, Top, 900, Color(Red), Color(White), + Color(White), Visible To and String, Default Visibility); + } +} + +rule("DEBUG - SKIP TIME") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.isDebug == True; + (Is Button Held(Event Player, Button(Primary Fire)) && Is Button Held(Event Player, Button(Crouch))) == True; + } + + actions + { + Global.timeSeconds = 59; + } +} + +disabled rule("DEBUG COLLECTION - Make Invincible, Show Player Coords") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.isDebug == True; + } + + actions + { + Create HUD Text(Local Player, Custom String("{0}", Position Of(Local Player)), Null, Null, Left, 0, Color(Yellow), Color(White), + Color(White), Visible To and String, Default Visibility); + Set Status(Event Player, Null, Invincible, 9999); + Set Status(Event Player, Null, Phased Out, 9999); + } +} + +rule("OPTIONAL ENDING - CREATE EXFIL POINT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("Exfiltration available! (optional - ends the mode)"), Null, Null, Top, 50, + Color(Red), Color(White), Color(White), Visible To and String, Default Visibility); + Global.globalHUDs[1] = Last Text ID; + Create In-World Text(All Players(Team 1), Custom String( + "Exfiltration available! Gather here!\n{0}/{1} Players ready to exfiltrate!", Count Of(Filtered Array(All Players(Team 1), + Distance Between(Vector(186, 11, -46.500), Current Array Element) <= 9)), Count Of(All Players(Team 1))), Vector(186, 15, + -46.500), 1.200, Do Not Clip, Visible To and String, Color(Green), Default Visibility); + Wait(3, Ignore Condition); + Destroy HUD Text(Global.globalHUDs[1]); + } +} + +rule("OPTIONAL ENDING - EXFIL PLAYERS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + Count Of(Filtered Array(All Players(Team 1), Distance Between(Vector(186, 11, -46.500), All Players(Team 1)) <= 9)) >= Count Of( + All Players(Team 1)) / 2; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GG! YOU DID IT!")); + Destroy All Dummy Bots; + Disable Movement Collision With Environment(All Players(Team 1), True); + Start Accelerating(All Players(Team 1), Up, 100, 5, To World, Direction Rate and Max Speed); + Wait(5, Ignore Condition); + Declare Team Victory(Team 1); + } +} + +rule("Team 1 (Ability): Second Wind save life") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + conditions + { + Event Player.abilities[9] == True; + Event Player.secondWindActive == True; + Health(Event Player) == 1; + } + + actions + { + Small Message(All Players(All Teams), Custom String("{0} received a second wind!", Event Player)); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Green), Event Player, 1); + Clear Status(Event Player, Unkillable); + Set Player Health(Event Player, Max Health(Event Player)); + Event Player.lastSecondWind = 30; + Event Player.secondWindActive = 0; + } +} + +rule("Team 1 (Ability): Second Wind after buying") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[9] == True; + Event Player.secondWindActive == False; + Event Player.lastSecondWind == 0; + } + + actions + { + If(Random Integer(1, 100) > Event Player.abilities[9] * 30); + Wait(30, Ignore Condition); + Loop; + End; + Set Status(Event Player, Null, Unkillable, 9999); + Event Player.secondWindActive = 1; + } +} + +rule("Team 1 (Ability): Second Wind counter") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Player.lastSecondWind > 0; + } + + actions + { + Wait(1, Ignore Condition); + Event Player.lastSecondWind -= 1; + Loop If Condition Is True; + } +} + +rule("Team 1: Change Hero") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Distance Between(Vector(159, 11, -46.500), Event Player) <= 2; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + Set Player Allowed Heroes(Event Player, Hero(Pharah)); + Set Player Allowed Heroes(Event Player, Hero(Ana)); + If(Global.isStoryHeroes); + Reset Player Hero Availability(Event Player); + Set Player Allowed Heroes(Event Player, Array(Hero(Ana), Hero(Brigitte), Hero(Mercy), Hero(Lúcio), Hero(Moira), Hero(Baptiste), + Hero(Ashe), Hero(D.Va), Hero(Genji), Hero(Hanzo), Hero(Widowmaker), Hero(Cassidy), Hero(Reinhardt), Hero(Soldier: 76), Hero( + Torbjörn), Hero(Tracer), Hero(Winston), Hero(Pharah))); + Else; + Reset Player Hero Availability(Event Player); + End; + Wait(0.500, Ignore Condition); + Wait Until(Has Spawned(Event Player), 99999); + Teleport(Event Player, Vector(159, 11, -46.500)); + } +} \ No newline at end of file diff --git a/defendTheCastleExtended/old_versions/c131.ow b/defendTheCastleExtended/old_versions/c131.ow new file mode 100644 index 0000000..3e54984 --- /dev/null +++ b/defendTheCastleExtended/old_versions/c131.ow @@ -0,0 +1,8676 @@ +settings +{ + main + { + Description: "Defend The Castle Extended Version c131\nby ShuriZma#2349\nJ1K6F (Code Version: c131)\nOriginal mode by HuKuTa94#2589\n\nDefend the gate, kill enemies and don't allow them to damage the gate!\n\nSpecial Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents\n& Josbird for teaching me about Menus!\n\nFind this mode on: workshop.codes/defend-the-castle\nFind the Original Mode on: workshop.codes/BQEGS\nTell me what you think on Discord: discord.shurizma.de\n\nPS: SHINGEN PLS COME BACK" + Mode Name: "Defend The Castle Extended" + } + + lobby + { + Max Spectators: 0 + Max Team 1 Players: 4 + Max Team 2 Players: 0 + Return To Lobby: Never + Swap Teams After Match: No + } + + modes + { + Escort + { + enabled maps + { + Havana + } + } + + Team Deathmatch + { + enabled maps + { + } + } + + General + { + Game Mode Start: Immediately + Spawn Health Packs: Disabled + } + } + + extensions + { + Beam Effects + Kinetic Explosion Effects + Energy Explosion Effects + Explosion Sounds + Play More Effects + Spawn More Dummy Bots + } +} + +variables +{ + global: + 0: gatePosition + 1: zenSpawnPositions + 2: spawnPositionMaxId + 3: loopIterator1 + 4: bigBossSpawnPositions + 5: playerSpawnPositions + 6: gateHealthChase + 7: gateHealth + 8: gateMaxHealth + 9: gateProgressBarColorCurrent + 10: gateProgressBarColorComponent + 11: gateHealthEvent + 12: bastionTargetPositions + 13: sniperPositions + 14: ballSpawnPositions + 15: zenRespawnTime + 16: timeSeconds + 17: timeMinutes + 18: defaultCurrentBot + 19: defaultHeroBotsPool + 20: defaultHeroBotsPoolCurrentId + 21: isDebug + 22: botOrisaParent + 24: botOrisaChild + 25: gateRepairPosition + 26: botOrisaTargetPosition + 27: botEchoRespawnPosition + 28: botEchoTeleportPositions + 29: upgradeGateMaxHealthValue + 30: upgradeGateMaxHealthHudId + 31: upgradePlayerMaxHealthValue + 32: upgradePlayerMaxHealthHudId + 33: upgradeCriticalDamageValue + 34: upgradeCriticalDamageHudId + 35: upgradeMaxAmmoValue + 36: upgradeMaxAmmoHudId + 37: upgradeMaxAmmoMaxValue + 38: upgradePlayerMaxHealthMaxValue + 39: upgradeCriticalDamageMaxValue + 40: upgradeGateMaxHealthMaxValue + 41: damageDealt + 42: isDebugAINavigation + 43: gameLogicCountOfUniqueHeroes + 44: isNewWaveGameLogicProcessing + 45: automaticRepair + 46: upgradePerkSharpshooterValue + 47: perk + 48: maxHealthDone + 49: startMoney + 50: time5Minutes + 51: selfNanoWorkshopSetting + 52: shopCamPosition + 53: shopBasePosition + 54: shopPositionAngle + 55: activeBoss + 56: bossTrigger + 57: bossRotation + 58: lastBoss + 59: time10Minutes + 60: moneyMultiplier + 61: challengeCount + 62: upgradeBossHealthValue + 63: globalHUDs + 112: allPositions + 113: allDirections + 114: firstPosition + 115: secondPosition + 116: firstPoint + 117: secondPoint + 118: second + 119: z + 120: wallId + 121: showWalls + 122: isGrounded + 123: beamType + 125: nodePositions + 126: nodeConnections + 127: distanceMatrix + + player: + 0: botSeePlayer + 1: botDoesUniqueBehaviour + 2: botEffects + 3: botRayCastHitPosition + 4: botEventPosition + 5: currentHero + 6: isDead + 7: isRespawning + 8: botBastionArtilleryDidShotsCount + 9: botCounter + 10: hasBadStatus + 11: eventHealth + 12: healOverTimeId + 13: botIsOrisaChild + 14: botEchoCapturedPlayer + 15: botPlayersInRadius + 16: botLoopIterator2 + 17: botWidowShotTime + 18: botWidowTeleportTime + 19: isNanoed + 20: abilityHUD + 21: lucioDashActive + 22: lucioDashIcon + 23: anaEntityID + 24: abilities + 25: money + 26: heroTalentText + 27: damageDealt + 28: playerHealth + 29: abilityCountdown + 30: hpPool + 31: effects_ + 32: abilityProjectile1 + 33: abilityEnd + 34: stormProjectile + 35: stormEndPoint + 36: stormEffects + 37: fearedUntil + 38: modificationDamage + 39: abilityProjectile2 + 40: abilityPosition + 41: chainReactionOn + 42: chainReactionImmune + 43: abilityActive + 44: abilityResource + 45: secondWindActive + 46: isInMenu + 47: reinPin + 48: playerFacing + 49: isBoss + 50: genDirection + 51: genAvailable + 52: abilityPlayer + 53: deathPosition + 54: lastSecondWind + 105: filterPosition + 106: lastSavedPosition + 107: closestBodyPosition + 108: fullBodyPosition + 109: previousPositionIntersection + 110: activeWall + 111: closestWall + 112: x + 113: intersectionLength + 114: thickness + 115: botCancelPathFinding + 116: botLoopIterator1 + 117: botTempArray + 118: botTargetPlayer + 119: botTargetPosition + 120: botClosestNodeIdToTarget + 121: botClosestNodeIdToBot + 122: botPreviousNodeId + 123: botNextNodeId + 124: botNextNodePosition + 125: botCurrentDistanceToTarget + 126: botShortestDistanceToTarget + 127: botIsPathFinding +} + +subroutines +{ + 0: BotBastionArtilleryDamage + 1: BotBastionFlameGunDamage + 2: BotBastionRespawn + 3: GateProgressBarColor + 4: BotZenyattaRespawn + 5: BotWidowRespawn + 6: BotBallRespawn + 7: GameLogicAddNextHeroInGame + 8: BotOrisaRespawn + 9: BotLandingFromSky + 10: BotEchoRespawn + 11: BotEchoDetachPlayer + 12: BotEchoFlyToPlayer + 13: BotEchoFlyToPortal + 14: GameLogicSetBotProperties + 15: DisablePlayer + 16: BotAppearFromUnderground + 17: BotReinRespawn + 18: PlayerInit + 19: BotInit + 20: PlayerRespawn + 21: BotRespawn + 22: BotWidowBadStatus + 23: GameLogicWave0 + 24: Refund + 25: EnablePlayer + 26: GateRepair + 124: BotStartPathFinding + 125: BotGetClosestNodeIdToTarget + 126: BotGetNextNodeIdAndPosition + 127: BotResetPathFinding +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("MAP: HAVANA") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Havana); + } + + actions + { + Global.nodePositions = Array(Vector(147.588, 6.425, -46.749), Vector(136.181, 6.425, -57.159), Vector(130.189, 6.425, -63.781), + Vector(123.305, 6.425, -57.983), Vector(125.678, 6.504, -46.633), Vector(114.485, 7.471, -46.699), Vector(138.743, 6.425, + -32.974), Vector(126.498, 6.425, -39.920), Vector(124.572, 10.434, -34.300), Vector(138.605, 5.359, -18.647), Vector(119.009, + 2.331, -31.024), Vector(121.138, 5.228, -19.933), Vector(126.722, 6.425, -29.505), Vector(102.762, 3.157, -33.609), Vector( + 76.030, 7.418, -74.087), Vector(83.720, 9.425, -33.744), Vector(97.439, 7.238, -42.379), Vector(86.252, 12.416, -47.261), + Vector(65.178, 11.425, -73.187), Vector(97.466, 7.269, -50.596), Vector(113.039, 7.424, -37.337), Vector(106.179, 7.450, + -46.143), Vector(90.086, 7.411, -44.653), Vector(78.752, 7.418, -62.140), Vector(82.124, 7.428, -44.229), Vector(90.675, 7.231, + -51.234), Vector(85.717, 4.692, -63.446), Vector(90.830, 4.330, -70.697), Vector(102.425, 2.387, -72.817), Vector(81.443, + 4.425, -81.648), Vector(70.743, 6.418, -81.495), Vector(69.738, 6.419, -96.344), Vector(127.586, 12.643, -63.344), Vector( + 118.911, 13.468, -58.008), Vector(102.885, 1.092, -56.579), Vector(100.009, 2.967, -67.139), Vector(106.703, 0.465, -44.628), + Vector(81.695, 7.418, -52.140), Vector(126.979, 12.393, -55.079), Vector(153.720, 18.578, -21.745), Vector(155.301, 18.619, + -17.595), Vector(133.043, 10.425, -26.625), Vector(114.646, 7.278, -57.336), Vector(95.160, 3.688, -81.194), Vector(78.456, + 5.418, -93.581), Vector(75.455, 5.418, -101.492), Vector(148.071, 9.432, -32.123), Vector(146.706, 9.425, -27.858), Vector( + 144.273, 9.445, -63.119), Vector(144.278, 9.454, -58.447)); + Global.nodeConnections = Array(Array(1, 6, 4, 7), Array(2, 1, 4, 6, 7, 0, 49), Array(1, 3), Array(2, 4, 42), Array(3, 1, 5, 7, 6, + 1, 0), Array(4, 7, 20, 21, 19, 16, 42), Array(7, 1, 4, 1, 9, 12, 0, 46), Array(4, 5, 6, 1, 1, 12, 0), Array(7, 41), Array(6, + 11), Array(11, 13), Array(9, 10, 13), Array(6, 7, 10), Array(10, 16, 36), Array(18, 23, 30), Array(17, 24), Array(13, 19, 22, + 21, 25, 5), Array(15, 22, 25, 23), Array(14), Array(16, 21, 22, 26, 27, 35, 25, 5), Array(5, 13, 10), Array(19, 16, 5, 13, 22, + 34), Array(16, 19, 21, 24, 25), Array(14, 25, 26, 37), Array(22, 15, 37), Array(23, 22, 19, 16, 26, 27, 35, 37), Array(25, 19, + 27, 35, 29), Array(19, 26, 25, 29, 35, 43), Array(35, 34, 43), Array(27, 26, 30, 43, 44), Array(29, 14, 31), Array(30, 29, 45), + Array(33, 38, 1, 48), Array(32, 38, 42), Array(35, 36, 28), Array(28, 19, 25, 27, 26, 34), Array(13, 34), Array(25, 23, 24), + Array(5, 4, 1, 6, 1, 32, 33, 0), Array(40), Array(39), Array(6, 8, 47, 46), Array(3, 5, 34), Array(28, 27, 29, 44), Array(29, + 43, 45), Array(44, 31), Array(6, 47), Array(46, 41), Array(49, 32), Array(1, 0, 6, 48)); + Global.distanceMatrix = Array(Array(0, 1, 2, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, + 4, 5, 4, 4, 5, 5, 5, 0, 0, 4, 3, 5, 6, 7, 2, 3, 3, 2), Array(1, 0, 1, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, + 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 3, 4, 4, 4, 5, 5, 4, 0, 0, 4, 3, 5, 6, 7, 2, 3, 2, 1), Array(2, 1, 0, 1, 2, 3, 2, 2, 6, 3, 4, 4, + 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 4, 6, 7, 8, 4, 5, 3, 4, 4, 6, 5, 0, 0, 5, 2, 5, 6, 7, 3, 4, 3, 2), Array(2, 2, + 1, 0, 1, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, 5, 6, 2, 3, 3, 5, 6, 0, 0, 5, 1, 4, + 5, 6, 3, 4, 4, 3), Array(1, 1, 2, 1, 0, 1, 1, 1, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, + 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, 2, 3, 3, 2), Array(2, 2, 3, 2, 1, 0, 2, 1, 6, 3, 2, 3, 2, 2, 4, 4, 1, 5, 5, 1, 1, 1, 2, 3, + 3, 2, 2, 2, 3, 3, 4, 5, 5, 6, 2, 2, 3, 3, 6, 0, 0, 5, 1, 3, 4, 5, 3, 4, 4, 3), Array(1, 1, 2, 2, 1, 2, 0, 1, 4, 1, 2, 2, 1, 3, + 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 4, 5, 4, 4, 4, 5, 5, 0, 0, 3, 3, 5, 6, 7, 1, 2, 3, 2), Array(1, 1, 2, 2, + 1, 1, 1, 0, 5, 2, 2, 3, 1, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, + 2, 3, 3, 2), Array(2, 2, 3, 3, 2, 2, 2, 1, 0, 3, 3, 4, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, + 5, 5, 6, 0, 0, 1, 3, 5, 6, 7, 2, 2, 4, 3), Array(2, 2, 3, 3, 2, 3, 1, 2, 5, 0, 2, 1, 2, 2, 6, 6, 3, 7, 7, 4, 4, 4, 4, 5, 5, 4, + 5, 5, 5, 6, 7, 8, 5, 6, 4, 5, 3, 5, 6, 0, 0, 4, 4, 6, 7, 8, 2, 3, 4, 3), Array(4, 4, 5, 5, 4, 3, 3, 4, 7, 2, 0, 1, 4, 1, 5, 5, + 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 7, 8, 3, 4, 2, 4, 8, 0, 0, 6, 4, 5, 6, 7, 4, 5, 6, 5), Array(3, 3, 4, 4, 3, 3, + 2, 3, 6, 1, 1, 0, 3, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 6, 7, 3, 4, 2, 4, 7, 0, 0, 5, 4, 5, 6, 7, 3, 4, + 5, 4), Array(2, 2, 3, 3, 2, 2, 1, 1, 5, 2, 1, 2, 0, 2, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, 3, 5, + 6, 0, 0, 4, 3, 5, 6, 7, 2, 3, 4, 3), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 3, 1, 2, 4, 0, 4, 4, 1, 5, 5, 2, 3, 2, 2, 3, 3, 2, 3, 3, + 3, 4, 5, 6, 7, 8, 2, 3, 1, 3, 8, 0, 0, 7, 3, 4, 5, 6, 5, 6, 6, 5), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 5, 6, 6, 4, 0, 4, 3, 5, + 1, 3, 5, 4, 3, 1, 3, 2, 2, 3, 4, 2, 1, 2, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 3, 3, 3, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, + 5, 10, 7, 5, 6, 6, 4, 3, 0, 3, 1, 4, 3, 5, 3, 2, 2, 1, 2, 3, 3, 4, 4, 4, 5, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 4, 5, 6, 7, 8, + 8, 7), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 3, 3, 0, 4, 4, 1, 2, 1, 1, 2, 2, 1, 2, 2, 3, 3, 4, 5, 6, 7, 2, 2, 2, 2, + 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 1, 2, 0, 3, 2, 4, 2, 1, 1, 2, 1, 2, 2, + 3, 3, 3, 4, 8, 9, 3, 2, 4, 2, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 6, 7, 7, 5, 1, 5, 4, 6, + 0, 4, 6, 5, 4, 2, 4, 3, 3, 4, 5, 3, 2, 3, 10, 11, 5, 4, 6, 3, 11, 0, 0, 10, 6, 4, 4, 4, 8, 9, 9, 8), Array(3, 3, 4, 3, 2, 1, 3, + 2, 7, 4, 3, 4, 3, 2, 3, 3, 1, 4, 4, 0, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 3, 4, 6, 7, 2, 1, 3, 2, 7, 0, 0, 6, 2, 2, 3, 4, 4, 5, 5, + 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 3, 1, 2, 3, 1, 5, 5, 2, 6, 6, 2, 0, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 6, 7, 3, 3, 2, 4, 7, + 0, 0, 6, 2, 4, 5, 6, 4, 5, 5, 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 4, 3, 1, 4, 5, 1, 2, 0, 1, 3, 2, 2, 2, 2, 2, + 3, 4, 5, 6, 7, 1, 2, 2, 3, 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 3, 2, 1, 3, 4, + 1, 3, 1, 0, 2, 1, 1, 2, 2, 3, 3, 4, 5, 7, 8, 2, 2, 3, 2, 8, 0, 0, 7, 3, 3, 4, 5, 5, 6, 6, 5), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, + 6, 4, 5, 5, 3, 1, 3, 2, 4, 2, 2, 4, 3, 2, 0, 2, 1, 1, 2, 3, 2, 2, 3, 8, 9, 3, 2, 4, 1, 9, 0, 0, 8, 4, 3, 3, 4, 6, 7, 7, 6), + Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 3, 1, 2, 2, 4, 2, 4, 2, 1, 2, 0, 2, 3, 3, 4, 4, 4, 5, 8, 9, 3, 3, 4, 1, 9, 0, + 0, 8, 4, 4, 5, 6, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 2, 3, 1, 4, 3, 1, 3, 2, 1, 1, 2, 0, 1, 1, 2, 2, + 3, 4, 7, 8, 2, 1, 3, 1, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, + 3, 2, 2, 2, 3, 1, 0, 1, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 2, 2, 3, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, + 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 0, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 1, 2, 3, 5, 6, 6, 5), Array( + 5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 4, 5, 3, 6, 5, 2, 4, 3, 3, 3, 4, 2, 2, 2, 0, 2, 3, 4, 8, 9, 1, 1, 2, 3, 9, 0, 0, 8, + 4, 1, 2, 3, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 2, 5, 3, 6, 3, 2, 4, 3, 3, 3, 4, 2, 1, 1, 2, 0, 1, 2, + 8, 9, 3, 2, 4, 3, 9, 0, 0, 8, 4, 1, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 1, 5, 4, 6, 2, 3, 5, 4, + 4, 2, 4, 3, 2, 2, 3, 1, 0, 1, 9, 10, 4, 3, 5, 3, 10, 0, 0, 9, 5, 2, 2, 2, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, + 7, 6, 5, 2, 6, 4, 7, 3, 3, 5, 4, 4, 3, 5, 3, 2, 2, 3, 1, 1, 0, 9, 10, 4, 3, 5, 4, 10, 0, 0, 9, 5, 2, 2, 1, 7, 8, 8, 7), Array( + 2, 1, 2, 3, 2, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 4, 5, 6, 7, 0, 1, 3, 4, 4, 5, 1, 0, 0, 5, + 2, 5, 6, 7, 3, 4, 1, 2), Array(2, 2, 3, 2, 2, 2, 2, 3, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, + 1, 0, 2, 3, 3, 5, 1, 0, 0, 5, 1, 4, 5, 6, 3, 4, 2, 3), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 5, 3, 4, 5, 2, 4, 5, 3, 6, 5, 2, 4, 3, + 3, 3, 4, 2, 2, 2, 1, 3, 4, 5, 8, 9, 0, 1, 1, 3, 9, 0, 0, 8, 4, 2, 3, 4, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, + 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 1, 1, 2, 3, 4, 7, 8, 1, 0, 2, 2, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(5, 5, + 6, 5, 4, 3, 5, 4, 9, 4, 2, 3, 5, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 8, 9, 1, 2, 0, 4, 9, 0, 0, 8, 4, 3, + 4, 5, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 2, 2, 3, 3, 2, 4, 3, 2, 1, 1, 1, 2, 2, 3, 3, 3, 4, 8, 9, + 3, 2, 4, 0, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(1, 1, 2, 2, 1, 1, 1, 2, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, + 4, 3, 3, 3, 4, 4, 5, 6, 1, 1, 3, 3, 4, 4, 0, 0, 0, 4, 2, 4, 5, 6, 2, 3, 2, 2), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(2, 2, 3, 3, 2, 3, 1, 2, 1, 2, 3, 3, 2, + 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 0, 4, 6, 7, 8, 1, 1, 4, 3), Array(3, 3, 2, + 1, 2, 1, 3, 2, 7, 4, 3, 4, 3, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 6, 7, 1, 2, 2, 4, 7, 0, 0, 6, 0, 3, 4, + 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 3, 5, 3, 6, 4, 2, 4, 3, 3, 3, 4, 2, 2, 1, 1, 1, 2, 3, 8, 9, 2, + 2, 3, 3, 9, 0, 0, 8, 4, 0, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 3, 6, 4, 7, 4, 3, 5, 4, 4, 4, 5, + 3, 2, 2, 2, 1, 2, 2, 9, 10, 3, 3, 4, 4, 10, 0, 0, 9, 5, 1, 0, 1, 7, 8, 8, 7), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 7, 8, 7, 6, + 3, 7, 5, 8, 4, 4, 6, 5, 5, 4, 6, 4, 3, 3, 3, 2, 2, 1, 10, 11, 4, 4, 5, 5, 11, 0, 0, 10, 6, 2, 1, 0, 8, 9, 9, 8), Array(2, 2, 3, + 3, 2, 3, 1, 2, 3, 2, 3, 3, 2, 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 2, 4, 6, 7, + 8, 0, 1, 4, 3), Array(3, 3, 4, 4, 3, 4, 2, 3, 2, 3, 4, 4, 3, 5, 8, 8, 5, 9, 9, 5, 5, 5, 6, 7, 7, 6, 6, 6, 7, 7, 8, 9, 6, 7, 6, + 6, 6, 7, 7, 0, 0, 1, 5, 7, 8, 9, 1, 0, 5, 4), Array(2, 2, 3, 4, 3, 3, 2, 3, 6, 3, 4, 4, 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, + 5, 5, 5, 5, 6, 7, 8, 1, 2, 4, 5, 5, 6, 2, 0, 0, 5, 3, 6, 7, 8, 3, 4, 0, 1), Array(1, 1, 2, 3, 2, 3, 1, 2, 5, 2, 3, 3, 2, 4, 7, + 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 2, 3, 5, 5, 5, 6, 3, 0, 0, 4, 4, 6, 7, 8, 2, 3, 1)); + } +} + +rule("SUBROUTINE: BOT - RESET PATH FINDING") +{ + event + { + Subroutine; + BotResetPathFinding; + } + + actions + { + Event Player.botTargetPlayer = -1; + Event Player.botTargetPosition = -1; + Event Player.botPreviousNodeId = -1; + Event Player.botClosestNodeIdToTarget = -1; + Event Player.botNextNodeId = -1; + Event Player.botNextNodePosition = -1; + Event Player.botIsPathFinding = False; + Event Player.botCancelPathFinding = False; + Stop Throttle In Direction(Event Player); + disabled Stop Facing(Event Player); + } +} + +rule("SUBROUTINE: BOT - START PATH FINDING") +{ + event + { + Subroutine; + BotStartPathFinding; + } + + actions + { + disabled Abort If(Event Player.botIsPathFinding == True); + Call Subroutine(BotGetNextNodeIdAndPosition); + disabled Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Event Player.botIsPathFinding = True; + } +} + +rule("SUBROUTINE: BOT - GET NEXT NODE ID AND POSITION") +{ + event + { + Subroutine; + BotGetNextNodeIdAndPosition; + } + + actions + { + "BOT JUST START FOLLOW PATH OR LOST NEXT NODE" + If(Event Player.botPreviousNodeId == -1); + Event Player.botClosestNodeIdToBot = Index Of Array Value(Global.nodePositions, Sorted Array(Filtered Array(Global.nodePositions, + Is In Line of Sight(Position Of(Event Player) + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS) == True), + Distance Between(Position Of(Event Player), Current Array Element))[0]); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + "NEXT NODE IS TARGET (DISTANCE TO TARGET NODE = 1)" + If(Global.distanceMatrix[Event Player.botClosestNodeIdToBot][Event Player.botClosestNodeIdToTarget] == 1); + Event Player.botNextNodeId = Event Player.botClosestNodeIdToTarget; + "CHECK CONNECTIONS OF REACHED NODE" + Else; + Event Player.botShortestDistanceToTarget = 999; + Event Player.botCurrentDistanceToTarget = Event Player.botShortestDistanceToTarget; + Event Player.botTempArray = Global.nodeConnections[Event Player.botClosestNodeIdToBot]; + For Player Variable(Event Player, botLoopIterator1, 0, Count Of(Event Player.botTempArray), 1); + Event Player.botCurrentDistanceToTarget = Global.distanceMatrix[Event Player.botTempArray[Event Player.botLoopIterator1]][Event Player.botClosestNodeIdToTarget]; + If(Event Player.botCurrentDistanceToTarget < Event Player.botShortestDistanceToTarget); + Event Player.botShortestDistanceToTarget = Event Player.botCurrentDistanceToTarget; + Event Player.botNextNodeId = Event Player.botTempArray[Event Player.botLoopIterator1]; + End; + End; + End; + "NEXT NODE IS HIGHER THAN BOT AND BOT DIDN'T REACH CLOSEST NODE" + If(Y Component Of(Position Of(Event Player)) - Y Component Of(Global.nodePositions[Event Player.botNextNodeId]) + < -3 && Event Player.botPreviousNodeId != Event Player.botClosestNodeIdToBot); + Event Player.botPreviousNodeId = Event Player.botClosestNodeIdToBot; + Event Player.botNextNodeId = Event Player.botClosestNodeIdToBot; + "BOT CAN SEE TARGET POSITION AND NEXT NODE IS TARGET" + Else If( + Global.distanceMatrix[Event Player.botClosestNodeIdToBot][Event Player.botClosestNodeIdToTarget] == 1 && Is In Line of Sight( + Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.botTargetPosition + Vector(0, 2, 0), Barriers Do Not Block LOS)); + Event Player.botNextNodePosition = Event Player.botTargetPosition; + Abort; + "BOT CAN'T SEE NEXT NODE AND PREV NODE != REACHED NODE" + Else If(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), + Global.nodePositions[Event Player.botNextNodeId] + Vector(0, 2, 0), Barriers Do Not Block LOS) + == False && Event Player.botPreviousNodeId != Event Player.botClosestNodeIdToBot); + Event Player.botPreviousNodeId = Event Player.botClosestNodeIdToBot; + Event Player.botNextNodeId = Event Player.botClosestNodeIdToBot; + End; + Event Player.botNextNodePosition = Global.nodePositions[Event Player.botNextNodeId]; + } +} + +rule("SUBROUTINE: BOT - GET CLOSEST NODE ID AND POSITION TO TARGET") +{ + event + { + Subroutine; + BotGetClosestNodeIdToTarget; + } + + actions + { + Event Player.botTargetPosition = Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) + : Event Player.botTargetPosition; + Event Player.botClosestNodeIdToTarget = Index Of Array Value(Global.nodePositions, Sorted Array(Filtered Array( + Global.nodePositions, Is In Line of Sight(Event Player.botTargetPosition + Vector(0, 2, 0), Current Array Element, + Barriers Do Not Block LOS) == True), Distance Between(Event Player.botTargetPosition, Current Array Element))[0]); + } +} + +rule("BOT: PATH FINDING - START") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + (Event Player.botTargetPosition != -1 || Event Player.botTargetPlayer != -1) == True; + } + + actions + { + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - CANCEL") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.botIsPathFinding == True; + Event Player.botCancelPathFinding == True; + } + + actions + { + Start Rule(BotResetPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - LOST THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.botIsPathFinding == True; + (Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.botNextNodePosition + Vector(0, 2.500, 0), + Barriers Do Not Block LOS) == False && Speed Of In Direction(Event Player, Throttle Of(Event Player)) < 2) == True; + } + + actions + { + Wait(0.500, Abort When False); + "RESET PREV NODE ID TO INFORM BOT THAT IT LOST NEXT NODE" + Event Player.botPreviousNodeId = -1; + "TRY FIND NEW NEXT NODE" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodeId), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +rule("BOT: PATH FINDING - REACHED THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.botIsPathFinding == True; + Event Player.botClosestNodeIdToTarget >= 0; + (Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.botNextNodePosition), 0, Z Component Of(Event Player.botNextNodePosition))) < 0.850) == True; + } + + actions + { + Event Player.botPreviousNodeId = Event Player.botNextNodeId; + Event Player.botClosestNodeIdToBot = Event Player.botNextNodeId; + "BOT'S TARGET IS PLAYER" + If(Event Player.botTargetPlayer != -1); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + Event Player.botCurrentDistanceToTarget = Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of( + Position Of(Event Player))), Vector(X Component Of(Event Player.botTargetPosition), 0, Z Component Of( + Event Player.botTargetPosition))); + "BOT REACHED THE TARGET NODE OR TARGET POSITION" + If(Event Player.botNextNodeId == Event Player.botClosestNodeIdToTarget || Event Player.botCurrentDistanceToTarget <= 0.850); + "BOT DIDN'T REACH TARGET POSITION" + If(Event Player.botCurrentDistanceToTarget > 0.850); + Event Player.botNextNodePosition = Event Player.botTargetPosition; + Skip(6); + "BOT REACHED TARGET" + Else; + Call Subroutine(BotResetPathFinding); + Abort; + End; + End; + "CONTINUE FOLLOW PATH" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: GAME MODE INIT - WORKSHOP SETTINGS") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.isDebug = False; + Global.isDebugAINavigation = False; + Global.gateMaxHealth = Workshop Setting Integer(Custom String("Defend The Castle Extended"), Custom String("GATE MAX HEALTH"), 500, + 100, 1000, 0); + Global.moneyMultiplier = Workshop Setting Real(Custom String("Defend The Castle Extended"), Custom String("Money Multiplicator"), + 1, 0.500, 2, 0); + Global.selfNanoWorkshopSetting = Workshop Setting Toggle(Custom String("Ana Self Nano"), Custom String( + "Ana can nano herself even if there are other players (only if no player targeted)"), False, 0); + } +} + +rule("GLOBAL: GAME MODE INIT - COMMON PROPERTIES") +{ + event + { + Ongoing - Global; + } + + actions + { + Create In-World Text(All Players(Team 1), Custom String( + "Defend The Castle Extended c131\r\nby ShuriZma#2349\r\nOriginal mode by HUKUTA94#2589\r\nDiscord: discord.shurizma.de\r\n{0}", + Custom String("Special Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents &\nJosbird for teaching me about Menus{0}", + Custom String(" \nPS: SHINGEN PLS COME BACK"))), Vector(165, 12, -46.500), 1.200, Clip Against Surfaces, Visible To, Color(White), Default Visibility); + Global.gateRepairPosition = Vector(153, 8, -46.500); + Global.gatePosition = Vector(148.800, 6, -46.400); + Global.ballSpawnPositions = Array(Vector(104, 7, -46), Vector(106, 2, -31)); + Global.sniperPositions = Array(Vector(154, 18, -22.600), Vector(86, 12, -46.600), Vector(80.880, 11.300, -71.600), Vector(98, 9, + -19)); + Global.zenSpawnPositions = Array(Vector(79.500, 5, -100), Vector(90, 4, -88), Vector(65, 11, -70), Vector(85, 4, -68), Vector(96, + 2, -73), Vector(84, 7, -47), Vector(95, 9, -34), Vector(108, 1.700, -28), Vector(113, 7, -37), Vector(123, 5, -19), Vector(144, + 5, -19), Vector(123, 6, -39), Vector(123, 6, -61), Vector(129, 6, -30.500), Vector(135, 6, -63)); + Global.playerSpawnPositions = Array(Vector(160, 11, -53), Vector(158, 11, -53), Vector(160, 11, -39), Vector(158, 11, -39)); + Global.bigBossSpawnPositions = Array(Vector(78, 4, -84), Vector(95, 4, -82)); + Global.bastionTargetPositions = Array(Vector(131, 12, -62), Vector(115, 7, -46), Objective Position(2), Vector(136, 10, -27)); + Global.spawnPositionMaxId = 2; + Global.botOrisaTargetPosition = Vector(104, 7, -46); + Global.botEchoRespawnPosition = Vector(130, 23, -44); + Global.botEchoTeleportPositions = Array(Vector(88, 23, -79), Vector(108, 18, -27)); + Global.defaultHeroBotsPool = Array(Hero(Zenyatta), Hero(Widowmaker), Null, Hero(Bastion), Hero(Echo), Hero(Bastion)); + Global.zenRespawnTime = 10; + Global.gameLogicCountOfUniqueHeroes = 5; + Global.lastBoss = Array(Null, Null, Null, Null); + Create Effect(All Players(Team 1), Ring, Color(Sky Blue), Vector(186, 11, -46.500), 9, Visible To Position and Radius); + Create Effect(All Players(Team 1), Ring, Color(Yellow), Vector(159, 11, -46.500), 2, Visible To Position and Radius); + } +} + +disabled rule("=== TEAM UPGRADES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: TEAM UPGRADES - INIT") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.upgradeMaxAmmoMaxValue[0] = 150; + Global.upgradeMaxAmmoMaxValue[1] = 300; + Global.upgradeMaxAmmoMaxValue[2] = 500; + Global.upgradeCriticalDamageMaxValue[0] = 10; + Global.upgradeCriticalDamageMaxValue[1] = 5; + Global.upgradeCriticalDamageMaxValue[2] = 10; + Global.upgradePlayerMaxHealthMaxValue[0] = 4000; + Global.upgradePlayerMaxHealthMaxValue[1] = 9000; + Global.upgradePlayerMaxHealthMaxValue[2] = 15000; + Global.upgradeGateMaxHealthMaxValue[0] = Round To Integer(Global.gateMaxHealth + Global.gateMaxHealth * 0.750, Up); + Global.upgradeGateMaxHealthMaxValue[1] = Global.upgradeGateMaxHealthMaxValue[0] + Global.upgradeGateMaxHealthMaxValue[0]; + Global.upgradeGateMaxHealthMaxValue[2] = Global.upgradeGateMaxHealthMaxValue[1] + Global.upgradeGateMaxHealthMaxValue[1]; + Abort If(Global.isDebug == False); + Global.upgradeMaxAmmoMaxValue[0] = 1; + Global.upgradeCriticalDamageMaxValue[0] = 1; + Global.upgradePlayerMaxHealthMaxValue[0] = 1; + Global.upgradeGateMaxHealthMaxValue[0] = 1; + Global.upgradeMaxAmmoMaxValue[1] = 1; + Global.upgradeCriticalDamageMaxValue[1] = 1; + Global.upgradePlayerMaxHealthMaxValue[1] = 1; + Global.upgradeGateMaxHealthMaxValue[1] = 1; + Global.upgradeMaxAmmoMaxValue[2] = 1; + Global.upgradeCriticalDamageMaxValue[2] = 1; + Global.upgradePlayerMaxHealthMaxValue[2] = 1; + Global.upgradeGateMaxHealthMaxValue[2] = 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GATE'S MAX HEALTH UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.gatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.gatePosition, 100); + Global.gateMaxHealth = Global.upgradeGateMaxHealthMaxValue[0]; + Global.gateHealth = Global.gateMaxHealth; + Destroy HUD Text(Global.upgradeGateMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("GATE'S MAX HEALTH: {0} HP", Global.upgradeGateMaxHealthMaxValue[0]), Right, 1, Color( + Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeGateMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X GATE REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.upgradeGateMaxHealthValue, Global.upgradeGateMaxHealthMaxValue[1]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.upgradeGateMaxHealthHudId[1] = Last Text ID; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X GATE REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.gatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.gatePosition, 100); + Destroy HUD Text(Global.upgradeGateMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X GATE REPAIR"), Right, 2, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.upgradeGateMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X AUTO-REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.upgradeGateMaxHealthValue, Global.upgradeGateMaxHealthMaxValue[2]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.upgradeGateMaxHealthHudId[2] = Last Text ID; + Global.gateHealth = Global.gateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 3 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("2X AUTO-REPAIR UNLOCKED!")); + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.gatePosition, 5); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Green), Global.gatePosition, 100); + Destroy HUD Text(Global.upgradeGateMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X AUTO-REPAIR"), Right, 3, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.upgradeGateMaxHealthHudId[2] = Last Text ID; + Global.gateHealth = Global.gateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - PLAYER'S MAX HEALTH - DEALT HEALING") +{ + event + { + Player Received Healing; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + disabled Healer != Event Player; + Global.upgradePlayerMaxHealthValue < Global.upgradePlayerMaxHealthMaxValue[2]; + } + + actions + { + Global.upgradePlayerMaxHealthValue += Event Healing; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH UNLOCKED!")); + Destroy HUD Text(Global.upgradePlayerMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +50%"), Right, 4, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradePlayerMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("Up You Go: You respawn twice as fast"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.upgradePlayerMaxHealthValue, Down), + Global.upgradePlayerMaxHealthMaxValue[1]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.upgradePlayerMaxHealthHudId[1] = Last Text ID; + For Global Variable(loopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 100); + End; + Global.maxHealthDone = 50; + All Players(Team 1).playerHealth = 100 + Global.maxHealthDone + All Players(Team 1).abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).playerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK UP YOU GO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("UP YOU GO UNLOCKED!")); + Destroy HUD Text(Global.upgradePlayerMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String("Up You Go"), + Right, 5, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradePlayerMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +100%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.upgradePlayerMaxHealthValue, Down), + Global.upgradePlayerMaxHealthMaxValue[2]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.upgradePlayerMaxHealthHudId[2] = Last Text ID; + Set Respawn Max Time(All Players(Team 1), 5); + Heal(All Players(Team 1), Null, 9999); + For Global Variable(loopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 100); + End; + Global.perk[2] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).abilityHUD[17] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("PLAYER'S MAX HEALTH 2 UNLOCKED!")); + Destroy HUD Text(Global.upgradePlayerMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +100%"), Right, 6, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradePlayerMaxHealthHudId[2] = Last Text ID; + For Global Variable(loopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 1); + Play Effect(All Players(All Teams), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 100); + End; + Global.maxHealthDone = 150; + All Players(Team 1).playerHealth = 100 + Global.maxHealthDone + All Players(Team 1).abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).playerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Hero Of(Victim) == Hero(Widowmaker); + Global.upgradeCriticalDamageValue < Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.upgradeCriticalDamageValue += 1; + Small Message(All Players(Team 1), Custom String("CRITICAL DAMAGE CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - CRITICAL DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.upgradeCriticalDamageValue >= Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("CRITICAL DAMAGE 150% UNLOCKED!")); + Destroy HUD Text(Global.upgradeCriticalDamageHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "CRITICAL DAMAGE 150%"), Right, 7, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeCriticalDamageHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String( + "Sharpshooter: Deal 40% more damage to enemies that are further than 15 meters away"), Custom String("KILL ECHO {0}/{1}", + Global.upgradePerkSharpshooterValue, Global.upgradeCriticalDamageMaxValue[1]), Left, 14, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.upgradeCriticalDamageHudId[1] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - UNLOCKED") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Global.upgradeCriticalDamageValue >= Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.500); + } +} + +rule("PLAYER: UPGRADE - PERK SHARPSHOOTER - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Echo); + Global.upgradePerkSharpshooterValue < Global.upgradeCriticalDamageMaxValue[1]; + Global.upgradeCriticalDamageValue >= Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.upgradePerkSharpshooterValue += 1; + Small Message(All Players(Team 1), Custom String("SHARPSHOOTER CHALLENGE +1")); + } +} + +rule("GLOBAL: UPGRADE - PERK SHARPSHOOTER - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.upgradePerkSharpshooterValue >= Global.upgradeCriticalDamageMaxValue[1]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("SHARPSHOOTER UNLOCKED!")); + Destroy HUD Text(Global.upgradeCriticalDamageHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Sharpshooter"), Right, 8, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeCriticalDamageHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("-10% BOSS HEALTH"), Custom String("KILL Bosses {0}/{1}", + Global.upgradeBossHealthValue, Global.upgradeCriticalDamageMaxValue[2]), Left, 14, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.upgradeCriticalDamageHudId[2] = Last Text ID; + Global.perk[0] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).abilityHUD[18] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - -10% BOSS HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2]; + } + + actions + { + Big Message(All Players(Team 1), Custom String("-10% BOSS HEALTH UNLOCKED!")); + Destroy HUD Text(Global.upgradeCriticalDamageHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "-10% BOSS HEALTH"), Right, 9, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeCriticalDamageHudId[2] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - MAX AMMO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[0]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("MAX AMMO 200% UNLOCKED!")); + Destroy HUD Text(Global.upgradeMaxAmmoHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "MAX AMMO 200%"), Right, 10, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("+50% DAMAGE"), Custom String("KILL {2}: {0}/{1}", + Global.upgradeMaxAmmoValue, Global.upgradeMaxAmmoMaxValue[1], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.upgradeMaxAmmoHudId[1] = Last Text ID; + For Global Variable(loopIterator1, 0, Count Of(All Players(Team 1)), 1); + Set Max Ammo(All Players(Team 1)[Global.loopIterator1], 0, Max Ammo(All Players(Team 1)[Global.loopIterator1], 0) * 2); + Set Max Ammo(All Players(Team 1)[Global.loopIterator1], 1, Max Ammo(All Players(Team 1)[Global.loopIterator1], 1) * 2); + Set Ammo(All Players(Team 1)[Global.loopIterator1], 0, Max Ammo(All Players(Team 1)[Global.loopIterator1], 0)); + Set Ammo(All Players(Team 1)[Global.loopIterator1], 1, Max Ammo(All Players(Team 1)[Global.loopIterator1], 1)); + End; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - +50% DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("+50% DAMAGE UNLOCKED!")); + Destroy HUD Text(Global.upgradeMaxAmmoHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "+50% DAMAGE"), Right, 12, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeMaxAmmoHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("Bulletstorm: Your weapon can hold unlimited ammo"), + Custom String("KILL {2}: {0}/{1}", Global.upgradeMaxAmmoValue, Global.upgradeMaxAmmoMaxValue[2], Hero(Zenyatta)), Left, 15, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.upgradeMaxAmmoHudId[2] = Last Text ID; + Global.damageDealt = 50; + All Players(Team 1).damageDealt = 100 + Global.damageDealt + All Players(Team 1).abilities[13] * 5; + Set Damage Dealt(All Players(Team 1), All Players(Team 1).damageDealt); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK BULLETSTORM - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[2]) == True; + } + + actions + { + Big Message(All Players(Team 1), Custom String("BULLETSTORM UNLOCKED!")); + Destroy HUD Text(Global.upgradeMaxAmmoHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Bulletstorm"), Right, 11, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeMaxAmmoHudId[2] = Last Text ID; + Global.perk[1] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).abilityHUD[19] = Last Text ID; + Global.challengeCount += 1; + } +} + +disabled rule("=== GAME PHASES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: ASSEMBLING PHASE - MAKE CHALLENGE HUDS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Assembling Heroes == True; + } + + actions + { + If(Global.isDebug); + Set Match Time(1); + Else; + Disable Inspector Recording; + Set Match Time(20); + End; + Create In-World Text(All Players(Team 1), Custom String(" {0}\r\nREPAIR\r\n {1}", Hero Icon String(Hero(Torbjörn)), + Ability Icon String(Hero(Bastion), Button(Secondary Fire))), Global.gatePosition + Vector(0, 1.400, 0), 1.200, Do Not Clip, + Visible To, Color(White), Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("TEAM CHALLENGES {0}/12", Global.challengeCount), Left, 11, Color( + White), Color(Blue), Color(White), Visible To and String, Default Visibility); + "UPGRADE - GATE'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String( + "GATE'S MAX HEALTH: {0} HP", Global.upgradeGateMaxHealthMaxValue[0]), Custom String("REPAIR GATE {0}/{1} HP", + Global.upgradeGateMaxHealthValue, Global.upgradeGateMaxHealthMaxValue[0]), Left, 12, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.upgradeGateMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 2, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - PLAYER'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +50%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.upgradePlayerMaxHealthValue, Down), + Global.upgradePlayerMaxHealthMaxValue[0]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.upgradePlayerMaxHealthHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 4, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - CRITICAL DAMAGE" + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("CRITICAL DAMAGE 150%"), Custom String( + "KILL WIDOW WITH HEADSHOT: {0}/{1}", Global.upgradeCriticalDamageValue, Global.upgradeCriticalDamageMaxValue[0]), Left, 14, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.upgradeCriticalDamageHudId[0] = Last Text ID; + disabled Create HUD Text(All Players(Team 1), Null, Custom String(" \r\n "), Null, Left, 6, Color(White), Color(White), Color(White), + Visible To, Default Visibility); + "UPGRADE - MAX AMMO" + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("MAX AMMO 200%"), Custom String("KILL {2}: {0}/{1}", + Global.upgradeMaxAmmoValue, Global.upgradeMaxAmmoMaxValue[0], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.upgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Custom String("HOLD {0} - Reload to open the shop", Input Binding String(Button(Reload))), + Null, Null, Top, 1000, Color(Yellow), Color(White), Color(White), Visible To and String, Default Visibility); + } +} + +rule("GLOBAL: SETUP PHASE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + If(Global.isDebug); + Set Match Time(1); + Else; + Pause Match Time; + Create HUD Text(All Players(Team 1), Custom String("PRESS {0} TO START", Button(Interact)), Null, Null, Top, 50, Color(Red), Color( + White), Color(White), Visible To and String, Default Visibility); + Global.globalHUDs[0] = Last Text ID; + Set Match Time(20); + Wait Until(Is True For Any(All Players(Team 1), Is Button Held(Current Array Element, Button(Interact))), 99999); + Destroy HUD Text(Global.globalHUDs[0]); + Unpause Match Time; + End; + Set Objective Description(All Players(All Teams), Custom String("DEFEND GATE"), Visible To and String); + } +} + +rule("GLOBAL: GAME IN PROGRESS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + } + + actions + { + Set Match Time(3599); + Pause Match Time; + Disable Built-In Game Mode Scoring; + Disable Built-In Game Mode Announcer; + Disable Built-In Game Mode Completion; + Disable Game Mode HUD(All Players(All Teams)); + Disable Game Mode In-World UI(All Players(All Teams)); + Global.gateHealth = Global.gateMaxHealth; + Global.gateHealthChase = Global.gateHealth; + Global.gateProgressBarColorComponent = 255; + Global.gateProgressBarColorCurrent = Color(White); + Create Progress Bar HUD Text(All Players(Team 1), Global.gateHealthChase * 100 / Global.gateMaxHealth, Custom String( + "GATE {0}/{1}", Global.gateHealth, Global.gateMaxHealth), Top, 1, Global.gateProgressBarColorCurrent, Color(White), + Visible To Values and Color, Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("SURVIVED TIME: {0}:{1}", Global.timeMinutes, + Global.timeSeconds < 10 ? Custom String("0{0}", Global.timeSeconds) : Global.timeSeconds), Top, 2, Color(White), Color(White), + Color(White), Visible To and String, Default Visibility); + Start Rule(GameLogicWave0, Do Nothing); + } +} + +disabled rule("=== GAME - MAIN LOGIC ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: DEFEAT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.isDebug == False; + Global.gateHealth <= 0; + } + + actions + { + Declare Team Victory(Team 2); + } +} + +rule("GLOBAL: TIMER - MAIN GAME LOOP") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + disabled Global.gateHealth > 0; + } + + actions + { + Wait(1, Ignore Condition); + Global.timeSeconds += 1; + If(Global.timeSeconds == 60); + Global.timeSeconds = 0; + Global.timeMinutes += 1; + Global.time5Minutes = Round To Integer(Global.timeMinutes / 5, Down); + Global.time10Minutes = Round To Integer(Global.timeMinutes / 10, Down); + Global.spawnPositionMaxId += 1; + disabled Start Rule(GameLogicAddNextHeroInGame, Restart Rule); + Else If(Global.timeSeconds == 30); + Global.spawnPositionMaxId += 1; + End; + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GAME LOGIC - ADD NEXT HERO IN GAME") +{ + event + { + Subroutine; + GameLogicAddNextHeroInGame; + } + + actions + { + "REDUCE RESPAWN TIME FOR ZENS" + disabled Global.zenRespawnTime -= 1.500; + disabled Global.zenRespawnTime = Max(1, Global.zenRespawnTime); + disabled Set Respawn Max Time(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Global.defaultHeroBotsPool[0]), + Global.zenRespawnTime); + "ALL HEROES WAS ADDED IN GAME" + Abort If(Global.defaultHeroBotsPoolCurrentId == Count Of(Global.defaultHeroBotsPool) - 1); + Global.defaultHeroBotsPoolCurrentId += 1; + "ВРЕМЕННЫЙ КОСТЫЛЬ ЧТОБЫ ЭХО ЗАМЕНИЛА ХАМСТЕРА" + If(Global.defaultHeroBotsPool[Global.defaultHeroBotsPoolCurrentId] == Hero(Echo)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Abort; + End; + "ABORT IF NEXT HERO IN ARRAY ORDER IS NULL" + Abort If(Global.defaultHeroBotsPool[Global.defaultHeroBotsPoolCurrentId] == Null); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.050, Ignore Condition); + Create Dummy Bot(Global.defaultHeroBotsPool[Global.defaultHeroBotsPoolCurrentId], Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("SUBROUTINE: GAME LOGIC - SET BOT PROPERTIES") +{ + event + { + Subroutine; + GameLogicSetBotProperties; + } + + actions + { + Abort If(Event Player.botIsOrisaChild == True); + If(Global.timeMinutes >= 10); + If(Filtered Array(Global.lastBoss, Current Array Element == Hero Of(Event Player)) == False); + If(Global.activeBoss == False); + If(Global.bossTrigger < Global.timeMinutes); + Global.bossTrigger = Global.timeMinutes; + Global.activeBoss = Event Player; + Event Player.isBoss = 1; + Big Message(All Players(Team 1), Custom String("BOSS SPAWNED - {0}", Hero Of(Event Player))); + End; + End; + End; + End; + "PROPERTIES BY DEFAULT" + Set Gravity(Event Player, 100); + Set Damage Dealt(Event Player, 100); + Set Respawn Max Time(Event Player, 10); + Start Scaling Player(Event Player, 1, False); + "INDIVIDUAL HERO'S PROPERTIES" + If(Hero Of(Event Player) == Hero(Zenyatta)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 30); + Set Max Health(Event Player, 10 * (100 + 10 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 1.500, False); + Else; + If(20 + 3 * Number Of Players(Team 1) + 3 * Global.timeMinutes > 75); + Set Move Speed(Event Player, 75); + Else; + Set Move Speed(Event Player, 20 + 3 * Count Of(All Players(Team 1)) + 3 * Global.timeMinutes); + End; + Set Max Health(Event Player, 100 + 10 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 20); + Set Max Health(Event Player, 5 * (70 + 20 * Count Of(All Players(Team 1)) + + 10 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + If(30 + Global.timeMinutes + 2.500 * Global.time5Minutes > 40); + Set Move Speed(Event Player, 40); + Else; + Set Move Speed(Event Player, 30 + Global.timeMinutes + 2.500 * Global.time5Minutes); + End; + Set Ultimate Charge(Event Player, 0); + Set Max Health(Event Player, 70 + 20 * Count Of(All Players(Team 1)) + + 10 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + If(Event Player.isBoss == 1); + Set Damage Dealt(Event Player, 2 * (85 + 15 * Count Of(All Players(Team 1)) + + 25 * Global.time5Minutes + 50 * Global.time10Minutes)); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 5 * (100 + 25 * Count Of(All Players(Team 1)) + + 5 * Global.timeMinutes + 15 * Global.time5Minutes + 40 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Event Player.botCounter = 0; + Set Damage Dealt(Event Player, 85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.time5Minutes + 50 * Global.time10Minutes); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 100 + 25 * Count Of(All Players(Team 1)) + + 5 * Global.timeMinutes + 15 * Global.time5Minutes + 40 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Bastion)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 50); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Minutes + 10 * Global.time10Minutes); + Start Scaling Player(Event Player, 3, False); + Set Max Health(Event Player, 5 * (155 + 150 * Count Of(All Players(Team 1)) + + 20 * Global.timeMinutes + 40 * Global.time5Minutes + 65 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Else; + Set Move Speed(Event Player, 80); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Minutes + 10 * Global.time10Minutes); + Start Scaling Player(Event Player, 2, False); + Set Max Health(Event Player, 155 + 150 * Count Of(All Players(Team 1)) + + 20 * Global.timeMinutes + 40 * Global.time5Minutes + 65 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Orisa)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 5 * (220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.time5Minutes + 100 * Global.time10Minutes) + * (Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Set Move Speed(Event Player, 30 + 5 * Global.time5Minutes); + Else; + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.time5Minutes + 100 * Global.time10Minutes); + Set Move Speed(Event Player, 90 + 5 * Global.time5Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Echo)); + If(Event Player.isBoss == 1); + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 70 + 5 * Global.time5Minutes); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 5 * (90 + 25 * Count Of(All Players(Team 1)) + + 15 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 130 + 5 * Global.time5Minutes); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 90 + 25 * Count Of(All Players(Team 1)) + + 15 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.500, False); + Set Move Speed(Event Player, 70); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Minutes + 10 * Global.time10Minutes); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 5 * (55 + 25 * Count Of(All Players(Team 1)) + + 15 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Else; + disabled Start Scaling Player(Event Player, 0.850, False); + Set Move Speed(Event Player, 110); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Minutes + 10 * Global.time10Minutes); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 55 + 25 * Count Of(All Players(Team 1)) + + 15 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes); + End; + End; + Wait(0.250, Ignore Condition); + "FILL HEALTH" + Heal(Event Player, Null, 100000); + } +} + +disabled rule("=== GATE ===") +{ + event + { + Ongoing - Global; + } +} + +rule("Subroutine: GATE REPAIR") +{ + event + { + Subroutine; + GateRepair; + } + + actions + { + Small Message(Event Player, Custom String("REPAIR +2% ULTIMATE")); + "UPGRADE - GATE'S MAX HEALTH" + If(Global.upgradeGateMaxHealthValue < Global.upgradeGateMaxHealthMaxValue[2]); + If(Global.gateMaxHealth - Global.gateHealth > 10 * ( + Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1] ? 2 : 1) * (Event Player.isNanoed == 1 ? 2 : 1)); + Global.upgradeGateMaxHealthValue += 10 * (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1] ? 2 : 1) * ( + Event Player.isNanoed == 1 ? 2 : 1); + Else; + Global.upgradeGateMaxHealthValue += Global.gateMaxHealth - Global.gateHealth; + End; + End; + "HEAL GATE" + If(Global.gateMaxHealth - Global.gateHealth > 10 * ( + Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1] ? 2 : 1) * (Event Player.isNanoed == 1 ? 2 : 1)); + Global.gateHealth += 10 * (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1] ? 2 : 1) * ( + Event Player.isNanoed == 1 ? 2 : 1); + Else; + Global.gateHealth += Global.gateMaxHealth - Global.gateHealth; + End; + "CHARGE ULTIMATE" + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + } +} + +rule("GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + ((Hero Of(Event Player) == Hero(Torbjörn) && Weapon(Event Player) == 2) || (Hero Of(Event Player) == Hero(Reinhardt) || Hero Of( + Event Player) == Hero(Brigitte))) == True; + Is Firing Primary(Event Player) == True; + Global.gateHealth < Global.gateMaxHealth; + Is In View Angle(Event Player, Global.gateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.gatePosition) < (Hero Of(Event Player) == Hero(Brigitte) ? 5 : 3.500); + } + + actions + { + If(Hero Of(Event Player) == Hero(Reinhardt)); + Wait(0.100, Ignore Condition); + End; + Call Subroutine(GateRepair); + If(Hero Of(Event Player) == Hero(Torbjörn)); + Wait(Is Using Ability 2(Event Player) == True ? 0.350 : 0.700, Ignore Condition); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Wait(0.850, Ignore Condition); + Else; + Wait(0.500, Ignore Condition); + End; + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GATE PROGRESS BAR COLOR") +{ + event + { + Subroutine; + GateProgressBarColor; + } + + actions + { + Stop Chasing Global Variable(gateHealthChase); + Chase Global Variable Over Time(gateHealthChase, Global.gateHealth, 0.100, Destination and Duration); + "GATE WAS DAMAGED" + If(Global.gateHealth < Global.gateHealthEvent); + For Global Variable(loopIterator1, 0, 3, 1); + Global.gateProgressBarColorCurrent = Color(Red); + Wait(0.030, Ignore Condition); + Global.gateProgressBarColorCurrent = Color(White); + Wait(0.030, Ignore Condition); + End; + "GATE WAS REPAIRED" + Else; + Global.gateProgressBarColorCurrent = Color(Green); + Wait(0.030, Ignore Condition); + Global.gateProgressBarColorCurrent = Color(Yellow); + Wait(0.030, Ignore Condition); + End; + Global.gateHealthEvent = Global.gateHealth; + Global.gateProgressBarColorComponent = Global.gateHealth * 255 / Global.gateMaxHealth; + Global.gateProgressBarColorCurrent = Custom Color(255, Global.gateProgressBarColorComponent, Global.gateProgressBarColorComponent, + 255); + } +} + +disabled rule("=== COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("ALL: INIT") +{ + event + { + Player Joined Match; + All; + All; + } + + actions + { + "ALL (COMMON) INIT" + Event Player.isDead = True; + Disable Kill Feed(Event Player); + Disable Game Mode In-World UI(Event Player); + Disable Death Spectate Target HUD(Event Player); + "BOT INIT" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotInit); + "PLAYER INIT" + Else; + Call Subroutine(PlayerInit); + End; + } +} + +rule("SUBROUTINE: BOT - INIT") +{ + event + { + Subroutine; + BotInit; + } + + actions + { + "INIT VARS" + Event Player.hasBadStatus = False; + Event Player.isRespawning = False; + Event Player.botDoesUniqueBehaviour = False; + Event Player.botEventPosition = Vector(9999, 999, 9999); + "DISABLE ALL FOR BOT" + Disable Hero HUD(Event Player); + Disable Messages(Event Player); + Disable Text Chat(Event Player); + Disable Scoreboard(Event Player); + Disable Game Mode HUD(Event Player); + Disable Death Spectate All Players(Event Player); + Disable Voice Chat(Event Player, True, True, True); + "INIT AI NAVIGATION VARS" + Call Subroutine(BotResetPathFinding); + } +} + +rule("SUBROUTINE: PLAYER - INIT") +{ + event + { + Subroutine; + PlayerInit; + } + + actions + { + "TEAM CHALLENGE - PLAYER'S MAX HEALTH" + If(Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[0]); + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + End; + If(Is Game In Progress); + Disable Game Mode HUD(Event Player); + End; + } +} + +rule("ALL: RESPAWN") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + (Hero Of(Event Player) != Event Player.currentHero || Event Player.isDead == True) == True; + } + + actions + { + Event Player.isDead = False; + "BOT RESPAWN" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotRespawn); + If(Global.isDebugAINavigation); + Create Beam Effect(All Players(All Teams), Good Beam, Eye Position(Event Player), Event Player.botNextNodePosition, Color(Green), + Visible To Position and Radius); + End; + "PLAYER RESPAWN" + Else; + Call Subroutine(PlayerRespawn); + End; + "MUST BE AFTER ALL RESPAWN SUBROUTINES!" + Event Player.currentHero = Hero Of(Event Player); + } +} + +rule("SUBROUTINE: BOT - RESPAWN") +{ + event + { + Subroutine; + BotRespawn; + } + + actions + { + "RESET COMMON PROPERTIES" + Event Player.isRespawning = True; + Enable Nameplates(Event Player, All Players(Team 1)); + Call Subroutine(BotResetPathFinding); + disabled If(Hero Of(Event Player) != Event Player.currentHero); + Call Subroutine(GameLogicSetBotProperties); + disabled End; + "INDIVIDUAL HERO'S RESPAWN SCRIPTS" + If(Hero Of(Event Player) == Hero(Bastion)); + Call Subroutine(BotBastionRespawn); + Else If(Hero Of(Event Player) == Hero(Zenyatta)); + Call Subroutine(BotZenyattaRespawn); + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + Call Subroutine(BotWidowRespawn); + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Call Subroutine(BotBallRespawn); + Else If(Hero Of(Event Player) == Hero(Orisa)); + Call Subroutine(BotOrisaRespawn); + Else If(Hero Of(Event Player) == Hero(Echo)); + Call Subroutine(BotEchoRespawn); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Call Subroutine(BotReinRespawn); + End; + Event Player.isRespawning = False; + } +} + +rule("SUBROUTINE: PLAYER - RESPAWN") +{ + event + { + Subroutine; + PlayerRespawn; + } + + actions + { + "TEAM CHALLENGE - MAX AMMO" + If(Hero Of(Event Player) != Event Player.currentHero && Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[0]); + Set Max Ammo(Event Player, 0, Ammo(Event Player, 0) * 2); + Set Max Ammo(Event Player, 1, Ammo(Event Player, 1) * 2); + Set Ammo(Event Player, 0, Max Ammo(Event Player, 0)); + Set Ammo(Event Player, 1, Max Ammo(Event Player, 1)); + End; + "MUST BE AFTER TEAM CHALLENGE MAX AMMO!" + disabled Event Player.currentHero = Hero Of(Event Player); + "PLAYER RESPAWN" + Set Status(Event Player, Null, Phased Out, 3); + Set Facing(Event Player, Vector(-1, 0, 0), To World); + If(Ability Cooldown(Players On Hero(Hero(Mercy), Team 1), Button(Ability 2)) >= 30 * (Players On Hero(Hero(Mercy), Team 1) + .abilities[6] ? Players On Hero(Hero(Mercy), Team 1).abilities[6] * 0.250 : 1) - 1); + Wait(0.250, Ignore Condition); + Teleport(Event Player, Event Player.deathPosition); + Else; + Teleport(Event Player, Global.playerSpawnPositions[Slot Of(Event Player) == Count Of(Global.playerSpawnPositions) ? Random Integer( + 0, Count Of(Global.playerSpawnPositions) - 1) : Slot Of(Event Player)]); + End; + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + } +} + +rule("PLAYER: DEATH") +{ + event + { + Player Died; + Team 1; + All; + } + + actions + { + If(Hero Of(Event Player) == Hero(Roadhog)); + Event Player.abilities[8] -= 1; + Wait(Global.perk[2] ? 5 : 10, Ignore Condition); + Event Player.abilities[8] += 1; + End; + Event Player.deathPosition = Position Of(Event Player); + disabled If(Event Player.lastSecondWind > 0); + disabled Event Player.lastSecondWind = 0; + disabled End; + Event Player.isDead = True; + } +} + +rule("BOT: DEATH") +{ + event + { + Player Died; + Team 2; + All; + } + + actions + { + If(Event Player.isBoss == 1); + If(Global.upgradePerkSharpshooterValue >= Global.upgradeCriticalDamageMaxValue[1]); + If(Global.upgradeBossHealthValue < Global.upgradeCriticalDamageMaxValue[2]); + Global.upgradeBossHealthValue += 1; + Small Message(All Players(Team 1), Custom String("-10% BOSS HEALTH CHALLENGE +1")); + End; + End; + Event Player.isBoss = 0; + Global.activeBoss = Null; + Big Message(All Players(Team 1), Custom String("BOSS DIED - {0}", Hero Of(Event Player))); + End; + Event Player.isDead = True; + Event Player.hasBadStatus = False; + Event Player.botDoesUniqueBehaviour = False; + Disable Nameplates(Event Player, All Players(Team 1)); + disabled Stop Holding Button(Event Player, Button(Ability 1)); + disabled Stop Holding Button(Event Player, Button(Primary Fire)); + disabled Stop Holding Button(Event Player, Button(Secondary Fire)); + "BOT HAS 1 EFFECT IN VAR (NOT ARRAY)" + Skip If(!Entity Exists(Event Player.botEffects), 1); + Destroy Effect(Event Player.botEffects); + "BOT HAS MORE THEN 1 EFFECT IN VAR (ARRAY)" + Skip If(Count Of(Event Player.botEffects) == 0, 3); + For Player Variable(Event Player, botLoopIterator1, 0, Count Of(Event Player.botEffects), 1); + Destroy Effect(Event Player.botEffects[Event Player.botLoopIterator1]); + End; + } +} + +disabled rule("=== BOT COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BAD STATUS") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.hasBadStatus == False; + (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + Event Player.hasBadStatus = True; + "PROCESS BAD STATUS" + If(Hero Of(Event Player) == Hero(Widowmaker)); + Start Rule(BotWidowBadStatus, Do Nothing); + End; + Wait Until(!Has Status(Event Player, Knocked Down) && !Has Status(Event Player, Asleep) && !Has Status(Event Player, Frozen) + && !Has Status(Event Player, Stunned), 15); + Event Player.hasBadStatus = False; + } +} + +rule("SUBROUTINE: BOT - LANDING FROM SKY") +{ + event + { + Subroutine; + BotLandingFromSky; + } + + actions + { + Stop Throttle In Direction(Event Player); + "SET RESPAWN POSITION" + Event Player.botEventPosition = Random Value In Array(Global.bigBossSpawnPositions); + "CREATE EFFECTS" + disabled Create Effect(All Players(All Teams), Light Shaft, Color(Red), Event Player.botEventPosition, 3, Visible To); + disabled Event Player.botEffects = Last Created Entity; + "RESPAWN IN LIGHT SHAFT EFFECT" + Teleport(Event Player, Event Player.botEventPosition + Vector(0, 25, 0)); + Wait(0.020, Ignore Condition); + "SLOW LANDING" + Set Gravity(Event Player, 50); + While(Is In Air(Event Player) == True); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Position Of(Event Player) + Vector(0, -2.700, 0), 2); + Wait(0.250, Ignore Condition); + End; + Set Gravity(Event Player, 100); + disabled Destroy Effect(Event Player.botEffects); + "LANDING EFFECTS" + Play Effect(All Players(All Teams), Wrecking Ball Piledriver Impact Effect, Custom Color(105, 87, 46, 255), Position Of( + Event Player), 8); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Sound, Color(White), Position Of(Event Player), 150); + } +} + +rule("SUBROUTINE: BOT - APPEAR FROM UNDERGROUND") +{ + event + { + Subroutine; + BotAppearFromUnderground; + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1); + Wait(0.200, Ignore Condition); + Set Gravity(Event Player, 20); + Disable Movement Collision With Environment(Event Player, True); + Teleport(Event Player, Global.zenSpawnPositions[Random Integer(Min(Global.timeMinutes, Count Of(Global.zenSpawnPositions) - 10), + Min(Global.spawnPositionMaxId, Count Of(Global.zenSpawnPositions) - 4))] + Vector(0, -1.500, 0)); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Sigma Accretion Impact Effect, Custom Color(220, 175, 100, 255), Eye Position(Event Player), + 3); + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(Gray), Eye Position(Event Player), 50); + Apply Impulse(Event Player, Up, 3.500, To World, Cancel Contrary Motion); + Wait(0.400, Ignore Condition); + Clear Status(Event Player, Knocked Down); + Set Gravity(Event Player, 100); + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("=== PLAYER MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("PLAYER: DARKNESS") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + !Entity Exists(Event Player.botEffects) == True; + } + + actions + { + Disable Nameplates(Event Player, All Players(All Teams)); + Start Forcing Player Outlines(Event Player, All Players(All Teams), False, Color(White), Default); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 14), 25, Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(-5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + Create Effect(Event Player, Bad Aura, Color(Black), Update Every Frame(Eye Position(Event Player) + World Vector Of(Vector(5, 0, + 3), Event Player, Rotation) + Facing Direction Of(Event Player) * 10), 25, Visible To Position and Radius); + } +} + +rule("PLAYER: HEALTH REGEN") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + actions + { + Stop Heal Over Time(Event Player.healOverTimeId); + Event Player.eventHealth = Health(Event Player); + Wait(4, Ignore Condition); + "TOOK DAMAGE, RESET REGENERATION TIMER" + Loop If(Is Alive(Event Player) && Event Player.eventHealth > Health(Event Player)); + Start Heal Over Time(Event Player, Null, 3, Max Health(Event Player) / 3); + Event Player.healOverTimeId = Last Heal Over Time ID; + } +} + +disabled rule("=== NERFS ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("REINHARDT: ANTI-CHARGE FOR BASTION & ORISA") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Using Ability 1(Event Player) == True; + Hero Of(Ray Cast Hit Player(Eye Position(Event Player) + Vector(0, 2, 0), Eye Position(Event Player) + Vector(0, 2, 0) + + Facing Direction Of(Event Player) * 2, All Living Players(Team 2), Event Player, True)) == (Hero(Bastion) == True || Hero( + Orisa) == True); + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1.500); + } +} + +rule("HOG: ANTI-HOOK FOR BASTION & ORISA") +{ + event + { + Player Dealt Damage; + Team 1; + Roadhog; + } + + conditions + { + Event Ability == Button(Ability 1); + (Hero Of(Victim) == Hero(Bastion) || Hero Of(Victim) == Hero(Orisa)) == True; + } + + actions + { + Set Status(Event Player, Null, Stunned, 0.005); + } +} + +disabled rule("=== ZENYATTA ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ZEN - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Zenyatta; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + } + + actions + { + Set Ammo(Event Player, 0, 0); + Communicate(Event Player, Hello); + disabled Call Subroutine(BotResetPathFinding); + Wait(1.500, Ignore Condition); + Abort If(Is Dead(Event Player) == True); + Kill(Event Player, Null); + } +} + +rule("BOT: ZEN - DEATH") +{ + event + { + Player Died; + Team 2; + Zenyatta; + } + + actions + { + "EFFECT" + Play Effect(All Players(All Teams), Junkrat Frag Launcher Explosion Effect, Color(Red), Eye Position(Event Player), 2.500); + Play Effect(All Players(All Teams), Ashe Dynamite Explosion Sound, Color(Red), Eye Position(Event Player), 70); + "DAMAGE AND APPLY IMPULSE TO PLAYERS" + Event Player.botPlayersInRadius = Players Within Radius(Position Of(Event Player), 2.500, All Teams, Surfaces And Enemy Barriers); + For Player Variable(Event Player, botLoopIterator1, 0, Count Of(Event Player.botPlayersInRadius), 1); + Apply Impulse(Event Player.botPlayersInRadius[Event Player.botLoopIterator1], Direction Towards(Position Of(Event Player), + Eye Position(Event Player.botPlayersInRadius[Event Player.botLoopIterator1])), 5, To World, Incorporate Contrary Motion); + If(Team Of(Event Player.botPlayersInRadius[Event Player.botLoopIterator1]) == Team 1); + Damage(Event Player.botPlayersInRadius[Event Player.botLoopIterator1], Event Player, 50); + End; + End; + "DAMAGE GATE" + If(Distance Between(Position Of(Event Player), Global.gatePosition) < 3 && Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.gateHealth -= 125; + Else; + Global.gateHealth -= 25 + 5 * Global.time5Minutes; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Respawn(Event Player); + Abort; + End; + "KILLED BY PLAYER" + Teleport(Event Player, Vector(0, -999, 0)); + Wait(2, Ignore Condition); + Respawn(Event Player); + Wait(2, Ignore Condition); + } +} + +rule("SUBROUTINE: ZEN - RESPAWN") +{ + event + { + Subroutine; + BotZenyattaRespawn; + } + + actions + { + Call Subroutine(BotAppearFromUnderground); + Event Player.botTargetPosition = Global.gatePosition; + Event Player.botIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WRECKING BALL ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BALL - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + disabled Distance Between(Position Of(Event Player), Global.gatePosition) < 3; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Set Ammo(Event Player, 0, 0); + Wait(1, Ignore Condition); + Set Ultimate Charge(Event Player, 100); + Start Holding Button(Event Player, Button(Ultimate)); + Wait Until(Is Using Ultimate(Event Player), 0.600); + Abort If(Is Dead(Event Player)); + Kill(Event Player, Null); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Effect, Color(Orange), Eye Position(Event Player), 6); + Play Effect(All Players(All Teams), DVa Self Destruct Explosion Sound, Color(White), Eye Position(Event Player), 250); + If(Distance Between(Position Of(Event Player), Global.gatePosition) < 3.500 && Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.gateHealth -= 300; + Else; + Global.gateHealth -= 150 + 10 * Global.time5Minutes; + End; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Damage(Players Within Radius(Eye Position(Event Player), 7, Team 1, Surfaces And All Barriers), Event Player, 200); + } +} + +rule("BOT: BALL - ALTERNATIVE FORM") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is In Alternate Form(Event Player) == False; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is In Alternate Form(Event Player), 10); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: BALL - DEATH") +{ + event + { + Player Died; + Team 2; + Wrecking Ball; + } + + actions + { + Stop Holding Button(Event Player, Button(Ability 1)); + Stop Holding Button(Event Player, Button(Ultimate)); + } +} + +rule("SUBROUTINE: BALL - RESPAWN") +{ + event + { + Subroutine; + BotBallRespawn; + } + + actions + { + "RESPAWN IN AIR" + Teleport(Event Player, Random Value In Array(Global.ballSpawnPositions) + Vector(0, 20, 0)); + Stop Holding Button(Event Player, Button(Ultimate)); + Wait(0.250, Ignore Condition); + "LANDING" + Start Holding Button(Event Player, Button(Crouch)); + Wait Until(Is On Ground(Event Player), 9999); + Stop Holding Button(Event Player, Button(Crouch)); + "LANDING IMPACT EFFECT" + Play Effect(All Players(All Teams), Sigma Accretion Impact Sound, Color(White), Event Player, 150); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Effect, Color(Gray), Position Of(Event Player), 10); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Eye Position(Event Player), 1.500, Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + "PATH FINDING TO GATE" + Event Player.botTargetPosition = Global.gatePosition; + Event Player.botIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +disabled rule("=== ECHO ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ECHO - FLY ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Is Using Ability 1(Event Player) == False; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), 0); + Press Button(Event Player, Button(Ability 1)); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - BEAM ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Is Using Ability 1(Event Player) == False; + Event Player.botDoesUniqueBehaviour == True; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - BAD STATUS - RESET BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.hasBadStatus == True; + disabled (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + If(Event Player.botDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + Wait Until(Event Player.hasBadStatus, 7); + } +} + +rule("BOT: ECHO - CAN'T SEE PORTAL - APPLY IMPULSE") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == True; + Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Wait(0.300, Abort When False); + Apply Impulse(Event Player, Vector(Random Integer(-1, 1), 1, Random Integer(-1, 1)), 20, To World, Incorporate Contrary Motion); + Wait(1, Ignore Condition); + If(!Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS)); + Event Player.botTargetPosition = Global.botEchoRespawnPosition; + Start Rule(BotStartPathFinding, Restart Rule); + Else; + Call Subroutine(BotResetPathFinding); + End; + Loop If Condition Is True; + } +} + +disabled rule("BOT: ECHO - MAIN LOGIC - BACKUP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + } + + actions + { + If(!Event Player.botIsPathFinding); + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Is In Line of Sight(Eye Position(Event Player), + Eye Position(Current Array Element), Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), + Position Of(Current Array Element)))[0]; + End; + "NO PLAYERS IN VIEW RANGE" + disabled If(Event Player.botSeePlayer == Null); + disabled Stop Throttle In Direction(Event Player); + disabled End; + "FLY TO PLAYER" + If(Event Player.botSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) + > 4 && Event Player.botDoesUniqueBehaviour == False); + Event Player.botTargetPlayer = Event Player.botSeePlayer; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + "ACTIVATE FOCUS BEAM" + Else If(Event Player.botSeePlayer != Null && Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) + < 4 && Event Player.botDoesUniqueBehaviour == False && Event Player.hasBadStatus == False); + Event Player.botDoesUniqueBehaviour = True; + Set Status(Event Player.botSeePlayer, Event Player, Stunned, 1); + Set Status(Event Player.botSeePlayer, Event Player, Hacked, 99999); + Attach Players(Event Player.botSeePlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + "TELEPORT PLAYER TO AWAY" + Else If(Event Player.botDoesUniqueBehaviour && Distance Between(Position Of(Event Player.botSeePlayer), + Global.botEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.botEchoRespawnPosition, 1); + Teleport(Event Player.botSeePlayer, Random Value In Array(Global.botEchoTeleportPositions)); + Set Status(Event Player.botSeePlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + "BEGIN TO FLY TO THE PORTAL" + Else If(Event Player.botDoesUniqueBehaviour == True); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.botIsPathFinding); + Event Player.botTargetPlayer = Event Player.botSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + } + + actions + { + If(Event Player.botDoesUniqueBehaviour == False); + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + End; + "TELEPORT PLAYER SO FAR" + If(Event Player.botDoesUniqueBehaviour && Distance Between(Position Of(Event Player.botEchoCapturedPlayer), + Global.botEchoRespawnPosition) < 4); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Global.botEchoRespawnPosition, 1); + Teleport(Event Player.botEchoCapturedPlayer, Random Value In Array(Global.botEchoTeleportPositions)); + Set Status(Event Player.botEchoCapturedPlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + End; + "BEGIN TO FLY TO THE PORTAL WITH A PLAYER" + If(Event Player.botDoesUniqueBehaviour); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.botIsPathFinding); + Event Player.botTargetPlayer = Event Player.botEchoCapturedPlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - DEFEND PORTAL") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer == Null; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer), Barriers Do Not Block LOS) == True; + } + + actions + { + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPlayer); + } +} + +rule("BOT: ECHO - PATH FINDING TO PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Event Player.botDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer), Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.botTargetPlayer = Event Player.botSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Call Subroutine(BotStartPathFinding); + } +} + +rule("BOT: ECHO - ATTACH PLAYER BY BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.hasBadStatus == False; + Event Player.botSeePlayer != Null; + Event Player.isRespawning == False; + Event Player.botEchoCapturedPlayer == Null; + Event Player.botDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer), Barriers Do Not Block LOS) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) < 3; + } + + actions + { + Event Player.botDoesUniqueBehaviour = True; + Event Player.botEchoCapturedPlayer = Event Player.botSeePlayer; + Set Status(Event Player.botEchoCapturedPlayer, Event Player, Stunned, 0.700); + Set Status(Event Player.botEchoCapturedPlayer, Event Player, Hacked, 10); + Attach Players(Event Player.botEchoCapturedPlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - PLAYER DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Is Dead(Event Player.botEchoCapturedPlayer) != Null; + } + + actions + { + If(Event Player.botDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - DEATH") +{ + event + { + Player Died; + Team 2; + Echo; + } + + actions + { + Call Subroutine(BotEchoDetachPlayer); + Stop Holding Button(Event Player, Button(Jump)); + Wait(5, Ignore Condition); + Teleport(Event Player, Vector(0, 999, 0)); + Start Forcing Player To Be Hero(Event Player, Hero(Orisa)); + } +} + +rule("SUBROUTINE: ECHO - RESPAWN") +{ + event + { + Subroutine; + BotEchoRespawn; + } + + actions + { + Event Player.botCounter = 0; + Event Player.botEffects = Empty Array; + Create Effect(All Players(All Teams), Good Aura, Color(Sky Blue), Global.botEchoRespawnPosition, Event Player.botCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, botEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Global.botEchoRespawnPosition, Event Player.botCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, botEffects, Append To Array, Last Created Entity); + Create Effect(All Players(All Teams), Energy Sound, Color(White), Global.botEchoRespawnPosition, 200, Visible To); + Modify Player Variable(Event Player, botEffects, Append To Array, Last Created Entity); + Chase Player Variable Over Time(Event Player, botCounter, 3, 0.800, Destination and Duration); + Play Effect(All Players(All Teams), Sombra EMP Explosion Effect, Color(Sky Blue), Global.botEchoRespawnPosition, 12); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Null, Global.botEchoRespawnPosition, 100); + Wait(3, Ignore Condition); + Teleport(Event Player, Global.botEchoRespawnPosition); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Global.botEchoRespawnPosition, 2.500); + Play Effect(All Players(All Teams), Debuff Impact Sound, Null, Global.botEchoRespawnPosition, 100); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PLAYER") +{ + event + { + Subroutine; + BotEchoFlyToPlayer; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Stop Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PORTAL") +{ + event + { + Subroutine; + BotEchoFlyToPortal; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - DETACH PLAYER") +{ + event + { + Subroutine; + BotEchoDetachPlayer; + } + + actions + { + Detach Players(Event Player.botEchoCapturedPlayer); + Clear Status(Event Player.botEchoCapturedPlayer, Hacked); + "IF PLAYER INSIDE THE WALL" + If(Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botEchoCapturedPlayer), Barriers Do Not Block LOS)); + Teleport(Event Player.botEchoCapturedPlayer, Position Of(Event Player)); + End; + Event Player.botDoesUniqueBehaviour = False; + Event Player.botEchoCapturedPlayer = Null; + } +} + +disabled rule("=== REINHARDT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: REIN - SET PLAYER AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + disabled Event Player.botIsPathFinding == False; + "BOT IS FAR FROM GATES" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Global.gatePosition), 0, Z Component Of(Global.gatePosition))) > 20; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET CLOSEST PLAYER TO BOT AS TARGET AND FOLLOW HIM" + Event Player.botTargetPlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Position Of(Event Player.botTargetPlayer)), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - SET GATE AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + "BOT DOESN'T FOLLOW PLAYER" + Event Player.botTargetPlayer == -1; + "CAN'T SEE ANY PLAYER" + disabled Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), !Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET GATE AS TARGET" + Event Player.botTargetPosition = Global.gatePosition; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - TARGET DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botTargetPlayer != -1; + Is Dead(Event Player.botTargetPlayer) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + } +} + +rule("BOT: REIN - ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) + : Global.gatePosition) < 4; + "CAN ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) : Global.gatePosition), 0, + Z Component Of(Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) : Global.gatePosition))) < 4; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + "TARGET IS PLAYER" + Abort If(Event Player.botTargetPlayer != -1); + If(Event Player.isBoss == 1); + "TARGET IS GATE" + Global.gateHealth -= 25 + 10 * Global.time10Minutes; + Else; + Global.gateHealth -= 5 + 5 * Global.time5Minutes; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: REIN - STOP ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) + : Global.gatePosition) > 4; + "CAN'T ATTACK TARGET (2D DISTANCE)" + disabled Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) : Global.gatePosition), 0, + Z Component Of(Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) : Global.gatePosition))) > 4; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + } +} + +rule("BOT: REIN - USE SHIELD") +{ + event + { + Player Took Damage; + Team 2; + Reinhardt; + } + + conditions + { + Distance Between(Position Of(Event Player), Position Of(Event Player.botTargetPlayer)) > 3; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Attacker)), 200, To World, + Direction and Turn Rate); + Start Holding Button(Event Player, Button(Secondary Fire)); + Wait Until(Distance Between(Position Of(Event Player), Position Of(Event Player.botTargetPlayer)) < 3, 3); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("BOT: REIN - CHARGE IN GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botTargetPlayer == -1; + Is Using Ability 1(Event Player) == False; + Is In Line of Sight(Eye Position(Event Player), Global.gatePosition, Barriers Do Not Block LOS) == True; + Is In View Angle(Event Player, Global.gatePosition, 7.500) == True; + } + + actions + { + disabled Wait(0.800, Abort When False); + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is Using Ability 1(Event Player), 1); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: REIN - DEATH") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("SUBROUTINE: REIN - RESPAWN") +{ + event + { + Subroutine; + BotReinRespawn; + } + + actions + { + Call Subroutine(BotAppearFromUnderground); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WIDOW ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: WIDOW - SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.botSeePlayer == Null; + Event Player.hasBadStatus == False; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Event Player.botWidowShotTime = Total Time Elapsed + (Global.timeMinutes >= 9 ? Random Real(2, 5) : Random Real(5, 10)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), 9999, To World, + Direction and Turn Rate); + } +} + +rule("BOT: WIDOW - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.botSeePlayer != Null; + Event Player.hasBadStatus == False; + Total Time Elapsed >= Event Player.botWidowShotTime; + } + + actions + { + Press Button(Event Player, Button(Primary Fire)); + Stop Facing(Event Player); + Event Player.botSeePlayer = Null; + } +} + +rule("BOT: WIDOW - Aim Sound") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Alive(Event Player) == True; + Is In Line of Sight(Eye Position(Players On Hero(Hero(Widowmaker), Team 2)), Eye Position(Event Player), Barriers Do Not Block LOS) + == True; + Is Alive(Players On Hero(Hero(Widowmaker), Team 2)) == True; + Players On Hero(Hero(Widowmaker), Team 2).botSeePlayer == True; + } + + actions + { + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 100); + Wait(1, Abort When False); + Loop If Condition Is True; + } +} + +rule("BOT: WIDOW - TELEPORT TO NEW POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.hasBadStatus == False; + Total Time Elapsed >= Event Player.botWidowTeleportTime; + } + + actions + { + Event Player.botWidowTeleportTime = Total Time Elapsed + 28; + Event Player.botWidowShotTime = Total Time Elapsed + (Global.timeMinutes >= 9 ? Random Real(1, 3) : Random Real(3, 6)); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(White), Event Player, 1); + Wait(0.016, Ignore Condition); + Teleport(Event Player, Filtered Array(Global.sniperPositions, Distance Between(Event Player.botEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.sniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.botEventPosition = Position Of(Event Player); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + } +} + +rule("BOT: WIDOW - DEATH") +{ + event + { + Player Died; + Team 2; + Widowmaker; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + Wait(0.250, Ignore Condition); + Destroy Effect(Event Player.botEffects); + } +} + +rule("SUBROUTINE: WIDOW - RESPAWN") +{ + event + { + Subroutine; + BotWidowRespawn; + } + + actions + { + "RESPAWN ON RANDOM SNIPER POSITION" + Teleport(Event Player, Filtered Array(Global.sniperPositions, Distance Between(Event Player.botEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.sniperPositions) - 2)]); + Wait(0.020, Ignore Condition); + Event Player.botEventPosition = Position Of(Event Player); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player, 100); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Wait(0.700, Ignore Condition); + Start Holding Button(Event Player, Button(Secondary Fire)); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + Wait Until(Is Dead(Event Player), 99999); + Destroy Effect(Event Player.botEffects); + } +} + +rule("SUBROUTINE: WIDOW - BAD STATUS") +{ + event + { + Subroutine; + BotWidowBadStatus; + } + + actions + { + Stop Facing(Event Player); + Destroy Effect(Event Player.botEffects); + Wait Until(!Event Player.hasBadStatus, 15); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + } +} + +disabled rule("=== BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +disabled rule("BOT: BASTION - FLAME GUN") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.botDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.botSeePlayer), 50) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) < 8; + } + + actions + { + Event Player.botDoesUniqueBehaviour = True; + Stop Holding Button(Event Player, Button(Primary Fire)); + Create Effect(All Players(All Teams), Bad Aura, Color(Orange), Update Every Frame(Eye Position(Event Player) + World Vector Of( + Vector(-1, -1.200, 1.800), Event Player, Rotation)), 1, Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + Start Rule(BotBastionFlameGunDamage, Do Nothing); + Wait(1.100, Ignore Condition); + Destroy Effect(Event Player.botEffects); + Wait(4, Ignore Condition); + Loop If Condition Is True; + } +} + +disabled rule("BOT: BASTION - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + disabled Event Player.botSeePlayer == Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - CAN'T SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element)), Is In Line of Sight(Eye Position( + Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS)) == False; + } + + actions + { + Event Player.botSeePlayer = Null; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 100, To World, + Direction and Turn Rate); + } +} + +disabled rule("BOT: BASTION - MOVE TO BASTION'S TARGET (POSITION)") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Event Player.botTargetPosition = Random Value In Array(Filtered Array(Global.bastionTargetPositions, Distance Between(Position Of( + Event Player), Current Array Element) > 3.500)); + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("BOT: BASTION - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), Barriers Do Not Block LOS) + == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + "SEE THE PLAYER" + If(Event Player.botSeePlayer != Null); + Stop Holding Button(Event Player, Button(Secondary Fire)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer) - Vector(0, 0.500, + 0)), 100, To World, Direction and Turn Rate); + "SELF REPAIRING" + Else If(!Is Firing Secondary(Event Player) && Health(Event Player) < Max Health(Event Player)); + Start Holding Button(Event Player, Button(Secondary Fire)); + End; + "START FOLLOW PATH" + disabled If(!Event Player.botIsPathFinding && !Event Player.botDoesUniqueBehaviour); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled Wait(0.050, Ignore Condition); + disabled Event Player.botTargetPosition = Random Value In Array(Global.bastionTargetPositions); + disabled Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Event Player.botTargetPosition + Vector(0, 2, 0)), 100, + To World, Direction and Turn Rate); + disabled Start Rule(BotStartPathFinding, Do Nothing); + "REACHED PATH TARGET" + disabled Else If(Distance Between(Position Of(Event Player), Event Player.botTargetPosition) <= 3); + disabled Start Rule(BotResetPathFinding, Do Nothing); + disabled End; + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - ARTILLERY") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.botDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.botSeePlayer), 30) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) > 18; + Distance Between(Eye Position(Event Player), Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Up * 99, Null, Event Player, False)) >= 35; + } + + actions + { + "TRYING TO CAPTURE TARGET" + Wait(0.800, Abort When False); + "CAPTURE TARGET" + Event Player.botDoesUniqueBehaviour = True; + Stop Throttle In Direction(Event Player); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Update Every Frame(Eye Position(Event Player)), + Update Every Frame(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 1000, All Living Players(Team 1), Event Player, True)), Color(Sky Blue), Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + Wait(1.400, Ignore Condition); + Destroy Effect(Event Player.botEffects); + Abort If(Is Dead(Event Player)); + Event Player.botEventPosition = Position Of(Event Player.botSeePlayer); + "SHOOT FROM ARTILLERY" + Event Player.botBastionArtilleryDidShotsCount = 0; + For Player Variable(Event Player, botLoopIterator1, 0, 4, 1); + Event Player.botBastionArtilleryDidShotsCount += 1; + Play Effect(All Players(All Teams), Wrecking Ball Minefield Explosion Sound, Color(White), Eye Position(Event Player), 250); + Play Effect(All Players(All Teams), Pharah Barrage Explosion Effect, Color(Orange), Eye Position(Event Player) + World Vector Of( + Vector(0, 1.400, -0.700), Event Player, Rotation), 2); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) + World Vector Of(Vector(0, 1.400, + -0.700), Event Player, Rotation), Eye Position(Event Player) + World Vector Of(Vector(Random Real(-1, 1), Random Integer(40, + 80), Random Real(0.500, 1.500)), Event Player, Rotation), Color(Orange), Visible To); + Event Player.botEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.botEffects); + Wait(0.400, Ignore Condition); + If(Is Dead(Event Player)); + Break; + End; + End; + disabled Call Subroutine(BotResetPathFinding); + disabled Start Rule(BotStartPathFinding, Do Nothing); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Wait(1.500, Ignore Condition); + Start Rule(BotBastionArtilleryDamage, Do Nothing); + Wait(4, Ignore Condition); + } +} + +rule("BOT: BASTION - PRIMARY FIRE") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Event Player.botDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.botSeePlayer), 40) == True; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Stop Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Bastion; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + For Player Variable(Event Player, botLoopIterator1, 0, 3, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Effect, Color(White), Event Player, 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player, 100); + Wait(0.250, Ignore Condition); + End; + } +} + +rule("SUBROUTINE: BASTION - RESPAWN") +{ + event + { + Subroutine; + BotBastionRespawn; + } + + actions + { + Abort If(Event Player.botIsOrisaChild == True); + Call Subroutine(BotLandingFromSky); + Set Ammo(Event Player, 0, 0); + Wait Until(!Is Reloading(Event Player), 99999); + Event Player.botTargetPosition = Objective Position(2); + } +} + +rule("SUBROUTINE: BASTION - ARTILLERY DAMAGE") +{ + event + { + Subroutine; + BotBastionArtilleryDamage; + } + + actions + { + Event Player.botDoesUniqueBehaviour = False; + "EXPLOSIONS OF ARTILLERY" + For Player Variable(Event Player, botLoopIterator2, 0, Event Player.botBastionArtilleryDidShotsCount, 1); + Event Player.botEventPosition = Ray Cast Hit Position(Event Player.botEventPosition + Vector(0, 50, 0), + Event Player.botEventPosition + Vector(Random Integer(-4, 4), -15, Random Integer(-4, 4)), Null, Event Player, True); + Damage(Players Within Radius(Event Player.botEventPosition, 8, Team 1, Surfaces And Enemy Barriers), Event Player, 50); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Event Player.botEventPosition, 150); + Play Effect(All Players(All Teams), Pharah Rocket Launcher Explosion Effect, Color(Orange), Event Player.botEventPosition, 5); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Event Player.botEventPosition, + Event Player.botEventPosition + Vector(0, 60, 0), Color(Orange), Visible To); + Event Player.botEffects = Last Created Entity; + Wait(0.050, Ignore Condition); + Destroy Effect(Event Player.botEffects); + Wait(0.400, Ignore Condition); + End; + } +} + +disabled rule("SUBROUTINE: BASTION - FLAME GUN DAMAGE") +{ + event + { + Subroutine; + BotBastionFlameGunDamage; + } + + actions + { + Event Player.botRayCastHitPosition = Eye Position(Event Player) + World Vector Of(Vector(-1, -1.200, 1.800), Event Player, + Rotation); + "FIRE PARTICLES OF FLAME GUN" + For Player Variable(Event Player, botLoopIterator1, 1, 13, 3); + Event Player.botEventPosition = Ray Cast Hit Position(Event Player.botRayCastHitPosition, + Event Player.botRayCastHitPosition + Facing Direction Of(Event Player) * Event Player.botLoopIterator1, Null, Event Player, + True); + Damage(Players Within Radius(Event Player.botEventPosition, 4, Team 1, Surfaces And Enemy Barriers), Event Player, 20); + Set Status(Players Within Radius(Event Player.botEventPosition, 4, Team 1, Off), Event Player, Burning, 2); + Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Event Player.botEventPosition, 150); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.botEventPosition, 2.500); + Wait(0.200, Ignore Condition); + End; + Event Player.botDoesUniqueBehaviour = False; + } +} + +disabled rule("=== ORISA + BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ORISA-BASTION - REACHED TARGET POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botIsPathFinding == True; + Distance Between(Position Of(Event Player), Global.botOrisaTargetPosition) < 1.500; + } + + actions + { + Call Subroutine(BotResetPathFinding); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Vector(X Component Of(Global.gatePosition), -999, + Z Component Of(Global.gatePosition))), 80, To World, Direction and Turn Rate); + Start Facing(Global.botOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Barriers Do Not Block LOS) ? Global.gatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + disabled Start Facing(Global.botOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Barriers Do Not Block LOS) ? Global.gatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element) && Is In Line of Sight(Eye Position(Event Player), Position Of(Current Array Element), + Barriers Do Not Block LOS)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + Press Button(Event Player, Button(Ability 1)); + Wait Until(Y Component Of(Facing Direction Of(Event Player)) < -0.300, 99999); + Press Button(Event Player, Button(Ability 2)); + Wait(0.800, Ignore Condition); + Global.botOrisaChild.botDoesUniqueBehaviour = False; + Disallow Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ORISA-BASTION - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Event Player.botDoesUniqueBehaviour = True; + While(Is Alive(Event Player)); + disabled Create Effect(All Players(All Teams), Bad Aura, Color(Purple), Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3.200, 1, Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + Wait(1.500, Ignore Condition); + Destroy Effect(Event Player.botEffects); + Abort If(Is Dead(Event Player)); + Press Button(Event Player, Button(Primary Fire)); + Press Button(Event Player, Button(Reload)); + Event Player.botRayCastHitPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Facing Direction Of(Event Player) * 999, All Players(Team 1), All Players(Team 2), True); + "ANTI-SHIELD BUG" + Event Player.botRayCastHitPosition = Event Player.botRayCastHitPosition + Direction Towards(Event Player.botRayCastHitPosition, + Eye Position(Event Player)) * 0.200; + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3, Event Player.botRayCastHitPosition, Color(Purple), Visible To Position and Radius); + Event Player.botEffects = Last Created Entity; + Damage(Players Within Radius(Event Player.botRayCastHitPosition, 4, Team 1, Surfaces And All Barriers), Event Player, 0.040); + Play Effect(All Players(All Teams), Pharah Concussive Blast Effect, Color(Purple), Event Player.botRayCastHitPosition, 4); + Play Effect(All Players(All Teams), Pharah Concussive Blast Sound, Color(Purple), Event Player.botRayCastHitPosition, 250); + Play Effect(All Players(All Teams), Bad Explosion, Color(Purple), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 3.300, 2); + Play Effect(All Players(All Teams), Sombra EMP Explosion Sound, Color(Purple), Eye Position(Event Player), 170); + If(Distance Between(Event Player.botRayCastHitPosition, Global.gatePosition) < 4 && Is In Line of Sight( + Event Player.botRayCastHitPosition, Global.gatePosition, Enemy Barriers Block LOS)); + Global.gateHealth -= 80 + 10 * Global.time5Minutes; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Wait(0.150, Ignore Condition); + Destroy Effect(Event Player.botEffects); + Wait(0.060, Ignore Condition); + Wait Until(!Is Reloading(Event Player), 2.500); + End; + } +} + +rule("BOT: ORISA-BASTION - CAN'T SEE THE TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Is In Line of Sight(Eye Position(Event Player), Global.gatePosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.botTargetPosition = Global.botOrisaTargetPosition; + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: ORISA-BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Orisa; + } + + actions + { + Allow Button(Event Player, Button(Ability 2)); + Kill(Global.botOrisaChild, Null); + Detach Players(Global.botOrisaChild); + Clear Status(Global.botOrisaChild, Phased Out); + Set Damage Dealt(Global.botOrisaChild, 100); + Global.botOrisaChild.botIsOrisaChild = False; + Global.botOrisaChild = Null; + Global.botOrisaParent = Null; + Start Forcing Player To Be Hero(Event Player, Hero(Widowmaker)); + } +} + +rule("SUBROUTINE: ORISA - RESPAWN") +{ + event + { + Subroutine; + BotOrisaRespawn; + } + + actions + { + Global.botOrisaParent = Event Player; + "WAITING FOR ANY BASTION TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero(Bastion)), + 99999); + "SETUP BASTION AS CHILD" + Global.botOrisaChild = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Bastion))[0]; + Global.botOrisaChild.botIsOrisaChild = True; + Global.botOrisaChild.botDoesUniqueBehaviour = True; + Wait(2, Ignore Condition); + Respawn(Global.botOrisaChild); + Start Scaling Player(Global.botOrisaChild, 1.800, False); + Set Damage Dealt(Global.botOrisaChild, 2000); + Set Status(Global.botOrisaChild, Null, Phased Out, 9999); + Disable Nameplates(Global.botOrisaChild, All Players(All Teams)); + Set Facing(Global.botOrisaChild, Vector(X Component Of(Facing Direction Of(Event Player)), 9999, Z Component Of( + Facing Direction Of(Event Player))), To World); + Start Holding Button(Global.botOrisaChild, Button(Ability 1)); + Wait Until(Is In Alternate Form(Global.botOrisaChild), 5); + Stop Holding Button(Global.botOrisaChild, Button(Ability 1)); + Teleport(Global.botOrisaChild, Position Of(Event Player)); + Attach Players(Global.botOrisaChild, Global.botOrisaParent, Vector(0, 1.800, 0.230)); + disabled Wait(1, Ignore Condition); + disabled Stop Holding Button(Global.botOrisaChild, Button(Primary Fire)); + disabled Wait(0.250, Ignore Condition); + Call Subroutine(BotLandingFromSky); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + Event Player.botTargetPosition = Global.botOrisaTargetPosition; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 0 - ZENS, REINS, BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 0; + } + + actions + { + "CREATE BOTS - ZEN" + While(Count Of(All Players(Team 2)) < 13); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "BALL" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "REPLACE DEAD ZEN TO REIN" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) != 3); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 1 - WIDOW") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 1; + } + + actions + { + Global.isNewWaveGameLogicProcessing = True; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Global.isNewWaveGameLogicProcessing = False; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 3 - BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 3; + } + + actions + { + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 5 - REINS WAVE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 5; + } + + actions + { + "PREPARE WAVE - DESTROY WIDOW AND BALLS" + Destroy Dummy Bot(Team 2, Slot Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))[0])); + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))[0]; + Kill(Global.defaultCurrentBot, Null); + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + End; + "FAKE BOSS WAVE" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) < 6); + Wait Until(Is True For Any(All Players(Team 2), Distance Between(Position Of(Current Array Element), Global.gatePosition) + > 13 && Hero Of(Current Array Element) == Hero(Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + disabled Wait(0.200, Ignore Condition); + disabled Set Max Health(Global.defaultCurrentBot, 50); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) > 3); + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Reinhardt)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Reinhardt))[0]; + Wait(0.500, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(All Players(Team 2)) < 13); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 7 - BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 7; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 9 - ECHO, +1 BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 9; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) > 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Echo))) == 0); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) < 2); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + "FILL EMPTY SLOTS BY ZENS" + While(Count Of(All Players(Team 2)) < 12); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("Ana Nano Variable") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + } + + actions + { + Player Closest To Reticle(Event Player, Team 1).isNanoed = 1; + } +} + +rule("isNanoed") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isNanoed == True; + } + + actions + { + If(Is Dead(Event Player)); + Event Player.isNanoed = 0; + End; + Wait(8, Ignore Condition); + Event Player.isNanoed = 0; + } +} + +rule("money on kill") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + actions + { + If(Hero Of(Victim) == Hero(Zenyatta)); + All Players(Team 1).money[0] += 5 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 10 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + If(Global.upgradeMaxAmmoValue < Global.upgradeMaxAmmoMaxValue[2]); + Global.upgradeMaxAmmoValue += (Victim.isBoss == 1 ? 10 : 1); + End; + Else If(Hero Of(Victim) == Hero(Reinhardt)); + All Players(Team 1).money[0] += 15 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 20 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Wrecking Ball)); + All Players(Team 1).money[0] += 25 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 25 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Widowmaker)); + All Players(Team 1).money[0] += 30 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 30 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Bastion)); + All Players(Team 1).money[0] += 50 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 50 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Echo)); + All Players(Team 1).money[0] += 75 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 75 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Orisa)); + All Players(Team 1).money[0] += 100 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 100 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + } +} + +rule("Abilities and Hero Talents by Shingen and LemonAid") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.damageDealt = 100; + Event Player.playerHealth = 100; + Event Player.money[0] = 2400 + Global.startMoney; + If(Custom String("{0}", Event Player) == Custom String("ShuriZma")); + Create HUD Text(Event Player, Custom String("Serverload: {0}, AVG {1}, Peak {2}", Server Load, Server Load Average, + Server Load Peak), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + End; + } +} + +rule("Team 1 (Ability): Headhunter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.abilities[1] == True; + Event Was Critical Hit == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.abilities[1] * 40 / Event Player.damageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Ambush") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Event Player.abilities[2] == True; + Event Ability != Null; + (Y Component Of(Position Of(Event Player)) - Y Component Of(Position Of(Victim)) >= 3 || Absolute Value(Horizontal Angle Towards( + Victim, Event Player)) >= 90) == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.abilities[2] * 30 / Event Player.damageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Quick Fix") +{ + event + { + Player Earned Elimination; + Team 1; + All; + } + + conditions + { + Event Player.abilities[3] == True; + } + + actions + { + Heal(Event Player, Null, Event Player.abilities[3] * 50); + Set Move Speed(Event Player, 100 + Event Player.abilities[3] * 20); + Wait(5, Restart When True); + Set Move Speed(Event Player, 100); + } +} + +rule("Team 1 (Ability): Heavyweight") +{ + event + { + Player Dealt Knockback; + Team 1; + All; + } + + conditions + { + Event Player.abilities[4] == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.abilities[4] * 25 / Event Player.damageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Charged") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[5] == True; + Ultimate Charge Percent(Event Player) < Event Player.abilities[5] * 20; + } + + actions + { + Set Ultimate Charge(Event Player, Event Player.abilities[5] * 20); + If(Is Duplicating(Event Player)); + Wait(0.016, Ignore Condition); + Set Ultimate Charge(Event Player, Event Player.abilities[5] * 20); + End; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Team 1 (Ability): Haste Primary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Primary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Primary Fire), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Primary Fire))); + } +} + +rule("Team 1 (Ability): Haste Secondary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Secondary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Secondary Fire), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Secondary Fire))); + } +} + +rule("Team 1 (Ability): Haste Ability 1") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 1)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 1))); + } +} + +rule("Team 1 (Ability): Haste Ability 2") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 2)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 2))); + } +} + +rule("Team 1 (Ability): Haste Jump") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Jump)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Jump), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, Button( + Jump))); + } +} + +rule("Team 1 (Ability): Haste Crouch") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Crouch)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Crouch), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, Button( + Crouch))); + } +} + +rule("Team 1 (Ability): Heavy Impact") +{ + event + { + Player Took Damage; + Team 2; + All; + } + + conditions + { + Attacker.abilities[7] == True; + } + + actions + { + Abort If(Random Real(-0.020, 1) > Event Damage / Max Health(Event Player)); + Set Status(Event Player, Attacker, Stunned, 1 * Attacker.abilities[7]); + Wait(5, Ignore Condition); + } +} + +rule("Team 1 (Ability): Binding Heal") +{ + event + { + Player Dealt Healing; + Team 1; + All; + } + + conditions + { + Event Player.abilities[10] == True; + Healee != Event Player; + } + + actions + { + Set Player Health(Event Player, Health(Event Player) + Event Player.abilities[10] * 0.250 * Event Healing); + } +} + +rule("Team 1 (Ability): Resilience") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[11] == True; + Normalized Health(Event Player) < Event Player.abilities[11] * 0.300; + } + + actions + { + Set Damage Received(Event Player, 70); + Wait Until(!(Event Player.abilities[11] && Normalized Health(Event Player) < Event Player.abilities[11] * 0.300), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Auto Repair") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.automaticRepair == True; + Global.gateHealth < Global.gateMaxHealth; + } + + actions + { + If(Global.gateMaxHealth - Global.gateHealth > 5 * Global.automaticRepair * ( + Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 2 : 1)); + Global.gateHealth += 5 * Global.automaticRepair * ( + Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 2 : 1); + Global.upgradeGateMaxHealthValue += 5 * Global.automaticRepair; + Else; + Global.gateHealth += Global.gateMaxHealth - Global.gateHealth; + Global.upgradeGateMaxHealthValue += Global.gateMaxHealth - Global.gateHealth; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(5, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + If(Hero Of(Event Player) == Hero(Ana)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Ana), Button(Ability 1)), Custom String( + "Sleep Paralysis: Slept enemies cannot be woken up by damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Ana), Button(Ability 2)), Custom String( + "Multinade: Ana throws multiple Biotic Grenades")); + Else If(Hero Of(Event Player) == Hero(Ashe)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Ashe), Button(Ability 2)), Custom String( + "Wildfire: Shooting a burning enemy ignites other nearby enemies")); + Event Player.heroTalentText[2] = Array(Icon String(Fire), Custom String( + "Flare trigger: Coach gun instantly damages all burning enemies")); + Else If(Hero Of(Event Player) == Hero(Baptiste)); + Event Player.heroTalentText[1] = Array(Icon String(Poison), Custom String( + "Corrode: Regenerative Burst will damage and poison enemies")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Breakthrough: Immortality Field HP threshold increased to 100%; allies inside gain ultimate")); + Else If(Hero Of(Event Player) == Hero(Bastion)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Bomblets: Bullets shot during sentry configuration are explosive")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ability 1)), Custom String( + "Tesla: A powerful mounted laser will automatically attack one enemy at a time")); + Else If(Hero Of(Event Player) == Hero(Brigitte)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Brigitte), Button(Ability 1)), Custom String( + "Heavy Iron: Hitting enemies with Whip Flail will root them in pace")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Brigitte), Button(Ultimate)), Custom String( + "Endeavor: Gain a health, damage and speed boost when your barrier breaks")); + Else If(Hero Of(Event Player) == Hero(Cassidy)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Cassidy), Button(Ability 2)), Custom String( + "Panic: Flashbang puts enemies in fear; deal +120% more damage to enemies in fear")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Cassidy), Button(Ultimate)), Custom String( + "Clocked: Deadeye deals more damage and knocks enemies down")); + Else If(Hero Of(Event Player) == Hero(Doomfist)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Jump)), Custom String( + "Phase Shifter: Immune to damage while any ability is active")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Doomfist), Button(Ultimate)), Custom String( + "Fissure: Meteor Strike leaves a large fissure behind that burns enemies over it")); + Else If(Hero Of(Event Player) == Hero(D.Va)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(D.Va), Button(Secondary Fire)), Custom String( + "Voltage Grid: Defense Matrix will damage and root enemies it's casted over")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(D.Va), Button(Ability 1)), Custom String( + "Shooting Star: Boosters set enemies on fire")); + Else If(Hero Of(Event Player) == Hero(Echo)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Focusing Optics: Focusing Beam damage ramp starts at 90% health")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Streamline: Fire many more sticky bombs per burst")); + Else If(Hero Of(Event Player) == Hero(Genji)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Genji), Button(Ability 1)), Custom String( + "Venomous Strike: Swift Strike poisons enemies; heal for poison damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Genji), Button(Ultimate)), Custom String( + "Dragon's Breath: Dragonblade fires large explosive energy charges")); + Else If(Hero Of(Event Player) == Hero(Hanzo)); + Event Player.heroTalentText[1] = Array(Icon String(Bolt), Custom String( + "Stormbreak: Enemies eliminated by hanzo unleash a thundercloud")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Hanzo), Button(Ability 2)), Custom String( + "Punch II: Storm Arrows deal more damage and stun and knockback enemies")); + Else If(Hero Of(Event Player) == Hero(Junkrat)); + Event Player.heroTalentText[1] = Array(Icon String(Fire), Custom String("Pyromania: All explosive attacks inflict fire damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Junkrat), Button(Ability 2)), Custom String( + "Short Fused: Steel Trap sets off violent explosions once triggered")); + Else If(Hero Of(Event Player) == Hero(Lúcio)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Lúcio), Button(Secondary Fire)), Custom String( + "Healing Wave: Sound wave heals allies for 30% of their max HP")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Lúcio), Button(Ability 1)), Custom String( + "Reverse Amp: Amp It Up inflicts the opposite effect of the currently played song to enemies")); + Else If(Hero Of(Event Player) == Hero(Mei)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Mei), Button(Ultimate)), Custom String( + "Cold Snap: Instantly freeze nearby enemies once Cryo-Freeze expires")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Mei), Button(Ability 2)), Custom String( + "Icebound: While Ice Wall is up, Icicles freeze and deal much more damage")); + Else If(Hero Of(Event Player) == Hero(Mercy)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Mercy), Button(Ability 2)), Custom String( + "Angelic blessing: Healing an ally slowly charges their ultimate")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Mercy), Button(Ultimate)), Custom String( + "Holy light missiles: Unleash blasts of holy light missiles during valkyrie")); + Else If(Hero Of(Event Player) == Hero(Moira)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Moira), Button(Secondary Fire)), Custom String( + "Hose: Biotic Grasp primary will damage and push enemies back")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Moira), Button(Ability 2)), Custom String( + "Flourish: Biotic Orbs are 3x more effective")); + Else If(Hero Of(Event Player) == Hero(Orisa)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Orisa), Button(Ability 1)), Custom String( + "Immovable Object: During Fortify, become immune and convert 50% of taken damage to healing")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Orisa), Button(Secondary Fire)), Custom String( + "Unstoppable Force: Halt! is much larger and pushes enemies. When triggered, it explodes violently")); + Else If(Hero Of(Event Player) == Hero(Pharah)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ability 2)), Custom String( + "Head Trauma: Concussive Blast stuns and damages enemies for 25% of their max health")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Pharah), Button(Ability 1)), Custom String( + "Thunderbird: Gain 150 shields and deal 4x the damage to barriers and objects")); + Else If(Hero Of(Event Player) == Hero(Reaper)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Reaper), Button(Ability 1)), Custom String( + "shadow streak: shadow step creates a beam that damages enemies who cross")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Reaper), Button(Ultimate)), Custom String( + "Loom: Traumatize enemies in front of you when using Wraith Form")); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Reinhardt), Button(Ability 2)), Custom String( + "Fire Blast: Fire Strike explodes as it deals damage, setting enemies on fire")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Reinhardt), Button(Ultimate)), Custom String( + "Epicenter: Earth shatter travels in all directions")); + Else If(Hero Of(Event Player) == Hero(Roadhog)); + Event Player.heroTalentText[1] = Array(Icon String(Poison), Custom String("Stench: Roadhog constantly damages enemies nearby")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Roadhog), Button(Ability 1)), Custom String( + "Rusted Anchor: Hook deals more damage; Eliminations will reset hook cooldown")); + Else If(Hero Of(Event Player) == Hero(Sigma)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Sigma), Button(Ability 1)), Custom String( + "Gravity Well: Kinetic Grasp gives invincibility")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Sigma), Button(Ultimate)), Custom String( + "Gravity Channels: Gravitic Flux damages enemies for 75% of max hp instead of 50%")); + Else If(Hero Of(Event Player) == Hero(Soldier: 76)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ultimate)), Custom String( + "Triple Threat: 2 more rockets are fired alongside Helix Rockets")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Soldier: 76), Button(Ability 1)), Custom String( + "Shoulder Check: Sprinting into enemies will damage and tackle them to the ground")); + Else If(Hero Of(Event Player) == Hero(Sombra)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Sombra), Button(Secondary Fire)), Custom String( + "Malware: Enemies hacked or in fear take +100% more damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Sombra), Button(Ultimate)), Custom String( + "Glitch: EMP leaves behind a large hack zone ")); + Else If(Hero Of(Event Player) == Hero(Symmetra)); + Event Player.heroTalentText[1] = Array(Icon String(Bolt), Custom String( + "High Voltage: Enemies eliminated by Symmetra explode and damage other enemies")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ultimate)), Custom String( + "Energy Source: While Photon Barrier is active, all players regenerate health and gain ultimate")); + Else If(Hero Of(Event Player) == Hero(Torbjörn)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Torbjörn), Button(Ability 2)), Custom String( + "Melting point: Unleash heatwaves during overload and molten core")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Torbjörn), Button(Ultimate)), Custom String( + "Roots Of Magma: Enemies trapped in Molten Core blots cannot move")); + Else If(Hero Of(Event Player) == Hero(Tracer)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Tracer), Button(Ability 2)), Custom String( + "Vortex: Recall pulls and roots enemies towards the activation point")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Tracer), Button(Ultimate)), Custom String( + "Chain Reaction: Pulse Bomb creates chain explosions on enemies damaged by it")); + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Widowmaker), Button(Ultimate)), Custom String( + "Kiss Of Death: Scoped critical hits against enemies below 30% health explode and instantly die")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Widowmaker), Button(Ability 2)), Custom String( + "Epidemic: Enemies hurt by Venom Mine unleash toxic pulses; heal for dealt damage")); + Else If(Hero Of(Event Player) == Hero(Winston)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Winston), Button(Ability 2)), Custom String( + "Blast Barrier: Barrier Projector damages enemies inside the area")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Winston), Button(Ultimate)), Custom String( + "Next Generation: Eliminations during Primal Rage add +15% ultimate charge towards the next")); + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ultimate)), Custom String( + "Mirror Ball: Reflect 100% of taken damage to nearby enemies")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ability 2)), Custom String( + "Distort: Adaptive Shields damages and hacks nearby enemies")); + Else If(Hero Of(Event Player) == Hero(Zarya)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Zarya), Button(Ability 1)), Custom String( + "Augment: Health and barrier hp increased by 50%; barrier sized doubled")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Perpetual Energy: secondary inflicts burn damage that continues to last until the enemy dies")); + Else If(Hero Of(Event Player) == Hero(Zenyatta)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Vigor: The ally under the effect of Harmony Orb is immune to damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Zenyatta), Button(Ultimate)), Custom String( + "Perfect Balance: Transcendence damages enemies in a large proximity")); + End; + } +} + +rule("Ana: Sleep Paralysis") +{ + event + { + Player Dealt Damage; + Team 1; + Ana; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Black), Victim, 1); + Wait(0.250, Ignore Condition); + Set Status(Victim, Null, Knocked Down, 5); + } +} + +rule("Ana: Multinade") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Event Player.abilityCountdown = 4; + While(Event Player.abilityCountdown > 0); + Wait(0.030, Ignore Condition); + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Cancel Primary Action(Event Player); + Wait(0.050, Ignore Condition); + Press Button(Event Player, Button(Ability 2)); + Event Player.abilityCountdown -= 1; + End; + Wait(2, Ignore Condition); + } +} + +rule("Brigitte: Heavy Iron") +{ + event + { + Player Dealt Damage; + Team 1; + Brigitte; + } + + conditions + { + (Event Ability == Button(Primary Fire) || Event Ability == Button(Ability 1)) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Victim, 1.500); + Set Status(Victim, Null, Rooted, 0.500); + Set Environment Credit Player(Victim, Event Player); + } +} + +rule("Brigitte: Endeavor") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Ability Cooldown(Event Player, Button(Secondary Fire)) >= 0.100; + Event Player.abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player, 0.400, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Eye Position(Event Player), 15); + Heal(Players Within Radius(Event Player, 15, Team Of(Event Player), Off), Event Player, 200); + Event Player.damageDealt *= 2.500; + Set Move Speed(Event Player, 100 * 1.750); + Add Health Pool To Player(Event Player, Armor, Max Health(Event Player) / 2, False, True); + Event Player.hpPool[1] = Last Created Health Pool; + Wait Until(Is Dead(Event Player), 6); + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Set Move Speed(Event Player, 100); + Remove Health Pool From Player(Event Player.hpPool[1]); + Destroy Effect(Event Player.effects_[1]); + } +} + +rule("Mercy: Angelic Blessing") +{ + event + { + Player Dealt Healing; + All; + Mercy; + } + + conditions + { + Event Player.abilities[8] == True; + Healee != Event Player; + Normalized Health(Healee) < True; + } + + actions + { + Set Ultimate Charge(Healee, Ultimate Charge Percent(Healee) + 1); + Wait(0.400, Ignore Condition); + } +} + +rule("Mercy: Aurora") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ultimate(Event Player) == True; + } + + actions + { + Wait(1.500, Ignore Condition); + Event Player.abilityProjectile1 = Eye Position(Event Player); + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(All Teams), Event Player, True); + Create Beam Effect(All Players(All Teams), Mercy Heal Beam, Event Player, Event Player.abilityProjectile1, Color(White), + Visible To Position and Radius); + Event Player.effects_[3] = Last Created Entity; + Chase Player Variable At Rate(Event Player, abilityProjectile1, Event Player.abilityEnd, 70, Destination and Rate); + While(Event Player.abilityEnd != Event Player.abilityProjectile1); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Event Player.abilityProjectile1, 1); + Wait(0.032, Ignore Condition); + End; + Destroy Effect(Event Player.effects_[3]); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.abilityProjectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Orange), Event Player.abilityProjectile1, 5); + Damage(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 120); + Loop If Condition Is True; + } +} + +rule("Lucio: Healing Wave") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Green), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4); + Heal(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 4, 4, Team Of(Event Player), Surfaces), + Event Player, Max Health(Filtered Array(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4, Team Of(Event Player), Surfaces), Is Alive(Current Array Element))) * 0.300); + } +} + +rule("Lucio: Reverse Amp") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + If(Is Using Ability 1(Event Player)); + Set Status(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Rooted, 4); + Else; + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 16.250); + End; + Play Effect(All Players(All Teams), Ring Explosion, Is Using Ability 1(Event Player) ? Color(Green) : Color(Yellow), Event Player, + 1); + Wait(0.400, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Hose") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Event Player.abilities[8] == True; + Ability Resource(Event Player, Button(Primary Fire)) > False; + } + + actions + { + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Facing Direction Of(Event Player), 15, To World, + Cancel Contrary Motion); + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && !Is In Line of Sight(Current Array Element, Event Player, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Up, 8, To World, Cancel Contrary Motion); + Start Damage Over Time(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), + Distance Between(Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS)), Event Player, 1, 15); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Flourish - Damage") +{ + event + { + Player Dealt Damage; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("[Moira] Flourish - Healing") +{ + event + { + Player Dealt Healing; + Team 1; + Moira; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[12] == True; + } + + actions + { + Heal(Healee, Event Player, Event Healing * 2); + Play Effect(All Players(All Teams), Good Explosion, Color(Yellow), Healee, 0.100); + Wait(0.250, Ignore Condition); + } +} + +rule("Baptiste: Corrode") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 20); + Wait(0.200, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 12); + } +} + +rule("Baptiste: Breakthrough") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Status(Event Player, Unkillable) == True; + (Event Player.abilities[12] ? Players On Hero(Hero(Baptiste), Team Of(Event Player)) : Empty Array).abilities[12] == True; + } + + actions + { + Heal(Event Player, Event Player, 10000); + Set Status(Event Player, Null, Invincible, 0.800); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ashe: Firebourne") +{ + event + { + Player Dealt Damage; + Team 1; + Ashe; + } + + conditions + { + Event Player.abilities[8] == True; + Event Ability == Button(Primary Fire); + Has Status(Victim, Burning) == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Null, Burning, 10); + Start Damage Over Time(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Event Player, 10, 15); + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 5); + Wait(0.250, Ignore Condition); + } +} + +rule("Ashe: Taunt") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Damage(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, Burning)), + Event Player, 125); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Frozen, + 0.016); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Stunned, + 2); + } +} + +rule("D.Va: Voltage Grid") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 2, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 5, 0.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 8, 0.500); + Wait(0.300, Ignore Condition); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Wait(0.016, Ignore Condition); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Loop If Condition Is True; + } +} + +rule("D.Va: Shooting Star") +{ + event + { + Player Dealt Knockback; + Team 1; + D.Va; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, 40); + Set Status(Victim, Null, Burning, 3); + Start Damage Over Time(Victim, Event Player, 3, 35); + Play Effect(All Players(All Teams), Bad Explosion, Color(Red), Victim, 1); + } +} + +rule("Genji: Venomous Strike") +{ + event + { + Player Dealt Damage; + Team 1; + Genji; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.abilities[8] == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 3, 25); + Start Damage Over Time(Victim, Event Player, 3, 25); + Damage(Victim, Event Player, 25); + Heal(Event Player, Event Player, 25); + } +} + +rule("Genji: Dragon's Breath") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is Firing Primary(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Good Aura, Color(Lime Green), Event Player.abilityProjectile1, 1, + Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Event Player.abilityProjectile1 = Eye Position(Event Player); + Chase Player Variable At Rate(Event Player, abilityProjectile1, Event Player.abilityEnd, 80, Destination and Rate); + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True); + Wait Until(Event Player.abilityEnd == Event Player.abilityProjectile1, 1); + Destroy Effect(Event Player.effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Green), Event Player.abilityProjectile1, 100); + Play Effect(All Players(All Teams), Bad Explosion, Color(Lime Green), Event Player.abilityProjectile1, 5); + Play Effect(All Players(All Teams), Bad Explosion, Color(Green), Event Player.abilityProjectile1, 5); + Damage(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 100); + } +} + +rule("[Hanzo] Stormbreak (stormEffects6)") +{ + event + { + Player Died; + Team 2; + All; + } + + conditions + { + Attacker.abilities[8] == True; + Hero Of(Attacker) == Hero(Hanzo); + } + + actions + { + Event Player.stormProjectile = Eye Position(Event Player); + Event Player.stormEndPoint = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Up * 12, Null, + All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, stormProjectile, Event Player.stormEndPoint, 4, Destination and Rate); + Create Effect(All Players(All Teams), Cloud, Color(White), Vector(False, -0.500, False) + Event Player.stormProjectile, 4, + Visible To Position and Radius); + Event Player.stormEffects[3] = Last Created Entity; + Create Effect(All Players(All Teams), Bad Aura, Color(White), Event Player.stormProjectile, 3, Visible To Position and Radius); + Event Player.stormEffects[4] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(White), Event Player.stormProjectile, 3.500, Visible To Position and Radius); + Event Player.stormEffects[5] = Last Created Entity; + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.stormProjectile, Ray Cast Hit Position( + Event Player.stormProjectile, Vector(0.100, 0, 0) + Event Player.stormProjectile + Down * 1000, Null, All Players(All Teams), + False), Color(Aqua), Visible To Position and Radius); + Event Player.stormEffects[6] = Last Created Entity; + While(Distance Between(Event Player.stormProjectile, Event Player.stormEndPoint) > 1); + Wait(0.600, Ignore Condition); + Damage(Players Within Radius(Ray Cast Hit Position(Event Player.stormProjectile, Event Player.stormProjectile + Down * 1000, Null, + All Players(All Teams), False), 3, Team Of(Event Player), Surfaces), Attacker, 50); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Ray Cast Hit Position(Event Player.stormProjectile, + Event Player.stormProjectile + Down * 1000, Null, All Players(All Teams), False), 3); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Ray Cast Hit Position(Event Player.stormProjectile, + Event Player.stormProjectile + Down * 1000, Null, All Players(All Teams), False), 3); + End; + Destroy Effect(Event Player.stormEffects[3]); + Destroy Effect(Event Player.stormEffects[4]); + Destroy Effect(Event Player.stormEffects[5]); + Destroy Effect(Event Player.stormEffects[6]); + } +} + +rule("Hanzo: Punch II") +{ + event + { + Player Dealt Damage; + Team 1; + Hanzo; + } + + conditions + { + Event Player.abilities[12] == True; + Event Ability == Button(Ability 2); + Hero Of(Victim) != Hero(Torbjörn); + } + + actions + { + Damage(Victim, Event Player, Event Damage * 0.800); + Apply Impulse(Victim, Facing Direction Of(Event Player), 12, To World, Cancel Contrary Motion); + Apply Impulse(Victim, Up, 5, To World, Cancel Contrary Motion); + Set Environment Credit Player(Victim, Event Player); + Set Status(Victim, Null, Stunned, 1); + } +} + +rule("Widowmaker: Kiss Of Death") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + (Normalized Health(Victim) <= 0.300 || Event Damage >= Normalized Health(Victim) + Event Damage) == True; + Is Firing Secondary(Event Player) == True; + Event Ability == Button(Primary Fire); + Event Player.abilities[8] == True; + Event Damage >= 40; + Event Was Critical Hit == True; + } + + actions + { + Kill(Victim, Event Player); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 2), Victim, 3); + Damage(Players Within Radius(Victim, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage * 1.500); + } +} + +rule("Widowmaker: Epidemic") +{ + event + { + Player Dealt Damage; + Team 1; + Widowmaker; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Violet), Victim, 8); + Play Effect(All Players(All Teams), Good Explosion, Color(Purple), Victim, 4); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Victim, 16); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Victim, 3); + Start Damage Over Time(Players Within Radius(Victim, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, 50); + Start Heal Over Time(Event Player, Event Player, 3, 50); + Wait(0.500, Ignore Condition); + } +} + +rule("McCree: Panic") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[8] == True; + } + + actions + { + Victim.fearedUntil = Total Time Elapsed + 3.500; + } +} + +rule("McCree: Panic - Damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), + Event Player.fearedUntil >= Total Time Elapsed), All Players(Team Of(Event Player)), 220, + Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Wait Until(!Event Player.abilities[8], 99999); + Stop Damage Modification(Event Player.modificationDamage[1]); + } +} + +rule("McCree: Clocked") +{ + event + { + Player Dealt Damage; + Team 1; + Cassidy; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Damage(Victim, Event Player, Event Damage * 1.500); + Set Status(Victim, Null, Knocked Down, 3); + } +} + +rule("Reinhardt: Fire Blast") +{ + event + { + Player Dealt Damage; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Victim, 5); + Start Damage Over Time(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, 20); + Set Status(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Burning, 5); + } +} + +rule("Reinhardt: Epicenter") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is On Ground(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, Knocked Down, 2.500); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 10); + Damage(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, 50); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 20); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 30); + Wait(0.016, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 40); + Wait(5, Ignore Condition); + } +} + +rule("[Soldier: 76] Rocket Assault Rifle") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Event Player.abilityProjectile2 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(-2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.abilityProjectile1 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.abilityPosition = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, + 0), Event Player, Rotation); + Event Player.abilityEnd = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, 0), + Event Player, Rotation); + Chase Player Variable At Rate(Event Player, abilityPosition, Event Player.abilityProjectile1, 60, Destination and Rate); + Chase Player Variable At Rate(Event Player, abilityEnd, Event Player.abilityProjectile2, 60, Destination and Rate); + Wait Until(Event Player.abilityPosition == 0 && Event Player.abilityEnd == 0, 2.500); + } +} + +rule("[Soldier: 76] First Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.abilityProjectile1 != Event Player.abilityPosition; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.abilityPosition, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.abilityPosition, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.abilityPosition, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.abilityPosition, 2.500); + Stop Chasing Player Variable(Event Player, abilityPosition); + Wait(0.016, Ignore Condition); + Damage(Players Within Radius(Event Player.abilityPosition, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 80); + Stop Chasing Player Variable(Event Player, abilityPosition); + Event Player.abilityPosition = 0; + Event Player.abilityProjectile1 = 0; + Wait(0.016, Ignore Condition); + } +} + +rule("[Soldier: 76] Second Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.abilityProjectile2 != Event Player.abilityEnd; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.abilityEnd, 0.400); + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(All Teams), Explosion Sound, Color(Orange), Event Player.abilityEnd, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.abilityEnd, 2.500); + Play Effect(All Players(All Teams), Bad Explosion, Color(Team 1), Event Player.abilityEnd, 2.500); + Stop Chasing Player Variable(Event Player, abilityEnd); + Damage(Players Within Radius(Event Player.abilityEnd, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Event Player.abilityEnd = 0; + Event Player.abilityProjectile2 = 0; + } +} + +rule("Soldier: 76 - Init rockets") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Event Player.abilityProjectile1 = Event Player.abilityPosition; + Event Player.abilityProjectile2 = Event Player.abilityEnd; + } +} + +rule("[Soldier: 76] Shoulder Check") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[12] == True; + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 3; + Is Alive(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) == True; + } + + actions + { + Damage(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Event Player, 55); + Set Status(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Null, Knocked Down, 1.500); + Apply Impulse(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Facing Direction Of(Event Player), 15, + To World, Cancel Contrary Motion); + Apply Impulse(Event Player, Vector(0, 8, 15), 15, To Player, Cancel Contrary Motion); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Closest Player To(Event Player, Opposite Team Of(Team Of( + Event Player))), 1); + Set Ability Cooldown(Event Player, Button(Melee), 0); + Press Button(Event Player, Button(Melee)); + Wait(1, Ignore Condition); + } +} + +rule("Torbjorn: Melting Point") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Event Player.abilities[8] == True; + (Is Using Ability 2(Event Player) || Is Using Ultimate(Event Player)) == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Explosion, Color(Orange), Event Player, 8); + Play Effect(All Players(All Teams), Bad Explosion, Color(Yellow), Event Player, 8); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Position Of(Event Player), 16); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, + 25); + Set Status(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Off), Null, Burning, 3); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player, 100); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Torbjorn: Roots of Magma") +{ + event + { + Player Dealt Damage; + Team 1; + Torbjörn; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Player.abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Orange), Victim, 1); + Set Status(Victim, Null, Rooted, 1); + Wait(1, Ignore Condition); + } +} + +rule("Tracer: Vortex") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Heal(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, 0); + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 10); + Play Effect(All Players(All Teams), Ring Explosion, Color(Red), Position Of(Event Player), 24); + Play Effect(All Players(All Teams), Ring Explosion, Color(Yellow), Position Of(Event Player), 18); + Play Effect(All Players(All Teams), Ring Explosion, Color(Green), Position Of(Event Player), 12); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player), 6); + Set Environment Credit Player(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player); + } +} + +rule("Tracer: Vortex 2") +{ + event + { + Player Received Healing; + Team 2; + All; + } + + conditions + { + Healer.abilities[8] == True; + Hero Of(Healer) == Hero(Tracer); + Is Using Ability 2(Healer) == True; + Event Ability == Null; + Event Damage <= 20; + } + + actions + { + Apply Impulse(Event Player, Up, 5, To World, Cancel Contrary Motion); + Wait(0.100, Ignore Condition); + Apply Impulse(Event Player, Direction Towards(Event Player, Healer), Distance Between(Event Player, Healer) * 3.500, To World, + Cancel Contrary Motion); + Set Status(Event Player, Null, Rooted, 1.300); + } +} + +rule("Tracer: Chain Reaction") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is True For Any(Filtered Array(All Players(Team Of(Event Player)), Current Array Element.chainReactionOn), Distance Between( + Event Player, Current Array Element) <= 8 && True) == True; + Event Player.chainReactionImmune == False; + Event Player.chainReactionOn == False; + Is Alive(Event Player) == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Event Player.chainReactionOn = True; + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player, 3); + } +} + +rule("Tracer: Chain Reaction 2") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Event Player.chainReactionOn == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Aqua), Event Player, 3); + Damage(Event Player, Players On Hero(Hero(Tracer), Opposite Team Of(Team Of(Event Player))), 200); + Wait(0.500, Ignore Condition); + Event Player.chainReactionImmune = True; + Event Player.chainReactionOn = False; + Wait(2, Ignore Condition); + Event Player.chainReactionImmune = False; + } +} + +rule("Tracer: Chain Reaction 3") +{ + event + { + Player Dealt Damage; + Team 1; + Tracer; + } + + conditions + { + Event Ability == Button(Ultimate); + Event Damage > 20; + Event Player.abilities[12] == True; + } + + actions + { + Victim.chainReactionOn = True; + } +} + +rule("[Winston] Electric Field") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player.abilityProjectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 65); + Destroy Effect(Event Player.effects_[1]); + Event Player.abilityActive = True; + Create Effect(All Players(All Teams), Orb, Color(White), Event Player.abilityProjectile1, 1, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Stop Chasing Player Variable(Event Player, abilityResource); + Event Player.abilityProjectile1 = Eye Position(Event Player); + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Down * 1000, Null, + All Players(All Teams), False); + Wait(0.100, Ignore Condition); + Event Player.abilityResource = 5; + Wait(0.250, Ignore Condition); + Chase Player Variable At Rate(Event Player, abilityResource, 20, 7, Destination and Rate); + Chase Player Variable At Rate(Event Player, abilityProjectile1, Event Player.abilityEnd, Event Player.abilityResource, + Destination and Rate); + Wait(8.650, Restart When True); + Event Player.abilityActive = False; + } +} + +rule("[Winston] Electric Field 2") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Event Player.abilityActive == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Event Player.abilityProjectile1, 5); + Damage(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 33); + Play Effect(All Players(All Teams), Ring Explosion, Color(Blue), Event Player.abilityProjectile1, 10); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + Damage(Players Within Radius(Event Player.abilityProjectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 80); + Play Effect(All Players(All Teams), Bad Explosion, Color(Turquoise), Event Player.abilityProjectile1, 12); + Destroy Effect(Event Player.effects_[1]); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Event Player.abilityProjectile1, 125); + } +} + +rule("Winston: Next Generation") +{ + event + { + Player Earned Elimination; + Team 1; + Winston; + } + + conditions + { + Ultimate Charge Percent(Event Player) <= 80; + Is Using Ultimate(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 15); + } +} + +rule("Pharah: Head Trauma") +{ + event + { + Player Dealt Knockback; + Team 1; + Pharah; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[8] == True; + Victim != Event Player; + } + + actions + { + Damage(Victim, Event Player, Max Health(Victim) * 0.300); + Set Status(Victim, Event Player, Knocked Down, 1); + Play Effect(All Players(All Teams), Good Explosion, Color(Team 1), Victim, 1); + } +} + +rule("Pharah: Thunderbird") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[12] == True; + Hero Of(Event Player) == Hero(Pharah); + } + + actions + { + Event Player.damageDealt *= 4; + Start Damage Modification(All Players(All Teams), Event Player, 25, Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Add Health Pool To Player(Event Player, Shields, 150, True, True); + Event Player.hpPool[1] = Last Created Health Pool; + Wait Until(!Event Player.abilities[12] || Hero Of(Event Player) != Hero(Pharah), 99999); + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Stop Damage Modification(Event Player.modificationDamage[1]); + Remove Health Pool From Player(Event Player.hpPool[1]); + } +} + +rule("Orisa: Unstoppable Force") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Event Player.genDirection = Facing Direction Of(Event Player); + Event Player.abilityActive = True; + Create Effect(All Players(All Teams), Sphere, Color(Green), Event Player.abilityProjectile1, 4, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Event Player.abilityProjectile1 = Eye Position(Event Player) + Facing Direction Of(Event Player) * 0.500; + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 100, Null, All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, abilityProjectile1, Event Player.abilityEnd, 25, Destination and Rate); + Wait(0.250, Ignore Condition); + Wait Until((!Event Player.genAvailable && Is Button Held(Event Player, Button(Secondary Fire))) || ( + Event Player.abilityProjectile1 == Event Player.abilityEnd), 99999); + Stop Chasing Player Variable(Event Player, abilityProjectile1); + Wait(0.500, Ignore Condition); + Damage(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 100); + Play Effect(All Players(All Teams), Good Explosion, Color(Lime Green), Event Player.abilityProjectile1, 5); + Destroy Effect(Event Player.effects_[1]); + Event Player.abilityActive = False; + } +} + +rule("Orisa: Availability for Halt!") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Event Player.genAvailable = True; + Wait Until(!Is Button Held(Event Player, Button(Secondary Fire)), 99999); + Event Player.genAvailable = False; + } +} + +rule("Orisa: Drag effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Event Player.abilities[12] == True; + Event Player.abilityActive == True; + } + + actions + { + Apply Impulse(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Is Alive(Event Player) ? Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of( + Event Player)), Surfaces) : Empty Array, Event Player.abilityProjectile1), 8, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Event Player.abilityProjectile1, Event Player.abilityEnd), 20, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Up, 5, + To Player, Cancel Contrary Motion); + Wait(0.200, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Orisa: Immoveable Object - Reduce dmg") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Set Damage Received(Event Player, 100 * 0.003); + Wait Until(!Is Using Ability 1(Event Player), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Orisa: Immovable Object - Healing") +{ + event + { + Player Took Damage; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Heal(Event Player, Null, Event Damage * 3); + } +} + +rule("[Reaper] Shadow Streak (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.abilities[8] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Event Player.abilityPosition = Position Of(Event Player) + Vector(0, 1, 0); + Wait(2, Abort When False); + Event Player.abilityEnd = Position Of(Event Player) + Vector(0, 1, 0); + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.abilityEnd, Event Player.abilityPosition, Color(Black), + Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Event Player.abilityActive = True; + Wait Until(Is Dead(Event Player) || Is Using Ability 2(Event Player), 99999); + Destroy Effect(Event Player.effects_[1]); + Event Player.abilityActive = False; + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage start to end (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.abilities[8] == True; + Ray Cast Hit Player(Event Player.abilityPosition, Event Player.abilityEnd, All Living Players(Opposite Team Of(Team Of( + Event Player))), Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.abilityActive == True; + } + + actions + { + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.abilityPosition, + Event Player.abilityEnd, All Living Players(All Teams), Event Player, True), 1); + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.abilityPosition, Event Player.abilityEnd, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage end to start (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.abilities[8] == True; + Ray Cast Hit Player(Event Player.abilityEnd, Event Player.abilityPosition, All Players(Opposite Team Of(Team Of(Event Player))), + Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.abilityActive == True; + } + + actions + { + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.abilityEnd, Event Player.abilityPosition, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Play Effect(All Players(All Teams), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.abilityEnd, + Event Player.abilityPosition, All Living Players(All Teams), Event Player, True), 1); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Reaper: Loom") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Hacked, 1.500); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Rooted, 1.500); + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Event Player, 45); + } +} + +rule("Sigma: Gravity Well") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, 25); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Null, Rooted, 2); + Set Status(Event Player, Null, Invincible, 1); + Play Effect(Event Player, Ring Explosion, Color(Blue), Eye Position(Event Player), 50); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Sigma: Gravity Channels") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ultimate(Event Player)), Event Player, 150, + Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Wait Until(!Event Player.abilities[12], 99999); + Stop Damage Modification(Event Player.modificationDamage[1]); + } +} + +rule("Echo: Focusing Optics") +{ + event + { + Player Dealt Damage; + Team 1; + Echo; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[8] == True; + Normalized Health(Victim) > 0.500; + Normalized Health(Victim) <= 0.900; + Is Duplicating(Event Player) == False; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 3); + Play Effect(All Players(All Teams), Bad Explosion, Color(Violet), Victim, 0.500); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Wait(0.700, Abort When False); + Cancel Primary Action(Event Player); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Set Projectile Speed(Event Player, 100); + Wait(0.150, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Bomblets") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Is In Alternate Form(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Orange), Null + Ray Cast Hit Position(Eye Position(Event Player), + Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, All Living Players(Opposite Team Of(Team Of( + Event Player))), All Players(Team Of(Event Player)), True), 2); + Damage(Players Within Radius(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 2, + Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 12); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Taser - Loop damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is True For Any(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive(Current Array Element) + && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status(Current Array Element, + Phased Out) && Distance Between(Event Player, Current Array Element) <= 25) == True; + Is Alive(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Play Effect(All Players(All Teams), Explosion Sound, Color(White), Event Player.abilityPlayer, 80); + Play Effect(All Players(All Teams), Bad Pickup Effect, Color(Aqua), Event Player.abilityPlayer, 1); + Event Player.abilityPlayer = Filtered Array(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive( + Current Array Element) && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status( + Current Array Element, Phased Out) && Distance Between(Event Player, Current Array Element) <= 25); + Damage(Players Within Radius(Event Player.abilityPlayer, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 30); + Wait(0.450, Ignore Condition); + Loop If Condition Is True; + Event Player.abilityPlayer = Null; + } +} + +rule("Bastion: Taser - Visual beam") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player + Vector(False, 1, False), + Event Player.abilityPlayer != Null ? Event Player.abilityPlayer : Event Player, Color(Aqua), + Visible To Position Radius and Color); + Event Player.effects_[1] = Last Created Entity; + Wait Until(!Event Player.abilities[12], 99999); + Destroy Effect(Event Player.effects_[1]); + } +} + +rule("Sombra: Malware") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, + Hacked) || Current Array Element.fearedUntil >= Total Time Elapsed), All Players(Team Of(Event Player)), 200, + Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Wait Until(!Event Player.abilities[8], 99999); + Stop Damage Modification(Event Player.modificationDamage[1]); + } +} + +rule("Sombra: Glitch") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Event Player.abilityActive = True; + Event Player.abilityPosition = Position Of(Event Player); + Create Effect(All Players(All Teams), Sphere, Color(Purple), Event Player.abilityPosition, 15, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Wait(8, Ignore Condition); + Destroy Effect(Event Player.effects_[1]); + Event Player.abilityActive = False; + } +} + +rule("Sombra: Glitch - Loop") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.abilityActive == True; + } + + actions + { + Set Status(Players Within Radius(Event Player.abilityPosition, 15, Opposite Team Of(Team Of(Event Player)), Off), Null, Hacked, + 0.750); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Mei: Cold Snap") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Event Player.abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Create Effect(All Players(All Teams), Bad Aura, Color(Sky Blue), Event Player, 1, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Wait Until(!Is Using Ability 1(Event Player), 99999); + Destroy Effect(Event Player.effects_[1]); + Damage(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Frozen, 2); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Rooted, 2); + Play Effect(All Players(All Teams), Ring Explosion, Color(White), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Sky Blue), Position Of(Event Player), 20); + Play Effect(All Players(All Teams), Ring Explosion, Color(Aqua), Position Of(Event Player) + Vector(0, 1, 0), 20); + } +} + +rule("Mei: Icebound") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Is Firing Secondary(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Aqua), Event Player, 0.400, Visible To Position and Radius); + Event Player.effects_[2] = Last Created Entity; + Set Projectile Speed(Event Player, 200); + Wait Until(!Is Firing Secondary(Event Player), 99999); + Destroy Effect(Event Player.effects_[2]); + Set Projectile Speed(Event Player, 100); + } +} + +rule("Mei: Icebound - Icicles hit") +{ + event + { + Player Dealt Damage; + Team 1; + Mei; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Is Using Ability 2(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, Event Damage * 1.250); + Set Status(Victim, Null, Frozen, 1); + Set Status(Victim, Null, Rooted, 1); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(White), Victim, 1); + } +} + +rule("Wrecking Ball: Mirror Ball") +{ + event + { + Player Took Damage; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 4.500, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage); + Wait(0.100, Ignore Condition); + } +} + +rule("Wrecking Ball: Distort") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Play Effect(All Players(All Teams), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Wait(0.100, Ignore Condition); + Play Effect(All Players(All Teams), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Set Status(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Hacked, Count Of( + Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces)) * 1.500); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Violet), Position Of(Event Player), 125); + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Sound, Color(Purple), Position Of(Event Player), 16); + Play Effect(All Players(All Teams), Explosion Sound, Color(Violet), Position Of(Event Player), 80); + } +} + +rule("Symmetra: High voltage") +{ + event + { + Player Dealt Final Blow; + Team 1; + Symmetra; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Victim, 10); + Play Effect(All Players(All Teams), Bad Explosion, Color(Aqua), Victim, 8); + Damage(Players Within Radius(Victim, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 150); + } +} + +rule("Symmetra: Energy Source") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is True For Any(Players On Hero(Hero(Symmetra), Team Of(Event Player)), Is Using Ultimate(Current Array Element) + && Current Array Element.abilities[12]) == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 1, 40); + Play Effect(All Players(All Teams), Good Explosion, Color(Blue), Event Player, 0.100); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Junkrat: Pyromania") +{ + event + { + Player Dealt Knockback; + Team 1; + Junkrat; + } + + conditions + { + Event Player.abilities[8] == True; + Event Ability != Button(Melee); + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 2, 30); + Set Status(Victim, Null, Burning, 2); + } +} + +rule("Junkrat: Short Fused") +{ + event + { + Player Dealt Damage; + Team 1; + Junkrat; + } + + conditions + { + Event Player.abilities[12] == True; + Event Ability == Button(Ability 2); + } + + actions + { + Event Player.abilityCountdown = 4; + While(Event Player.abilityCountdown > 0); + Event Player.abilityCountdown -= 1; + Event Player.abilityPosition = Position Of(Victim) + Vector(Random Real(-2, 2), Random Real(-2, 2), Random Real(-2, 2)); + Play Effect(All Players(All Teams), Good Explosion, Color(Sky Blue), Event Player.abilityPosition, 4); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Event Player.abilityPosition, 4); + Damage(Players Within Radius(Event Player.abilityPosition, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 35); + Set Status(Players Within Radius(Event Player.abilityPosition, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Stunned, 0.800); + Wait(0.200, Ignore Condition); + End; + } +} + +rule("Zenyatta: Vigor") +{ + event + { + Player Dealt Healing; + Team 1; + Zenyatta; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Set Status(Healee, Null, Invincible, 1); + Wait(0.800, Ignore Condition); + } +} + +rule("Zenyatta: Perfect Balance") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Start Damage Over Time(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 0.750, 200); + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player, 24); + Wait(0.600, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Stench") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Violet), Event Player, 8, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Wait Until(!Event Player.abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Destroy Effect(Event Player.effects_[1]); + } +} + +rule("Roadhog: Stench effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 8; + Event Player.abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 9); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Rusted Anchor") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ability 1(Event Player)), Event Player, 400, + Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Wait Until(!Event Player.abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Stop Damage Modification(Event Player.modificationDamage[1]); + } +} + +rule("Roadhog: Rusted Anchor - Reset cooldown") +{ + event + { + Player Earned Elimination; + Team 1; + Roadhog; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ability 1(Event Player), 3); + Set Ability Cooldown(Event Player, Button(Ability 1), False); + } +} + +rule("Zarya: Augment") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Start Scaling Barriers(Event Player, 2, True); + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5 + 50; + Set Max Health(Event Player, Event Player.playerHealth); + Wait Until(!Event Player.abilities[8] || Hero Of(Event Player) != Hero(Zarya), 99999); + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + Stop Scaling Barriers(Event Player); + } +} + +rule("Zarya: Perpetual Energy") +{ + event + { + Player Dealt Knockback; + Team 1; + Zarya; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Event Player.abilities[12] == True; + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 9999, 15); + Set Status(Victim, Null, Burning, 9999); + } +} + +rule("Doomfist: Phase Shifter") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + (Is Firing Secondary(Event Player) || Is Using Ability 1(Event Player) || Is Using Ability 2(Event Player)) == True; + Event Player.abilities[8] == True; + } + + actions + { + Set Status(Event Player, Null, Phased Out, 1); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ultimate(Event Player), 99999); + Event Player.abilityPosition = Position Of(Event Player); + Event Player.abilityActive = True; + Wait Until(Is Dead(Event Player), 8); + Event Player.abilityActive = False; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Event Player.abilityActive == True; + Event Player.abilities[12] == True; + } + + actions + { + Create Effect(All Players(All Teams), Ring, Color(Orange), Event Player.abilityPosition, 8, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Create Effect(All Players(All Teams), Cloud, Color(Orange), Event Player.abilityPosition, 8, Visible To Position and Radius); + Event Player.effects_[2] = Last Created Entity; + Play Effect(All Players(All Teams), Ring Explosion, Color(Orange), Event Player.abilityPosition, 16); + While(Event Player.abilityActive == True); + Damage(Players Within Radius(Event Player.abilityPosition, 8, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 34); + Wait(0.235, Ignore Condition); + End; + Destroy Effect(Event Player.effects_[1]); + Destroy Effect(Event Player.effects_[2]); + } +} + +rule("Team 1 (perk): Sharpshooter") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + conditions + { + Global.perk[0] == True; + Event Ability != Null; + Distance Between(Event Player, Victim) >= 10; + } + + actions + { + Damage(Victim, Event Player, 50 / Event Player.damageDealt * Event Damage); + } +} + +rule("Team 1 (perk): Bulletstorm") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.perk[1] == True; + (Ammo(Event Player, 0) < Max Ammo(Event Player, 0) || Ammo(Event Player, 1) < Max Ammo(Event Player, 1)) == True; + } + + actions + { + Set Ammo(Event Player, 0, 1000); + Set Ammo(Event Player, 1, 1000); + } +} + +rule("Team 1 Challenges") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + If(Global.perk[2] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.abilityHUD[17] = Last Text ID; + End; + If(Global.perk[0] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.abilityHUD[18] = Last Text ID; + End; + If(Global.perk[1] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.abilityHUD[19] = Last Text ID; + End; + If(Global.maxHealthDone == 50); + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + End; + } +} + +rule("Stuff to do when Player leaves") +{ + event + { + Player Left Match; + Team 1; + All; + } + + actions + { + Global.automaticRepair -= Event Player.abilities[16]; + } +} + +rule("Refund") +{ + event + { + Subroutine; + Refund; + } + + actions + { + "Refund Money" + Event Player.money[0] += Event Player.money[1]; + Event Player.money[1] = 0; + "Reset Headhunter" + Event Player.abilities[1] = 0; + "Reset Ambush" + Event Player.abilities[2] = 0; + "Reset QuickFix" + Event Player.abilities[3] = 0; + "Reset HeavyWeight" + Event Player.abilities[4] = 0; + "Reset Charged" + Event Player.abilities[5] = 0; + "Reset Haste" + Event Player.abilities[6] = 0; + "Reset HeavyImpact" + Event Player.abilities[7] = 0; + "Reset HeroTalent1" + Event Player.abilities[8] = 0; + "Reset SecondWind" + Event Player.abilities[9] = 0; + "Reset BindingHeal" + Event Player.abilities[10] = 0; + "Reset Resilience" + Event Player.abilities[11] = 0; + "Reset HeroTalent2" + Event Player.abilities[12] = 0; + "Reset Damage" + Event Player.abilities[13] = 0; + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.damageDealt); + "Reset Health" + Event Player.abilities[14] = 0; + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + If(Global.maxHealthDone == 0); + End; + "Reset Healing" + Event Player.abilities[15] = 0; + Set Healing Dealt(Event Player, 100 + Event Player.abilities[15] * 5); + "Reset automaticRepair" + Global.automaticRepair -= Event Player.abilities[16]; + Event Player.abilities[16] = 0; + } +} + +rule("Lucio Dash HUD Creation") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + } + + actions + { + If(Event Player.lucioDashActive == False); + Event Player.lucioDashActive = True; + Create HUD Text(Event Player, Null, Null, Custom String("{0} Slam on ground - Press: {1}", Ability Icon String(Hero(Wrecking Ball), + Button(Crouch)), Input Binding String(Button(Crouch))), Left, 1000, Color(White), Color(White), Color(White), + Visible To and String, Default Visibility); + Event Player.lucioDashIcon = Last Text ID; + End; + } +} + +rule("Lucio Dash Remove HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) != Hero(Lúcio); + Event Player.lucioDashActive == True; + } + + actions + { + Destroy HUD Text(Event Player.lucioDashIcon); + Event Player.lucioDashActive = False; + } +} + +rule("Lucio Dash") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + Event Player.lucioDashActive == True; + Is On Ground(Event Player) == False; + Is Button Held(Event Player, Button(Crouch)) == True; + } + + actions + { + Apply Impulse(Event Player, Down, 20, To World, Cancel Contrary Motion); + } +} + +rule("Ana Self-Nano") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + Ultimate Charge Percent(Event Player) == 100; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Abort If(Global.selfNanoWorkshopSetting == False && Number Of Players(Team 1) > 1); + Wait(0.100, Ignore Condition); + If(Is Using Ultimate(Event Player) == False); + Create Dummy Bot(Hero(Ana), Team Of(Event Player), -1, Position Of(Event Player) + Backward, Eye Position(Event Player)); + Event Player.anaEntityID = Last Created Entity; + Wait(0.100, Ignore Condition); + Set Ultimate Charge(Event Player.anaEntityID, 100); + Start Facing(Event Player.anaEntityID, Direction Towards(Eye Position(Event Player.anaEntityID), Position Of(Event Player) + Up), + 1000, To World, Direction and Turn Rate); + Set Invisible(Event Player.anaEntityID, All); + Set Status(Event Player.anaEntityID, Null, Phased Out, 9999); + Wait(0.150, Ignore Condition); + Press Button(Event Player.anaEntityID, Button(Ultimate)); + Set Ultimate Charge(Event Player, 0); + Wait(0.150, Ignore Condition); + Teleport(Event Player.anaEntityID, Position Of(First Of(Spawn Points(Team Of(Event Player))))); + Wait(10, Ignore Condition); + Destroy Dummy Bot(Team Of(Event Player), Slot Of(Event Player.anaEntityID)); + End; + } +} + +rule("Reinhard Charge Cancel") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + } + + actions + { + Wait(0.600, Ignore Condition); + Wait Until(Is Button Held(Event Player, Button(Ability 1)), 5); + Set Status(Event Player, Null, Rooted, 0.001); + Wait Until(Event Player.reinPin, 1); + If(Event Player.reinPin != 0); + Apply Impulse(Event Player.reinPin, Facing Direction Of(Event Player), 15, To World, Cancel Contrary Motion); + End; + } +} + +disabled rule("Map Editor Walls") +{ + event + { + Ongoing - Global; + } +} + +rule("Initial Global") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.allPositions = Empty Array; + Global.allDirections = Empty Array; + Global.firstPosition = Empty Array; + Global.secondPosition = Empty Array; + Global.firstPoint = Empty Array; + Global.secondPoint = Empty Array; + Global.second = Empty Array; + Global.z = Empty Array; + Global.wallId = Empty Array; + Global.beamType = Empty Array; + } +} + +rule("Initial Player") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.filterPosition = 0; + Event Player.lastSavedPosition = 0; + Event Player.closestBodyPosition = 0; + Event Player.fullBodyPosition = 0; + Event Player.previousPositionIntersection = 0; + Event Player.activeWall = Empty Array; + Event Player.closestWall = Empty Array; + } +} + +rule("Collision Logic") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Event Player.lastSavedPosition = (Eye Position(Event Player) + Position Of(Event Player)) / 2; + Wait(0.016, Ignore Condition); + Event Player.closestWall = Filtered Array(Global.allPositions, Distance Between(Global.allPositions[Current Array Index], + Event Player) <= Distance Between(Global.allPositions[Current Array Index], Global.firstPosition[Current Array Index]) + || Event Player.activeWall[Current Array Index] == 1 || (Dot Product(Direction Towards(Current Array Element, + Event Player.lastSavedPosition), Global.allDirections[Current Array Index]) > 0) != (Dot Product(Direction Towards( + Current Array Element, Event Player), Global.allDirections[Current Array Index]) > 0)); + For Player Variable(Event Player, x, 0, Count Of(Event Player.closestWall), 1); + Global.z = Index Of Array Value(Global.allPositions, Event Player.closestWall[Event Player.x]); + If(Global.wallId[Global.z] == 1 || Global.wallId[Global.z] == 3 || Global.wallId[Global.z] == 5); + If(Y Component Of(Global.firstPosition[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.firstPosition[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestBodyPosition = Global.firstPosition[Global.z]; + Else If(Y Component Of(Global.secondPosition[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.secondPosition[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestBodyPosition = Global.secondPosition[Global.z]; + Else; + Event Player.closestBodyPosition = Position Of(Event Player); + End; + Event Player.fullBodyPosition = Vector(X Component Of(Eye Position(Event Player)), Y Component Of( + Event Player.closestBodyPosition), Z Component Of(Eye Position(Event Player))); + Event Player.filterPosition = Event Player.fullBodyPosition + Global.allDirections[Global.z] * Dot Product( + Global.allPositions[Global.z] - Event Player.fullBodyPosition, Global.allDirections[Global.z]) / Dot Product( + Global.allDirections[Global.z], Global.allDirections[Global.z]); + If(Global.wallId[Global.z] == 1 || Global.wallId[Global.z] == 3); + If((Dot Product(Direction Towards(Global.allPositions[Global.z], Event Player.lastSavedPosition), Global.allDirections[Global.z]) + > 0) != (Dot Product(Direction Towards(Global.allPositions[Global.z], Event Player.fullBodyPosition), + Global.allDirections[Global.z]) > 0)); + Event Player.intersectionLength = Dot Product(Global.allPositions[Global.z] - Event Player.fullBodyPosition, + Global.allDirections[Global.z]) / Dot Product(Direction Towards(Event Player.lastSavedPosition, Event Player.fullBodyPosition), + Global.allDirections[Global.z]); + Event Player.previousPositionIntersection = Event Player.fullBodyPosition + Direction Towards(Event Player.lastSavedPosition, + Event Player.fullBodyPosition) * Vector(1, Empty Array, 1) * Event Player.intersectionLength; + If(Dot Product(Direction Towards(Global.firstPosition[Global.z], Vector(X Component Of(Global.secondPosition[Global.z]), + Y Component Of(Global.firstPosition[Global.z]), Z Component Of(Global.secondPosition[Global.z]))), Direction Towards( + Global.firstPosition[Global.z], Event Player.previousPositionIntersection)) >= 0 && Dot Product(Direction Towards( + Global.firstPosition[Global.z], Vector(X Component Of(Global.firstPosition[Global.z]), Y Component Of( + Global.secondPosition[Global.z]), Z Component Of(Global.firstPosition[Global.z]))), Direction Towards( + Global.firstPosition[Global.z], Event Player.previousPositionIntersection)) >= 0 && Dot Product(Direction Towards( + Global.secondPosition[Global.z], Vector(X Component Of(Global.secondPosition[Global.z]), Y Component Of( + Global.firstPosition[Global.z]), Z Component Of(Global.secondPosition[Global.z]))), Direction Towards( + Global.secondPosition[Global.z], Event Player.previousPositionIntersection)) >= 0 && Dot Product(Direction Towards( + Global.secondPosition[Global.z], Vector(X Component Of(Global.firstPosition[Global.z]), Y Component Of( + Global.secondPosition[Global.z]), Z Component Of(Global.firstPosition[Global.z]))), Direction Towards( + Global.secondPosition[Global.z], Event Player.previousPositionIntersection)) >= 0); + Cancel Primary Action(Event Player); + Teleport(Event Player, Event Player.previousPositionIntersection + Direction Towards(Event Player.previousPositionIntersection, + Event Player.lastSavedPosition) * Vector(1, Empty Array, 1) * 2); + End; + End; + End; + Event Player.thickness = 0; + If(Global.wallId[Global.z] == 5); + Event Player.thickness = 4; + Else; + Event Player.thickness = 1; + End; + If(Distance Between(Event Player.fullBodyPosition, Event Player.filterPosition) <= Event Player.thickness && Dot Product( + Direction Towards(Global.firstPosition[Global.z], Vector(X Component Of(Global.secondPosition[Global.z]), Y Component Of( + Global.firstPosition[Global.z]), Z Component Of(Global.secondPosition[Global.z]))), Direction Towards( + Global.firstPosition[Global.z], Event Player.filterPosition)) >= 0 && Dot Product(Direction Towards( + Global.firstPosition[Global.z], Vector(X Component Of(Global.firstPosition[Global.z]), Y Component Of( + Global.secondPosition[Global.z]), Z Component Of(Global.firstPosition[Global.z]))), Direction Towards( + Global.firstPosition[Global.z], Event Player.filterPosition)) >= 0 && Dot Product(Direction Towards( + Global.secondPosition[Global.z], Vector(X Component Of(Global.secondPosition[Global.z]), Y Component Of( + Global.firstPosition[Global.z]), Z Component Of(Global.secondPosition[Global.z]))), Direction Towards( + Global.secondPosition[Global.z], Event Player.filterPosition)) >= 0 && Dot Product(Direction Towards( + Global.secondPosition[Global.z], Vector(X Component Of(Global.firstPosition[Global.z]), Y Component Of( + Global.secondPosition[Global.z]), Z Component Of(Global.firstPosition[Global.z]))), Direction Towards( + Global.secondPosition[Global.z], Event Player.filterPosition)) >= 0); + If(!Global.isGrounded); + Set Gravity(Event Player, 100); + End; + If(Event Player.activeWall[Global.z] == False); + Event Player.activeWall[Global.z] = 1; + If((Global.wallId[Global.z] == 1 || Global.wallId[Global.z] == 3) && Global.isGrounded == False); + Set Gravity(Event Player, 100); + Else If(Global.wallId[Global.z] == 5); + Disable Movement Collision With Environment(Event Player, False); + End; + End; + If(Global.wallId[Global.z] == 1); + Apply Impulse(Event Player, Direction Towards(Event Player.filterPosition, Event Player.fullBodyPosition) * Vector(1, Empty Array, + 1), 0.001, To World, Cancel Contrary Motion); + Set Move Speed(Event Player, 100 - Dot Product(Direction Towards(Eye Position(Event Player), Eye Position(Event Player) + + World Vector Of(Throttle Of(Event Player), Event Player, Rotation)), Direction Towards(Event Player.filterPosition, + Event Player.fullBodyPosition) * -1) * 100); + Else If(Global.wallId[Global.z] == 3); + Apply Impulse(Event Player, Direction Towards(Event Player.filterPosition, Event Player.fullBodyPosition), Speed Of(Event Player), + To World, Cancel Contrary Motion); + End; + Else; + Event Player.activeWall[Global.z] = 0; + Set Move Speed(Event Player, 100); + End; + End; + End; + Loop; + } +} + +rule("Reset") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Count Of(Filtered Array(Event Player.activeWall, Current Array Element != 0)) == 0; + } + + actions + { + Enable Movement Collision With Environment(Event Player); + } +} + +rule("Wall Data") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.allPositions = Array(Vector(155.968, 12.470, -30.507), Vector(155.962, 12.472, -62.500), Vector(81.153, 6.453, -103.851), + Vector(69.148, 6.474, -104.548)); + Global.allDirections = Array(Vector(-1, 0, -0.002), Vector(1, 0, -0.001), Vector(0, 0, 1), Vector(0.001, 0, 1)); + Global.firstPosition = Array(Vector(155.971, 11.047, -31.771), Vector(155.964, 11.050, -61.229), Vector(79.761, 5.030, -103.852), + Vector(67.738, 5.022, -104.547)); + Global.secondPosition = Array(Vector(155.965, 13.894, -29.242), Vector(155.960, 13.894, -63.771), Vector(82.544, 7.876, -103.851), + Vector(70.558, 7.925, -104.550)); + Global.firstPoint = Array(Vector(155.971, 13.894, -31.771), Vector(155.964, 13.894, -61.229), Vector(79.761, 7.876, -103.852), + Vector(67.738, 7.925, -104.547)); + Global.secondPoint = Array(Vector(155.965, 11.047, -29.242), Vector(155.960, 11.050, -63.771), Vector(82.544, 5.030, -103.851), + Vector(70.558, 5.022, -104.550)); + Global.z = 3; + Global.beamType = Array(1, 1, 1, 1); + Global.showWalls = True; + Global.wallId = Array(5, 5, 5, 5); + } +} + +disabled rule("NEW SHOP") +{ + event + { + Ongoing - Global; + } +} + +rule("Setting Shop Position") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.shopCamPosition = 900 * Up; + Global.shopPositionAngle[1] = Direction From Angles(Horizontal Angle From Direction(Forward), Vertical Angle From Direction( + Forward) - 90); + Global.shopPositionAngle[0] = Cross Product(Global.shopPositionAngle[1], Forward); + Global.shopBasePosition = Global.shopCamPosition - 9 * Global.shopPositionAngle[1] + 142 * Forward; + } +} + +rule("Create Shop Buttons") +{ + event + { + Ongoing - Global; + } + + actions + { + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), + Global.shopBasePosition - 41 * Global.shopPositionAngle[1] + 90 * Global.shopPositionAngle[0], 2.500, Do Not Clip, Visible To, + Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), + Global.shopBasePosition - 41 * Global.shopPositionAngle[1] - 90 * Global.shopPositionAngle[0], 2.500, Do Not Clip, Visible To, + Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Refund"), + Global.shopBasePosition + 45 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 3, Do Not Clip, Visible To, + Color(Green), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("[{0}] Leave", + Input Binding String(Button(Reload))), + Global.shopBasePosition + 45 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 3, Do Not Clip, + Visible To and String, Color(Green), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("{0}$\n", Local Player.money[0]), + Global.shopBasePosition + 36.500 * Global.shopPositionAngle[1], 3, Do Not Clip, Visible To and String, Color(White), + Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("▲"), Update Every Frame( + Global.shopBasePosition - (4 + Vertical Facing Angle Of(Local Player)) + * Global.shopPositionAngle[1] + Horizontal Facing Angle Of(Local Player) * Global.shopPositionAngle[0]), 4, Do Not Clip, + Visible To Position and Color, Custom Color(245 + 10 * Sine From Radians(4 * Total Time Elapsed), 205 + 50 * Sine From Radians( + 4 * Total Time Elapsed), 200 * Sine From Radians(4 * Total Time Elapsed), 255), Default Visibility); + "Headhunter" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[1] ? Custom String("Headhunter II\n  800$") : Custom String("Headhunter I\n  800$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[1] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Ambush" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[2] ? Custom String("Ambush II\n 800$") : Custom String("Ambush I\n 800$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[2] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Quick Fix" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[3] ? Custom String("Quick Fix II\n  700$") : Custom String("Quick Fix I\n  700$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[3] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavyweight" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[4] ? Custom String("Heavyweight II\n  1000$") : Custom String("Heavyweight I\n  1000$"), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[4] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Charged" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[5] ? Custom String("Charged II\n  700$") : Custom String("Charged I\n  700$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[5] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Haste" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[6] ? Custom String("Haste II\n 700$") : Custom String("Haste I\n 700$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[6] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavy Impact" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[7] ? Custom String("Heavy Impact II\n  1000$") : Custom String("Heavy Impact I\n  1000$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[7] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 1" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 1\n  1200$"), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[8] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "Second Wind" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[9] ? Custom String("Second Wind II\n   900$") : Custom String("Second Wind I\n   900$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[9] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Binding Heal" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[10] ? Custom String("Binding Heal II\n   700$") : Custom String("Binding Heal I\n   700$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[10] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Resilience" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[11] ? Custom String("Resilience II\n  800$") : Custom String("Resilience I\n  800$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[11] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 2" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 2\n  1200$"), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[12] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "PlusDamage" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Damage\n  400$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealth" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Health\n 400$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Healing\n  400$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To and String, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "+{0} Auto-Repair\n    400$", Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Global.automaticRepair < 5 ? Color(Green) : Color(Gray), Default Visibility); + "Use Update Every Frame to avoid showing the String when the cursor is out of bounds, resulting in 0\r\n ROW 0" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -33.750 ? Array(Custom String("Leave Buy Menu\n"), Custom String( + ""), Custom String(""), Custom String("Refund your money\n"))[Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) + / 45, Down)] : Custom String("")), Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, + Visible To and String, Color(White), Default Visibility); + "ROW 1" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 22.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -11.250 ? Array(Custom String("Increase your damage by 5%\n"), + Local Player.abilities[9] ? Custom String( + "Second Wind II: 60% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds") + : Custom String( + "Second Wind I: 30% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds"), + Local Player.abilities[5] ? Custom String("Charged II: Ultimates cost 40% less\n") : Custom String( + "Charged I: Ultimates cost 20% less\n"), Local Player.abilities[1] ? Custom String( + "Headhunter II: Critical hits deal 80% more damage\n") : Custom String("Headhunter I: Critical hits deal 40% more damage\n")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), + Default Visibility); + "ROW 2" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 36.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 11.250 ? Array(Custom String("Increase your health by 5%\n"), + Local Player.abilities[10] ? Custom String("Binding Heal II: Heal yourself for 50% the amount when healing allies\n") + : Custom String("Binding Heal I: Heal yourself for 25% the amount when healing allies\n"), + Local Player.abilities[6] ? Custom String( + " Haste II: Ability cooldown is reduced by 50%\nDoes not affect abilities with multiple charges") : Custom String( + " Haste I: Ability cooldown is reduced by 25%\nDoes not affect abilities with multiple charges"), + Local Player.abilities[2] ? Custom String("Ambush II: Deal 60% more damage when attacking enemies from behind or above\n") + : Custom String("Ambush I: Deal 30% more damage when attacking enemies from behind or above\n"))[Round To Integer(( + Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), + Default Visibility); + "ROW 3" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 83.750) < 72.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 33.750 ? Array(Custom String("Increase your healing by 5%\n"), + Local Player.abilities[11] ? Custom String("Resilience II: Take 30% less damage while below 60% health\n") : Custom String( + "Resilience I: Take 30% less damage while below 30% health\n"), Local Player.abilities[7] ? Custom String( + "Heavy Impact II: Every hit has a chance to stun the enemy for 2 seconds\n") : Custom String( + "Heavy Impact I: Every hit has a chance to stun the enemy for 1 second\n"), Local Player.abilities[3] ? Custom String( + "Quick Fix II: Eliminations restore 100 HP and shortly increase speed by 40%\n") : Custom String( + "Quick Fix I: Eliminations restore 50 HP and shortly increase speed by 20%\n"))[Round To Integer((Horizontal Facing Angle Of( + Local Player) + 90) / 45, Down)] : Custom String("")), Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, + Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 4" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 133) < 99.250 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 56.250 ? Array(Custom String( + "Increase your auto-repair by {0}/5s\n", Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Custom String("{0}", Local Player.heroTalentText[2][1]), Custom String("{0}", Local Player.heroTalentText[1][1]), + Local Player.abilities[4] ? Custom String( + "Heavyweight II: Your knock back attacks deal 50% more damage and knock back\n            You receive 33% less knock back") + : Custom String( + "Heavyweight I: Your knock back attacks deal 25% more damage and knock back\n            You receive 20% less knock back")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), + Default Visibility); + } +} + +rule("Toggle Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + !Is Dummy Bot(Event Player) == True; + Is Button Held(Event Player, Button(Reload)) == True; + !Is Communicating Any Emote(Event Player) == True; + } + + actions + { + If(Event Player.isInMenu == False); + Wait Until(!Is Button Held(Event Player, Button(Reload)), 0.500); + If(!Is Button Held(Event Player, Button(Reload))); + Abort; + End; + End; + Event Player.isInMenu = !Event Player.isInMenu; + } +} + +rule("Open Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == True; + } + + actions + { + Event Player.playerFacing = Facing Direction Of(Event Player); + Start Camera(Event Player, Global.shopCamPosition, Global.shopCamPosition + Forward, 0); + Disable Hero HUD(Event Player); + Call Subroutine(DisablePlayer); + Set Aim Speed(Event Player, 200); + } +} + +rule("Close Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + "Open Shop" + Event Player.isInMenu == False; + } + + actions + { + Stop Camera(Event Player); + Enable Hero HUD(Event Player); + Call Subroutine(EnablePlayer); + Set Aim Speed(Event Player, 100); + Set Facing(Event Player, Event Player.playerFacing, To World); + } +} + +rule("Subroutine: Disable Player") +{ + event + { + Subroutine; + DisablePlayer; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + Set Primary Fire Enabled(Event Player, False); + Set Secondary Fire Enabled(Event Player, False); + Set Ability 1 Enabled(Event Player, False); + Set Ability 2 Enabled(Event Player, False); + Set Melee Enabled(Event Player, False); + Set Jump Enabled(Event Player, False); + Set Crouch Enabled(Event Player, False); + Disallow Button(Event Player, Button(Ultimate)); + } +} + +rule("Subroutine: Enable Player") +{ + event + { + Subroutine; + EnablePlayer; + } + + actions + { + Stop Forcing Throttle(Event Player); + Set Primary Fire Enabled(Event Player, True); + Set Secondary Fire Enabled(Event Player, True); + Set Ability 1 Enabled(Event Player, True); + Set Ability 2 Enabled(Event Player, True); + Set Melee Enabled(Event Player, True); + Set Jump Enabled(Event Player, True); + Set Crouch Enabled(Event Player, True); + Allow Button(Event Player, Button(Ultimate)); + } +} + +rule("Buy Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Primary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + Event Player.isInMenu = !Event Player.isInMenu; + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.money[1] != 0); + Call Subroutine(Refund); + Else; + Small Message(Local Player, Custom String("You don't have anything to refund!")); + End; + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Event Player.abilities[13] += 1; + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.damageDealt); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[9] != 2); + If(Event Player.money[0] >= 900); + Event Player.money[0] -= 900; + Event Player.money[1] += 900; + Event Player.abilities[9] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[5] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[5] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[1] != 2); + If(Event Player.money[0] >= 800); + Event Player.money[0] -= 800; + Event Player.money[1] += 800; + Event Player.abilities[1] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Event Player.abilities[14] += 1; + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[10] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[10] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[6] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[6] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[2] != 2); + If(Event Player.money[0] >= 800); + Event Player.money[0] -= 800; + Event Player.money[1] += 800; + Event Player.abilities[2] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Event Player.abilities[15] += 1; + Set Healing Dealt(Event Player, 100 + Event Player.abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[11] != 2); + If(Event Player.money[0] >= 800); + Event Player.money[0] -= 800; + Event Player.money[1] += 800; + Event Player.abilities[11] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[7] != 2); + If(Event Player.money[0] >= 1000); + Event Player.money[0] -= 1000; + Event Player.money[1] += 1000; + Event Player.abilities[7] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[3] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[3] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Global.automaticRepair != 5); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Global.automaticRepair += 1; + Event Player.abilities[16] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[12] != 1); + If(Event Player.money[0] >= 1200); + Event Player.money[0] -= 1200; + Event Player.money[1] += 1200; + Event Player.abilities[12] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[8] != 1); + If(Event Player.money[0] >= 1200); + Event Player.money[0] -= 1200; + Event Player.money[1] += 1200; + Event Player.abilities[8] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[4] != 2); + If(Event Player.money[0] >= 1000); + Event Player.money[0] -= 1000; + Event Player.money[1] += 1000; + Event Player.abilities[4] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + End; + } +} + +rule("Refund Single Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Secondary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[13] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Event Player.abilities[13] -= 1; + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.damageDealt); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[9] != 0); + Event Player.money[0] += 900; + Event Player.money[1] -= 900; + Event Player.abilities[9] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[5] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[5] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[1] != 0); + Event Player.money[0] += 800; + Event Player.money[1] -= 800; + Event Player.abilities[1] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[14] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Event Player.abilities[14] -= 1; + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[10] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[10] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[6] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[6] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[2] != 0); + Event Player.money[0] += 800; + Event Player.money[1] -= 800; + Event Player.abilities[2] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[15] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Event Player.abilities[15] -= 1; + Set Healing Dealt(Event Player, 100 + Event Player.abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[11] != 0); + Event Player.money[0] += 800; + Event Player.money[1] -= 800; + Event Player.abilities[11] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[7] != 0); + Event Player.money[0] += 1000; + Event Player.money[1] -= 1000; + Event Player.abilities[7] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[3] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[3] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[16] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Global.automaticRepair -= 1; + Event Player.abilities[16] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[12] != 0); + Event Player.money[0] += 1200; + Event Player.money[1] -= 1200; + Event Player.abilities[12] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[8] != 0); + Event Player.money[0] += 1200; + Event Player.money[1] -= 1200; + Event Player.abilities[8] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[4] != 0); + Event Player.money[0] += 1000; + Event Player.money[1] -= 1000; + Event Player.abilities[4] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + End; + } +} + +rule("Create Player HUD") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Custom String("{0}{1}", + Event Player, Event Player.isInMenu ? Custom String("(In Shop)") : Custom String("")), Custom String("{0}{1}", Is Alive( + Event Player) ? Custom String("{0} HP", Round To Integer(Health(Event Player), Up)) : Custom String("Dead"), Custom String( + ", {0}$", Event Player.money)), Left, Local Player == Event Player ? -1 : Slot Of(Event Player), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), + Visible To Sort Order String and Color, Default Visibility); + Create HUD Text(Event Player.abilities[13] || Global.damageDealt ? Event Player : Null, Null, Null, Custom String("+{0}% Damage", + Global.damageDealt + Event Player.abilities[13] * 5), Left, 913, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[9] ? Event Player : Null, Null, Null, Custom String("Second Wind {0}", + Event Player.abilities[9] == 1 ? Custom String("I") : Custom String("II")), Left, 908, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[5] ? Event Player : Null, Null, Null, Custom String("Charged {0}", + Event Player.abilities[5] == 1 ? Custom String("I") : Custom String("II")), Left, 905, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[1] ? Event Player : Null, Null, Null, Custom String("Headhunter {0}", + Event Player.abilities[1] == 1 ? Custom String("I") : Custom String("II")), Left, 901, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[14] || Global.maxHealthDone ? Event Player : Null, Null, Null, Custom String("+{0}% Health", + Global.maxHealthDone + Event Player.abilities[14] * 5), Left, 914, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[10] ? Event Player : Null, Null, Null, Custom String("Binding Heal {0}", + Event Player.abilities[10] == 1 ? Custom String("I") : Custom String("II")), Left, 909, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[6] ? Event Player : Null, Null, Null, Custom String("Haste {0}", + Event Player.abilities[6] == 1 ? Custom String("I") : Custom String("II")), Left, 906, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[2] ? Event Player : Null, Null, Null, Custom String("Ambush {0}", + Event Player.abilities[2] == 1 ? Custom String("I") : Custom String("II")), Left, 902, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[15] ? Event Player : Null, Null, Null, Custom String("+{0}% Healing", + Event Player.abilities[15] * 5), Left, 915, Color(White), Color(White), Color(Turquoise), Visible To and String, + Default Visibility); + Create HUD Text(Event Player.abilities[11] ? Event Player : Null, Null, Null, Custom String("Resilience {0}", + Event Player.abilities[11] == 1 ? Custom String("I") : Custom String("II")), Left, 910, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[7] ? Event Player : Null, Null, Null, Custom String("Heavy Impact {0}", + Event Player.abilities[7] == 1 ? Custom String("I") : Custom String("II")), Left, 907, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[3] ? Event Player : Null, Null, Null, Custom String("Quick Fix {0}", + Event Player.abilities[3] == 1 ? Custom String("I") : Custom String("II")), Left, 903, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Global.automaticRepair ? Event Player : Null, Null, Null, Custom String("{0} total Auto-Repair/5s", + Global.automaticRepair * (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 10 : 5)), Left, 916, + Color(White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[12] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.heroTalentText[2][0], Event Player.heroTalentText[2][1]), Top, 902, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[12] ? Event Player : Null, Null, Null, Custom String("Hero Talent 2"), Left, 912, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[8] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.heroTalentText[1][0], Event Player.heroTalentText[1][1]), Top, 901, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[8] ? Event Player : Null, Null, Null, Custom String("Hero Talent 1"), Left, 911, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[4] ? Event Player : Null, Null, Null, Custom String("Heavyweight {0}", + Event Player.abilities[4] == 1 ? Custom String("I") : Custom String("II")), Left, 904, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + } +} + +rule("Rein Pin detect") +{ + event + { + Player Dealt Knockback; + Team 1; + Reinhardt; + } + + conditions + { + Event Ability == Button(Ability 1); + Has Status(Victim, Stunned) == True; + } + + actions + { + Event Player.reinPin = Victim; + Wait(1, Ignore Condition); + Event Player.reinPin = Null; + } +} + +rule("Boss Rotation") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.activeBoss == True; + } + + actions + { + If(Global.bossRotation == 0 || Global.bossRotation == 3); + Global.bossRotation = 1; + Global.lastBoss[1] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 1); + Global.bossRotation = 2; + Global.lastBoss[2] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 2); + Global.bossRotation = 3; + Global.lastBoss[3] = Hero Of(Global.activeBoss); + End; + } +} + +rule("BOSS HUD") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 10; + } + + actions + { + Create HUD Text(All Players(Team 1), Global.activeBoss ? Custom String("Boss: {0}, HP: {1}/{2}", Hero Of(Global.activeBoss), + Health(Global.activeBoss), Max Health(Global.activeBoss)) : Custom String(""), Null, Null, Top, 900, Color(Red), Color(White), + Color(White), Visible To and String, Default Visibility); + } +} + +rule("DEBUG - SKIP TIME") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.isDebug == True; + (Is Button Held(Event Player, Button(Primary Fire)) && Is Button Held(Event Player, Button(Crouch))) == True; + } + + actions + { + Global.timeSeconds = 59; + } +} + +disabled rule("DEBUG COLLECTION - Make Invincible, Show Player Coords") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.isDebug == True; + } + + actions + { + Create HUD Text(Local Player, Custom String("{0}", Position Of(Local Player)), Null, Null, Left, 0, Color(Yellow), Color(White), + Color(White), Visible To and String, Default Visibility); + Set Status(Event Player, Null, Invincible, 9999); + Set Status(Event Player, Null, Phased Out, 9999); + } +} + +rule("OPTIONAL ENDING - CREATE EXFIL POINT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("Exfiltration available! (optional - ends the mode)"), Null, Null, Top, 50, + Color(Red), Color(White), Color(White), Visible To and String, Default Visibility); + Global.globalHUDs[1] = Last Text ID; + Create In-World Text(All Players(Team 1), Custom String( + "Exfiltration available! Gather here!\n{0}/{1} Players ready to exfiltrate!", Count Of(Filtered Array(All Players(Team 1), + Distance Between(Vector(186, 11, -46.500), Current Array Element) <= 9)), Count Of(All Players(Team 1))), Vector(186, 15, + -46.500), 1.200, Do Not Clip, Visible To and String, Color(Green), Default Visibility); + Wait(3, Ignore Condition); + Destroy HUD Text(Global.globalHUDs[1]); + } +} + +rule("OPTIONAL ENDING - EXFIL PLAYERS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + Count Of(Filtered Array(All Players(Team 1), Distance Between(Vector(186, 11, -46.500), All Players(Team 1)) <= 9)) >= Count Of( + All Players(Team 1)) / 2; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GG! YOU DID IT!")); + Destroy All Dummy Bots; + Disable Movement Collision With Environment(All Players(Team 1), True); + Start Accelerating(All Players(Team 1), Up, 100, 5, To World, Direction Rate and Max Speed); + Wait(5, Ignore Condition); + Declare Team Victory(Team 1); + } +} + +rule("Team 1 (Ability): Second Wind save life") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + conditions + { + Event Player.abilities[9] == True; + Event Player.secondWindActive == True; + Health(Event Player) == 1; + } + + actions + { + Small Message(All Players(All Teams), Custom String("{0} received a second wind!", Event Player)); + Play Effect(All Players(All Teams), Good Pickup Effect, Color(Green), Event Player, 1); + Clear Status(Event Player, Unkillable); + Set Player Health(Event Player, Max Health(Event Player)); + Event Player.lastSecondWind = 30; + Event Player.secondWindActive = 0; + } +} + +rule("Team 1 (Ability): Second Wind after buying") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[9] == True; + Event Player.secondWindActive == False; + Event Player.lastSecondWind == 0; + } + + actions + { + If(Random Integer(1, 100) > Event Player.abilities[9] * 30); + Wait(30, Ignore Condition); + Loop; + End; + Set Status(Event Player, Null, Unkillable, 9999); + Event Player.secondWindActive = 1; + } +} + +rule("Team 1 (Ability): Second Wind counter") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Player.lastSecondWind > 0; + } + + actions + { + Wait(1, Ignore Condition); + Event Player.lastSecondWind -= 1; + Loop If Condition Is True; + } +} + +rule("Team 1: Change Hero") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Distance Between(Vector(159, 11, -46.500), Event Player) <= 2; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + Set Player Allowed Heroes(Event Player, Hero(Pharah)); + Set Player Allowed Heroes(Event Player, Hero(Ana)); + Reset Player Hero Availability(Event Player); + Wait(0.500, Ignore Condition); + Wait Until(Has Spawned(Event Player), 99999); + Teleport(Event Player, Vector(159, 11, -46.500)); + } +} diff --git a/defendTheCastleExtended/old_versions/c135.ow b/defendTheCastleExtended/old_versions/c135.ow new file mode 100644 index 0000000..6a40a50 --- /dev/null +++ b/defendTheCastleExtended/old_versions/c135.ow @@ -0,0 +1,7758 @@ +settings +{ + main + { + Description: "Defend The Castle Extended Version c135\nby ShuriZma#2349\nJ1K6F (Code Version: c132)\nOriginal mode by HuKuTa94#2589\n\nDefend the gate, kill enemies and don't allow them to damage the gate!\n\nSpecial Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents\n& Josbird for teaching me about Menus!\n\nFind this mode on: workshop.codes/defend-the-castle\nFind the Original Mode on: workshop.codes/BQEGS\nTell me what you think on Discord: dc.shuri.gg\n\nPS: SHINGEN PLS COME BACK" + Mode Name: "Defend The Castle Extended" + } + + lobby + { + Max Spectators: 0 + Max Team 1 Players: 4 + Max Team 2 Players: 0 + Return To Lobby: Never + Swap Teams After Match: No + } + + modes + { + Escort + { + enabled maps + { + Havana + } + } + + Team Deathmatch + { + enabled maps + { + } + } + + General + { + Game Mode Start: Immediately + Spawn Health Packs: Disabled + } + } + + extensions + { + Beam Effects + Kinetic Explosion Effects + Energy Explosion Effects + Explosion Sounds + Play More Effects + Spawn More Dummy Bots + } +} + +variables +{ + global: + 0: gatePosition + 1: zenSpawnPositions + 2: spawnPositionMaxId + 3: loopIterator1 + 4: bigBossSpawnPositions + 5: playerSpawnPositions + 6: gateHealthChase + 7: gateHealth + 8: gateMaxHealth + 9: gateProgressBarColorCurrent + 10: gateProgressBarColorComponent + 11: gateHealthEvent + 12: bastionTargetPositions + 13: sniperPositions + 14: ballSpawnPositions + 15: zenRespawnTime + 16: timeSeconds + 17: timeMinutes + 18: defaultCurrentBot + 19: defaultHeroBotsPool + 20: defaultHeroBotsPoolCurrentId + 21: isDebug + 22: botOrisaParent + 24: botOrisaChild + 25: gateRepairPosition + 26: botOrisaTargetPosition + 27: botEchoRespawnPosition + 28: botEchoTeleportPositions + 29: upgradeGateMaxHealthValue + 30: upgradeGateMaxHealthHudId + 31: upgradePlayerMaxHealthValue + 32: upgradePlayerMaxHealthHudId + 33: upgradeCriticalDamageValue + 34: upgradeCriticalDamageHudId + 35: upgradeMaxAmmoValue + 36: upgradeMaxAmmoHudId + 37: upgradeMaxAmmoMaxValue + 38: upgradePlayerMaxHealthMaxValue + 39: upgradeCriticalDamageMaxValue + 40: upgradeGateMaxHealthMaxValue + 41: damageDealt + 42: isDebugAINavigation + 43: gameLogicCountOfUniqueHeroes + 44: isNewWaveGameLogicProcessing + 45: automaticRepair + 46: upgradePerkSharpshooterValue + 47: perk + 48: maxHealthDone + 49: startMoney + 50: time5Minutes + 51: selfNanoWorkshopSetting + 52: shopCamPosition + 53: shopBasePosition + 54: shopPositionAngle + 55: activeBoss + 57: bossRotation + 58: lastBoss + 59: time10Minutes + 60: moneyMultiplier + 61: challengeCount + 62: upgradeBossHealthValue + 63: globalHUDs + 112: allPositions + 113: allDirections + 114: firstPosition + 115: secondPosition + 116: firstPoint + 117: secondPoint + 118: second + 119: z + 120: wallId + 121: showWalls + 122: isGrounded + 123: beamType + 125: nodePositions + 126: nodeConnections + 127: distanceMatrix + + player: + 0: botSeePlayer + 1: botDoesUniqueBehaviour + 2: botEffects + 3: botRayCastHitPosition + 4: botEventPosition + 5: currentHero + 6: isDead + 7: isRespawning + 8: botBastionArtilleryDidShotsCount + 9: botCounter + 10: hasBadStatus + 11: eventHealth + 12: healOverTimeId + 13: botIsOrisaChild + 14: botEchoCapturedPlayer + 15: botPlayersInRadius + 16: botLoopIterator2 + 17: botWidowShotTime + 18: botWidowTeleportTime + 19: isNanoed + 20: abilityHUD + 21: lucioDashActive + 22: lucioDashIcon + 23: anaEntityID + 24: abilities + 25: money + 26: heroTalentText + 27: damageDealt + 28: playerHealth + 29: abilityCountdown + 30: hpPool + 31: effects_ + 32: abilityProjectile1 + 33: abilityEnd + 34: stormProjectile + 35: stormEndPoint + 36: stormEffects + 37: fearedUntil + 38: modificationDamage + 39: abilityProjectile2 + 40: abilityPosition + 41: chainReactionOn + 42: chainReactionImmune + 43: abilityActive + 44: abilityResource + 45: secondWindActive + 46: isInMenu + 48: playerFacing + 49: isBoss + 50: genDirection + 51: genAvailable + 52: abilityPlayer + 53: deathPosition + 54: lastSecondWind + 55: vote + 105: filterPosition + 106: lastSavedPosition + 107: closestBodyPosition + 108: fullBodyPosition + 109: previousPositionIntersection + 110: activeWall + 111: closestWall + 112: x + 113: intersectionLength + 114: thickness + 115: botCancelPathFinding + 116: botLoopIterator1 + 117: botTempArray + 118: botTargetPlayer + 119: botTargetPosition + 120: botClosestNodeIdToTarget + 121: botClosestNodeIdToBot + 122: botPreviousNodeId + 123: botNextNodeId + 124: botNextNodePosition + 125: botCurrentDistanceToTarget + 126: botShortestDistanceToTarget + 127: botIsPathFinding +} + +subroutines +{ + 0: BotBastionArtilleryDamage + 2: BotBastionRespawn + 3: GateProgressBarColor + 4: BotZenyattaRespawn + 5: BotWidowRespawn + 6: BotBallRespawn + 7: GameLogicAddNextHeroInGame + 8: BotOrisaRespawn + 9: BotLandingFromSky + 10: BotEchoRespawn + 11: BotEchoDetachPlayer + 12: BotEchoFlyToPlayer + 13: BotEchoFlyToPortal + 14: GameLogicSetBotProperties + 15: DisablePlayer + 16: BotAppearFromUnderground + 17: BotReinRespawn + 18: PlayerInit + 19: BotInit + 20: PlayerRespawn + 21: BotRespawn + 22: BotWidowBadStatus + 23: GameLogicWave0 + 24: Refund + 25: EnablePlayer + 26: GateRepair + 124: BotStartPathFinding + 125: BotGetClosestNodeIdToTarget + 126: BotGetNextNodeIdAndPosition + 127: BotResetPathFinding +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("MAP: HAVANA") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Havana); + } + + actions + { + Global.nodePositions = Array(Vector(147.588, 6.425, -46.749), Vector(136.181, 6.425, -57.159), Vector(130.189, 6.425, -63.781), + Vector(123.305, 6.425, -57.983), Vector(125.678, 6.504, -46.633), Vector(114.485, 7.471, -46.699), Vector(138.743, 6.425, + -32.974), Vector(126.498, 6.425, -39.920), Vector(124.572, 10.434, -34.300), Vector(138.605, 5.359, -18.647), Vector(119.009, + 2.331, -31.024), Vector(121.138, 5.228, -19.933), Vector(126.722, 6.425, -29.505), Vector(102.762, 3.157, -33.609), Vector( + 76.030, 7.418, -74.087), Vector(83.720, 9.425, -33.744), Vector(97.439, 7.238, -42.379), Vector(86.252, 12.416, -47.261), + Vector(65.178, 11.425, -73.187), Vector(97.466, 7.269, -50.596), Vector(113.039, 7.424, -37.337), Vector(106.179, 7.450, + -46.143), Vector(90.086, 7.411, -44.653), Vector(78.752, 7.418, -62.140), Vector(82.124, 7.428, -44.229), Vector(90.675, 7.231, + -51.234), Vector(85.717, 4.692, -63.446), Vector(90.830, 4.330, -70.697), Vector(102.425, 2.387, -72.817), Vector(81.443, + 4.425, -81.648), Vector(70.743, 6.418, -81.495), Vector(69.738, 6.419, -96.344), Vector(127.586, 12.643, -63.344), Vector( + 118.911, 13.468, -58.008), Vector(102.885, 1.092, -56.579), Vector(100.009, 2.967, -67.139), Vector(106.703, 0.465, -44.628), + Vector(81.695, 7.418, -52.140), Vector(126.979, 12.393, -55.079), Vector(153.720, 18.578, -21.745), Vector(155.301, 18.619, + -17.595), Vector(133.043, 10.425, -26.625), Vector(114.646, 7.278, -57.336), Vector(95.160, 3.688, -81.194), Vector(78.456, + 5.418, -93.581), Vector(75.455, 5.418, -101.492), Vector(148.071, 9.432, -32.123), Vector(146.706, 9.425, -27.858), Vector( + 144.273, 9.445, -63.119), Vector(144.278, 9.454, -58.447)); + Global.nodeConnections = Array(Array(1, 6, 4, 7), Array(2, 1, 4, 6, 7, 0, 49), Array(1, 3), Array(2, 4, 42), Array(3, 1, 5, 7, 6, + 1, 0), Array(4, 7, 20, 21, 19, 16, 42), Array(7, 1, 4, 1, 9, 12, 0, 46), Array(4, 5, 6, 1, 1, 12, 0), Array(7, 41), Array(6, + 11), Array(11, 13), Array(9, 10, 13), Array(6, 7, 10), Array(10, 16, 36), Array(18, 23, 30), Array(17, 24), Array(13, 19, 22, + 21, 25, 5), Array(15, 22, 25, 23), Array(14), Array(16, 21, 22, 26, 27, 35, 25, 5), Array(5, 13, 10), Array(19, 16, 5, 13, 22, + 34), Array(16, 19, 21, 24, 25), Array(14, 25, 26, 37), Array(22, 15, 37), Array(23, 22, 19, 16, 26, 27, 35, 37), Array(25, 19, + 27, 35, 29), Array(19, 26, 25, 29, 35, 43), Array(35, 34, 43), Array(27, 26, 30, 43, 44), Array(29, 14, 31), Array(30, 29, 45), + Array(33, 38, 1, 48), Array(32, 38, 42), Array(35, 36, 28), Array(28, 19, 25, 27, 26, 34), Array(13, 34), Array(25, 23, 24), + Array(5, 4, 1, 6, 1, 32, 33, 0), Array(40), Array(39), Array(6, 8, 47, 46), Array(3, 5, 34), Array(28, 27, 29, 44), Array(29, + 43, 45), Array(44, 31), Array(6, 47), Array(46, 41), Array(49, 32), Array(1, 0, 6, 48)); + Global.distanceMatrix = Array(Array(0, 1, 2, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, + 4, 5, 4, 4, 5, 5, 5, 0, 0, 4, 3, 5, 6, 7, 2, 3, 3, 2), Array(1, 0, 1, 2, 1, 2, 1, 1, 5, 2, 3, 3, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, + 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 3, 4, 4, 4, 5, 5, 4, 0, 0, 4, 3, 5, 6, 7, 2, 3, 2, 1), Array(2, 1, 0, 1, 2, 3, 2, 2, 6, 3, 4, 4, + 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 4, 6, 7, 8, 4, 5, 3, 4, 4, 6, 5, 0, 0, 5, 2, 5, 6, 7, 3, 4, 3, 2), Array(2, 2, + 1, 0, 1, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, 5, 6, 2, 3, 3, 5, 6, 0, 0, 5, 1, 4, + 5, 6, 3, 4, 4, 3), Array(1, 1, 2, 1, 0, 1, 1, 1, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, + 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, 2, 3, 3, 2), Array(2, 2, 3, 2, 1, 0, 2, 1, 6, 3, 2, 3, 2, 2, 4, 4, 1, 5, 5, 1, 1, 1, 2, 3, + 3, 2, 2, 2, 3, 3, 4, 5, 5, 6, 2, 2, 3, 3, 6, 0, 0, 5, 1, 3, 4, 5, 3, 4, 4, 3), Array(1, 1, 2, 2, 1, 2, 0, 1, 4, 1, 2, 2, 1, 3, + 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 4, 5, 4, 4, 4, 5, 5, 0, 0, 3, 3, 5, 6, 7, 1, 2, 3, 2), Array(1, 1, 2, 2, + 1, 1, 1, 0, 5, 2, 2, 3, 1, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 4, 5, 3, 3, 4, 4, 5, 0, 0, 4, 2, 4, 5, 6, + 2, 3, 3, 2), Array(2, 2, 3, 3, 2, 2, 2, 1, 0, 3, 3, 4, 2, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, + 5, 5, 6, 0, 0, 1, 3, 5, 6, 7, 2, 2, 4, 3), Array(2, 2, 3, 3, 2, 3, 1, 2, 5, 0, 2, 1, 2, 2, 6, 6, 3, 7, 7, 4, 4, 4, 4, 5, 5, 4, + 5, 5, 5, 6, 7, 8, 5, 6, 4, 5, 3, 5, 6, 0, 0, 4, 4, 6, 7, 8, 2, 3, 4, 3), Array(4, 4, 5, 5, 4, 3, 3, 4, 7, 2, 0, 1, 4, 1, 5, 5, + 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 7, 8, 3, 4, 2, 4, 8, 0, 0, 6, 4, 5, 6, 7, 4, 5, 6, 5), Array(3, 3, 4, 4, 3, 3, + 2, 3, 6, 1, 1, 0, 3, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 4, 4, 4, 5, 6, 7, 6, 7, 3, 4, 2, 4, 7, 0, 0, 5, 4, 5, 6, 7, 3, 4, + 5, 4), Array(2, 2, 3, 3, 2, 2, 1, 1, 5, 2, 1, 2, 0, 2, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 5, 5, 6, 7, 5, 6, 4, 4, 3, 5, + 6, 0, 0, 4, 3, 5, 6, 7, 2, 3, 4, 3), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 3, 1, 2, 4, 0, 4, 4, 1, 5, 5, 2, 3, 2, 2, 3, 3, 2, 3, 3, + 3, 4, 5, 6, 7, 8, 2, 3, 1, 3, 8, 0, 0, 7, 3, 4, 5, 6, 5, 6, 6, 5), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 5, 6, 6, 4, 0, 4, 3, 5, + 1, 3, 5, 4, 3, 1, 3, 2, 2, 3, 4, 2, 1, 2, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 3, 3, 3, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, + 5, 10, 7, 5, 6, 6, 4, 3, 0, 3, 1, 4, 3, 5, 3, 2, 2, 1, 2, 3, 3, 4, 4, 4, 5, 9, 10, 4, 3, 5, 2, 10, 0, 0, 9, 5, 4, 5, 6, 7, 8, + 8, 7), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 3, 3, 0, 4, 4, 1, 2, 1, 1, 2, 2, 1, 2, 2, 3, 3, 4, 5, 6, 7, 2, 2, 2, 2, + 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 1, 2, 0, 3, 2, 4, 2, 1, 1, 2, 1, 2, 2, + 3, 3, 3, 4, 8, 9, 3, 2, 4, 2, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 6, 7, 7, 5, 1, 5, 4, 6, + 0, 4, 6, 5, 4, 2, 4, 3, 3, 4, 5, 3, 2, 3, 10, 11, 5, 4, 6, 3, 11, 0, 0, 10, 6, 4, 4, 4, 8, 9, 9, 8), Array(3, 3, 4, 3, 2, 1, 3, + 2, 7, 4, 3, 4, 3, 2, 3, 3, 1, 4, 4, 0, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 3, 4, 6, 7, 2, 1, 3, 2, 7, 0, 0, 6, 2, 2, 3, 4, 4, 5, 5, + 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 3, 1, 2, 3, 1, 5, 5, 2, 6, 6, 2, 0, 2, 3, 4, 4, 3, 3, 3, 4, 4, 5, 6, 6, 7, 3, 3, 2, 4, 7, + 0, 0, 6, 2, 4, 5, 6, 4, 5, 5, 4), Array(3, 3, 4, 3, 2, 1, 3, 2, 7, 4, 2, 3, 3, 1, 4, 3, 1, 4, 5, 1, 2, 0, 1, 3, 2, 2, 2, 2, 2, + 3, 4, 5, 6, 7, 1, 2, 2, 3, 7, 0, 0, 6, 2, 3, 4, 5, 4, 5, 5, 4), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 3, 2, 1, 3, 4, + 1, 3, 1, 0, 2, 1, 1, 2, 2, 3, 3, 4, 5, 7, 8, 2, 2, 3, 2, 8, 0, 0, 7, 3, 3, 4, 5, 5, 6, 6, 5), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, + 6, 4, 5, 5, 3, 1, 3, 2, 4, 2, 2, 4, 3, 2, 0, 2, 1, 1, 2, 3, 2, 2, 3, 8, 9, 3, 2, 4, 1, 9, 0, 0, 8, 4, 3, 3, 4, 6, 7, 7, 6), + Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 3, 1, 2, 2, 4, 2, 4, 2, 1, 2, 0, 2, 3, 3, 4, 4, 4, 5, 8, 9, 3, 3, 4, 1, 9, 0, + 0, 8, 4, 4, 5, 6, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 3, 4, 4, 2, 2, 3, 1, 4, 3, 1, 3, 2, 1, 1, 2, 0, 1, 1, 2, 2, + 3, 4, 7, 8, 2, 1, 3, 1, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, + 3, 2, 2, 2, 3, 1, 0, 1, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 2, 2, 3, 5, 6, 6, 5), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, + 4, 5, 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 0, 2, 1, 2, 3, 7, 8, 2, 1, 3, 2, 8, 0, 0, 7, 3, 1, 2, 3, 5, 6, 6, 5), Array( + 5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 4, 5, 3, 6, 5, 2, 4, 3, 3, 3, 4, 2, 2, 2, 0, 2, 3, 4, 8, 9, 1, 1, 2, 3, 9, 0, 0, 8, + 4, 1, 2, 3, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 2, 5, 3, 6, 3, 2, 4, 3, 3, 3, 4, 2, 1, 1, 2, 0, 1, 2, + 8, 9, 3, 2, 4, 3, 9, 0, 0, 8, 4, 1, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 1, 5, 4, 6, 2, 3, 5, 4, + 4, 2, 4, 3, 2, 2, 3, 1, 0, 1, 9, 10, 4, 3, 5, 3, 10, 0, 0, 9, 5, 2, 2, 2, 7, 8, 8, 7), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, + 7, 6, 5, 2, 6, 4, 7, 3, 3, 5, 4, 4, 3, 5, 3, 2, 2, 3, 1, 1, 0, 9, 10, 4, 3, 5, 4, 10, 0, 0, 9, 5, 2, 2, 1, 7, 8, 8, 7), Array( + 2, 1, 2, 3, 2, 2, 2, 2, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 4, 5, 6, 7, 0, 1, 3, 4, 4, 5, 1, 0, 0, 5, + 2, 5, 6, 7, 3, 4, 1, 2), Array(2, 2, 3, 2, 2, 2, 2, 3, 6, 3, 4, 4, 3, 4, 6, 6, 3, 7, 7, 3, 3, 3, 4, 5, 5, 4, 4, 4, 3, 5, 6, 7, + 1, 0, 2, 3, 3, 5, 1, 0, 0, 5, 1, 4, 5, 6, 3, 4, 2, 3), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 5, 3, 4, 5, 2, 4, 5, 3, 6, 5, 2, 4, 3, + 3, 3, 4, 2, 2, 2, 1, 3, 4, 5, 8, 9, 0, 1, 1, 3, 9, 0, 0, 8, 4, 2, 3, 4, 6, 7, 7, 6), Array(4, 4, 5, 4, 3, 2, 4, 3, 8, 5, 4, 5, + 4, 3, 3, 4, 2, 5, 4, 1, 3, 2, 2, 2, 3, 1, 1, 1, 1, 2, 3, 4, 7, 8, 1, 0, 2, 2, 8, 0, 0, 7, 3, 2, 3, 4, 5, 6, 6, 5), Array(5, 5, + 6, 5, 4, 3, 5, 4, 9, 4, 2, 3, 5, 1, 5, 5, 2, 6, 6, 3, 4, 3, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 8, 9, 1, 2, 0, 4, 9, 0, 0, 8, 4, 3, + 4, 5, 6, 7, 7, 6), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 4, 5, 5, 3, 2, 2, 2, 3, 3, 2, 4, 3, 2, 1, 1, 1, 2, 2, 3, 3, 3, 4, 8, 9, + 3, 2, 4, 0, 9, 0, 0, 8, 4, 3, 4, 5, 6, 7, 7, 6), Array(1, 1, 2, 2, 1, 1, 1, 2, 5, 2, 3, 3, 2, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, + 4, 3, 3, 3, 4, 4, 5, 6, 1, 1, 3, 3, 4, 4, 0, 0, 0, 4, 2, 4, 5, 6, 2, 3, 2, 2), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), Array(2, 2, 3, 3, 2, 3, 1, 2, 1, 2, 3, 3, 2, + 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 0, 4, 6, 7, 8, 1, 1, 4, 3), Array(3, 3, 2, + 1, 2, 1, 3, 2, 7, 4, 3, 4, 3, 3, 5, 5, 2, 6, 6, 2, 2, 2, 3, 4, 4, 3, 3, 3, 2, 4, 5, 6, 6, 7, 1, 2, 2, 4, 7, 0, 0, 6, 0, 3, 4, + 5, 4, 5, 5, 4), Array(5, 5, 6, 5, 4, 3, 5, 4, 9, 6, 5, 6, 5, 4, 3, 5, 3, 6, 4, 2, 4, 3, 3, 3, 4, 2, 2, 1, 1, 1, 2, 3, 8, 9, 2, + 2, 3, 3, 9, 0, 0, 8, 4, 0, 1, 2, 6, 7, 7, 6), Array(6, 6, 7, 6, 5, 4, 6, 5, 10, 7, 6, 7, 6, 5, 3, 6, 4, 7, 4, 3, 5, 4, 4, 4, 5, + 3, 2, 2, 2, 1, 2, 2, 9, 10, 3, 3, 4, 4, 10, 0, 0, 9, 5, 1, 0, 1, 7, 8, 8, 7), Array(7, 7, 8, 7, 6, 5, 7, 6, 11, 8, 7, 8, 7, 6, + 3, 7, 5, 8, 4, 4, 6, 5, 5, 4, 6, 4, 3, 3, 3, 2, 2, 1, 10, 11, 4, 4, 5, 5, 11, 0, 0, 10, 6, 2, 1, 0, 8, 9, 9, 8), Array(2, 2, 3, + 3, 2, 3, 1, 2, 3, 2, 3, 3, 2, 4, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 5, 6, 5, 5, 5, 6, 6, 0, 0, 2, 4, 6, 7, + 8, 0, 1, 4, 3), Array(3, 3, 4, 4, 3, 4, 2, 3, 2, 3, 4, 4, 3, 5, 8, 8, 5, 9, 9, 5, 5, 5, 6, 7, 7, 6, 6, 6, 7, 7, 8, 9, 6, 7, 6, + 6, 6, 7, 7, 0, 0, 1, 5, 7, 8, 9, 1, 0, 5, 4), Array(2, 2, 3, 4, 3, 3, 2, 3, 6, 3, 4, 4, 3, 5, 7, 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, + 5, 5, 5, 5, 6, 7, 8, 1, 2, 4, 5, 5, 6, 2, 0, 0, 5, 3, 6, 7, 8, 3, 4, 0, 1), Array(1, 1, 2, 3, 2, 3, 1, 2, 5, 2, 3, 3, 2, 4, 7, + 7, 4, 8, 8, 4, 4, 4, 5, 6, 6, 5, 5, 5, 6, 6, 7, 8, 2, 3, 5, 5, 5, 6, 3, 0, 0, 4, 4, 6, 7, 8, 2, 3, 1)); + } +} + +rule("SUBROUTINE: BOT - RESET PATH FINDING") +{ + event + { + Subroutine; + BotResetPathFinding; + } + + actions + { + Event Player.botTargetPlayer = -1; + Event Player.botTargetPosition = -1; + Event Player.botPreviousNodeId = -1; + Event Player.botClosestNodeIdToTarget = -1; + Event Player.botNextNodeId = -1; + Event Player.botNextNodePosition = -1; + Event Player.botIsPathFinding = False; + Event Player.botCancelPathFinding = False; + Stop Throttle In Direction(Event Player); + } +} + +rule("SUBROUTINE: BOT - START PATH FINDING") +{ + event + { + Subroutine; + BotStartPathFinding; + } + + actions + { + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Event Player.botIsPathFinding = True; + } +} + +rule("SUBROUTINE: BOT - GET NEXT NODE ID AND POSITION") +{ + event + { + Subroutine; + BotGetNextNodeIdAndPosition; + } + + actions + { + "BOT JUST START FOLLOW PATH OR LOST NEXT NODE" + If(Event Player.botPreviousNodeId == -1); + Event Player.botClosestNodeIdToBot = Index Of Array Value(Global.nodePositions, Sorted Array(Filtered Array(Global.nodePositions, + Is In Line of Sight(Position Of(Event Player) + Vector(0, 2, 0), Current Array Element, Barriers Do Not Block LOS) == True), + Distance Between(Position Of(Event Player), Current Array Element))[0]); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + "NEXT NODE IS TARGET (DISTANCE TO TARGET NODE = 1)" + If(Global.distanceMatrix[Event Player.botClosestNodeIdToBot][Event Player.botClosestNodeIdToTarget] == 1); + Event Player.botNextNodeId = Event Player.botClosestNodeIdToTarget; + "CHECK CONNECTIONS OF REACHED NODE" + Else; + Event Player.botShortestDistanceToTarget = 999; + Event Player.botCurrentDistanceToTarget = Event Player.botShortestDistanceToTarget; + Event Player.botTempArray = Global.nodeConnections[Event Player.botClosestNodeIdToBot]; + For Player Variable(Event Player, botLoopIterator1, 0, Count Of(Event Player.botTempArray), 1); + Event Player.botCurrentDistanceToTarget = Global.distanceMatrix[Event Player.botTempArray[Event Player.botLoopIterator1]][Event Player.botClosestNodeIdToTarget]; + If(Event Player.botCurrentDistanceToTarget < Event Player.botShortestDistanceToTarget); + Event Player.botShortestDistanceToTarget = Event Player.botCurrentDistanceToTarget; + Event Player.botNextNodeId = Event Player.botTempArray[Event Player.botLoopIterator1]; + End; + End; + End; + "NEXT NODE IS HIGHER THAN BOT AND BOT DIDN'T REACH CLOSEST NODE" + If(Y Component Of(Position Of(Event Player)) - Y Component Of(Global.nodePositions[Event Player.botNextNodeId]) + < -3 && Event Player.botPreviousNodeId != Event Player.botClosestNodeIdToBot); + Event Player.botPreviousNodeId = Event Player.botClosestNodeIdToBot; + Event Player.botNextNodeId = Event Player.botClosestNodeIdToBot; + "BOT CAN SEE TARGET POSITION AND NEXT NODE IS TARGET" + Else If( + Global.distanceMatrix[Event Player.botClosestNodeIdToBot][Event Player.botClosestNodeIdToTarget] == 1 && Is In Line of Sight( + Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.botTargetPosition + Vector(0, 2, 0), Barriers Do Not Block LOS)); + Event Player.botNextNodePosition = Event Player.botTargetPosition; + Abort; + "BOT CAN'T SEE NEXT NODE AND PREV NODE != REACHED NODE" + Else If(Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), + Global.nodePositions[Event Player.botNextNodeId] + Vector(0, 2, 0), Barriers Do Not Block LOS) + == False && Event Player.botPreviousNodeId != Event Player.botClosestNodeIdToBot); + Event Player.botPreviousNodeId = Event Player.botClosestNodeIdToBot; + Event Player.botNextNodeId = Event Player.botClosestNodeIdToBot; + End; + Event Player.botNextNodePosition = Global.nodePositions[Event Player.botNextNodeId]; + } +} + +rule("SUBROUTINE: BOT - GET CLOSEST NODE ID AND POSITION TO TARGET") +{ + event + { + Subroutine; + BotGetClosestNodeIdToTarget; + } + + actions + { + Event Player.botTargetPosition = Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) + : Event Player.botTargetPosition; + Event Player.botClosestNodeIdToTarget = Index Of Array Value(Global.nodePositions, Sorted Array(Filtered Array( + Global.nodePositions, Is In Line of Sight(Event Player.botTargetPosition + Vector(0, 2, 0), Current Array Element, + Barriers Do Not Block LOS) == True), Distance Between(Event Player.botTargetPosition, Current Array Element))[0]); + } +} + +rule("BOT: PATH FINDING - START") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + (Event Player.botTargetPosition != -1 || Event Player.botTargetPlayer != -1) == True; + } + + actions + { + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - CANCEL") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.botIsPathFinding == True; + Event Player.botCancelPathFinding == True; + } + + actions + { + Start Rule(BotResetPathFinding, Restart Rule); + } +} + +rule("BOT: PATH FINDING - LOST THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.botIsPathFinding == True; + (Is In Line of Sight(Position Of(Event Player) + Vector(0, 1.600, 0), Event Player.botNextNodePosition + Vector(0, 2.500, 0), + Barriers Do Not Block LOS) == False && Speed Of In Direction(Event Player, Throttle Of(Event Player)) < 2) == True; + } + + actions + { + Wait(0.500, Abort When False); + "RESET PREV NODE ID TO INFORM BOT THAT IT LOST NEXT NODE" + Event Player.botPreviousNodeId = -1; + "TRY FIND NEW NEXT NODE" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodeId), 360, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +rule("BOT: PATH FINDING - REACHED THE NODE") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Event Player.botIsPathFinding == True; + Event Player.botClosestNodeIdToTarget >= 0; + (Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of(Position Of(Event Player))), Vector( + X Component Of(Event Player.botNextNodePosition), 0, Z Component Of(Event Player.botNextNodePosition))) < 0.850) == True; + } + + actions + { + Event Player.botPreviousNodeId = Event Player.botNextNodeId; + Event Player.botClosestNodeIdToBot = Event Player.botNextNodeId; + "BOT'S TARGET IS PLAYER" + If(Event Player.botTargetPlayer != -1); + Call Subroutine(BotGetClosestNodeIdToTarget); + End; + Event Player.botCurrentDistanceToTarget = Distance Between(Vector(X Component Of(Position Of(Event Player)), 0, Z Component Of( + Position Of(Event Player))), Vector(X Component Of(Event Player.botTargetPosition), 0, Z Component Of( + Event Player.botTargetPosition))); + "BOT REACHED THE TARGET NODE OR TARGET POSITION" + If(Event Player.botNextNodeId == Event Player.botClosestNodeIdToTarget || Event Player.botCurrentDistanceToTarget <= 0.850); + "BOT DIDN'T REACH TARGET POSITION" + If(Event Player.botCurrentDistanceToTarget > 0.850); + Event Player.botNextNodePosition = Event Player.botTargetPosition; + Skip(6); + "BOT REACHED TARGET" + Else; + Call Subroutine(BotResetPathFinding); + Abort; + End; + End; + "CONTINUE FOLLOW PATH" + Call Subroutine(BotGetNextNodeIdAndPosition); + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + } +} + +disabled rule("=== PATH BUILDER MODE IMPORT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: GAME MODE INIT - WORKSHOP SETTINGS") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.isDebug = False; + Global.isDebugAINavigation = False; + Global.gateMaxHealth = Workshop Setting Integer(Custom String("Defend The Castle Extended"), Custom String("GATE MAX HEALTH"), 500, + 100, 1000, 0); + Global.moneyMultiplier = Workshop Setting Real(Custom String("Defend The Castle Extended"), Custom String("Money Multiplicator"), + 1, 0.500, 2, 0); + Global.selfNanoWorkshopSetting = Workshop Setting Toggle(Custom String("Ana Self Nano"), Custom String( + "Ana can nano herself even if there are other players (only if no player targeted)"), False, 0); + } +} + +rule("GLOBAL: GAME MODE INIT - COMMON PROPERTIES") +{ + event + { + Ongoing - Global; + } + + actions + { + Create In-World Text(All Players(Team 1), Custom String( + "Defend The Castle Extended c135\r\nby ShuriZma#2349\r\nOriginal mode by HUKUTA94#2589\r\nDiscord: dc.shuri.gg\r\n{0}", + Custom String( + "Special Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents &\nJosbird for teaching me about Menus{0}", + Custom String(" \nPS: SHINGEN PLS COME BACK"))), Vector(165, 12, -46.500), 1.200, Clip Against Surfaces, Visible To, Color( + White), Default Visibility); + Global.gateRepairPosition = Vector(153, 8, -46.500); + Global.gatePosition = Vector(148.800, 6, -46.400); + Global.ballSpawnPositions = Array(Vector(104, 7, -46), Vector(106, 2, -31)); + Global.sniperPositions = Array(Vector(154, 18, -22.600), Vector(86, 12, -46.600), Vector(80.880, 11.300, -71.600), Vector(98, 9, + -19)); + Global.zenSpawnPositions = Array(Vector(79.500, 5, -100), Vector(90, 4, -88), Vector(65, 11, -70), Vector(85, 4, -68), Vector(96, + 2, -73), Vector(84, 7, -47), Vector(95, 9, -34), Vector(108, 1.700, -28), Vector(113, 7, -37), Vector(123, 5, -19), Vector(144, + 5, -19), Vector(123, 6, -39), Vector(123, 6, -61), Vector(129, 6, -30.500), Vector(135, 6, -63)); + Global.playerSpawnPositions = Array(Vector(160, 11, -53), Vector(158, 11, -53), Vector(160, 11, -39), Vector(158, 11, -39)); + Global.bigBossSpawnPositions = Array(Vector(78, 4, -84), Vector(95, 4, -82)); + Global.bastionTargetPositions = Array(Vector(131, 12, -62), Vector(115, 7, -46), Objective Position(2), Vector(136, 10, -27)); + Global.spawnPositionMaxId = 2; + Global.botOrisaTargetPosition = Vector(104, 7, -46); + Global.botEchoRespawnPosition = Vector(130, 23, -44); + Global.botEchoTeleportPositions = Array(Vector(88, 23, -79), Vector(108, 18, -27)); + Global.defaultHeroBotsPool = Array(Hero(Zenyatta), Hero(Widowmaker), Null, Hero(Bastion), Hero(Echo), Hero(Bastion)); + Global.zenRespawnTime = 10; + Global.gameLogicCountOfUniqueHeroes = 5; + Global.lastBoss = Array(Null, Null, Null, Null); + Create Effect(All Players(Team 1), Ring, Color(Sky Blue), Vector(186, 11, -46.500), 9, Visible To Position and Radius); + Create Effect(All Players(Team 1), Ring, Color(Yellow), Vector(159, 11, -46.500), 2, Visible To Position and Radius); + } +} + +disabled rule("=== TEAM UPGRADES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: TEAM UPGRADES - INIT") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.upgradeMaxAmmoMaxValue[0] = 150; + Global.upgradeMaxAmmoMaxValue[1] = 300; + Global.upgradeMaxAmmoMaxValue[2] = 500; + Global.upgradeCriticalDamageMaxValue[0] = 10; + Global.upgradeCriticalDamageMaxValue[1] = 5; + Global.upgradeCriticalDamageMaxValue[2] = 10; + Global.upgradePlayerMaxHealthMaxValue[0] = 4000; + Global.upgradePlayerMaxHealthMaxValue[1] = 9000; + Global.upgradePlayerMaxHealthMaxValue[2] = 15000; + Global.upgradeGateMaxHealthMaxValue[0] = Round To Integer(Global.gateMaxHealth + Global.gateMaxHealth * 0.750, Up); + Global.upgradeGateMaxHealthMaxValue[1] = Global.upgradeGateMaxHealthMaxValue[0] + Global.upgradeGateMaxHealthMaxValue[0]; + Global.upgradeGateMaxHealthMaxValue[2] = Global.upgradeGateMaxHealthMaxValue[1] + Global.upgradeGateMaxHealthMaxValue[1]; + Abort If(Global.isDebug == False); + Global.upgradeMaxAmmoMaxValue[0] = 1; + Global.upgradeCriticalDamageMaxValue[0] = 1; + Global.upgradePlayerMaxHealthMaxValue[0] = 1; + Global.upgradeGateMaxHealthMaxValue[0] = 1; + Global.upgradeMaxAmmoMaxValue[1] = 1; + Global.upgradeCriticalDamageMaxValue[1] = 1; + Global.upgradePlayerMaxHealthMaxValue[1] = 1; + Global.upgradeGateMaxHealthMaxValue[1] = 1; + Global.upgradeMaxAmmoMaxValue[2] = 1; + Global.upgradeCriticalDamageMaxValue[2] = 1; + Global.upgradePlayerMaxHealthMaxValue[2] = 1; + Global.upgradeGateMaxHealthMaxValue[2] = 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[0]) == True; + } + + actions + { + Play Effect(All Players(Team 1), Good Explosion, Color(Green), Global.gatePosition, 5); + Play Effect(All Players(Team 1), Buff Impact Sound, Color(Green), Global.gatePosition, 100); + Global.gateMaxHealth = Global.upgradeGateMaxHealthMaxValue[0]; + Global.gateHealth = Global.gateMaxHealth; + Destroy HUD Text(Global.upgradeGateMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("GATE'S MAX HEALTH: {0} HP", Global.upgradeGateMaxHealthMaxValue[0]), Right, 1, Color( + Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeGateMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X GATE REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.upgradeGateMaxHealthValue, Global.upgradeGateMaxHealthMaxValue[1]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.upgradeGateMaxHealthHudId[1] = Last Text ID; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1]) == True; + } + + actions + { + Play Effect(All Players(Team 1), Good Explosion, Color(Green), Global.gatePosition, 5); + Play Effect(All Players(Team 1), Buff Impact Sound, Color(Green), Global.gatePosition, 100); + Destroy HUD Text(Global.upgradeGateMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X GATE REPAIR"), Right, 2, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.upgradeGateMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("2X AUTO-REPAIR"), + Custom String("REPAIR GATE {0}/{1} HP", Global.upgradeGateMaxHealthValue, Global.upgradeGateMaxHealthMaxValue[2]), Left, 12, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.upgradeGateMaxHealthHudId[2] = Last Text ID; + Global.gateHealth = Global.gateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - GATE'S MAX HEALTH 3 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2]) == True; + } + + actions + { + Play Effect(All Players(Team 1), Good Explosion, Color(Green), Global.gatePosition, 5); + Play Effect(All Players(Team 1), Buff Impact Sound, Color(Green), Global.gatePosition, 100); + Destroy HUD Text(Global.upgradeGateMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String("{0}", + Icon String(Checkmark)), Custom String("2X AUTO-REPAIR"), Right, 3, Color(Green), Color(Green), Color(Green), Visible To, + Default Visibility); + Global.upgradeGateMaxHealthHudId[2] = Last Text ID; + Global.gateHealth = Global.gateMaxHealth; + Start Rule(GateProgressBarColor, Restart Rule); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - PLAYER'S MAX HEALTH - DEALT HEALING") +{ + event + { + Player Received Healing; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Global.upgradePlayerMaxHealthValue < Global.upgradePlayerMaxHealthMaxValue[2]; + } + + actions + { + Global.upgradePlayerMaxHealthValue += Event Healing; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[0]) == True; + } + + actions + { + Destroy HUD Text(Global.upgradePlayerMaxHealthHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +50%"), Right, 4, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradePlayerMaxHealthHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("Up You Go: You respawn twice as fast"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.upgradePlayerMaxHealthValue, Down), + Global.upgradePlayerMaxHealthMaxValue[1]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.upgradePlayerMaxHealthHudId[1] = Last Text ID; + For Global Variable(loopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 1); + Play Effect(All Players(Team 1), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 100); + End; + Global.maxHealthDone = 50; + All Players(Team 1).playerHealth = 100 + Global.maxHealthDone + All Players(Team 1).abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).playerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK UP YOU GO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[1]) == True; + } + + actions + { + Destroy HUD Text(Global.upgradePlayerMaxHealthHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String("Up You Go"), + Right, 5, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradePlayerMaxHealthHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +100%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.upgradePlayerMaxHealthValue, Down), + Global.upgradePlayerMaxHealthMaxValue[2]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.upgradePlayerMaxHealthHudId[2] = Last Text ID; + Set Respawn Max Time(All Players(Team 1), 5); + Heal(All Players(Team 1), Null, 9999); + For Global Variable(loopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 1); + Play Effect(All Players(Team 1), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 100); + End; + Global.perk[2] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).abilityHUD[17] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PLAYER'S MAX HEALTH 2 - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[2]) == True; + } + + actions + { + Destroy HUD Text(Global.upgradePlayerMaxHealthHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("{0}", Icon String(Checkmark)), Custom String( + "PLAYER'S MAX HEALTH +100%"), Right, 6, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradePlayerMaxHealthHudId[2] = Last Text ID; + For Global Variable(loopIterator1, 0, Count Of(All Players(Team 1)), 1); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 1); + Play Effect(All Players(Team 1), Buff Impact Sound, Color(Yellow), Position Of(All Players(Team 1)[Global.loopIterator1]), 100); + End; + Global.maxHealthDone = 150; + All Players(Team 1).playerHealth = 100 + Global.maxHealthDone + All Players(Team 1).abilities[14] * 5; + Set Max Health(All Players(Team 1), All Players(Team 1).playerHealth); + Heal(All Players(Team 1), Null, 9999); + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - CRITICAL DAMAGE - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Was Critical Hit == True; + Hero Of(Victim) == Hero(Widowmaker); + Global.upgradeCriticalDamageValue < Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.upgradeCriticalDamageValue += 1; + } +} + +rule("GLOBAL: UPGRADE - CRITICAL DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.upgradeCriticalDamageValue >= Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Destroy HUD Text(Global.upgradeCriticalDamageHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "CRITICAL DAMAGE 150%"), Right, 7, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeCriticalDamageHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String( + "Sharpshooter: Deal 40% more damage to enemies that are further than 15 meters away"), Custom String("KILL ECHO {0}/{1}", + Global.upgradePerkSharpshooterValue, Global.upgradeCriticalDamageMaxValue[1]), Left, 14, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.upgradeCriticalDamageHudId[1] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("PLAYER: UPGRADE - PERK SHARPSHOOTER - DEALT KILL") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Hero Of(Victim) == Hero(Echo); + Global.upgradePerkSharpshooterValue < Global.upgradeCriticalDamageMaxValue[1]; + Global.upgradeCriticalDamageValue >= Global.upgradeCriticalDamageMaxValue[0]; + } + + actions + { + Global.upgradePerkSharpshooterValue += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK SHARPSHOOTER - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.upgradePerkSharpshooterValue >= Global.upgradeCriticalDamageMaxValue[1]; + } + + actions + { + Destroy HUD Text(Global.upgradeCriticalDamageHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Sharpshooter"), Right, 8, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeCriticalDamageHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("-10% BOSS HEALTH"), Custom String("KILL Bosses {0}/{1}", + Global.upgradeBossHealthValue, Global.upgradeCriticalDamageMaxValue[2]), Left, 14, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.upgradeCriticalDamageHudId[2] = Last Text ID; + Global.perk[0] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).abilityHUD[18] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - -10% BOSS HEALTH - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2]; + } + + actions + { + Destroy HUD Text(Global.upgradeCriticalDamageHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("{0}", Icon String(Checkmark)), Custom String( + "-10% BOSS HEALTH"), Right, 9, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeCriticalDamageHudId[2] = Last Text ID; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - MAX AMMO - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[0]) == True; + } + + actions + { + Destroy HUD Text(Global.upgradeMaxAmmoHudId[0]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "MAX AMMO 200%"), Right, 10, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("+50% DAMAGE"), Custom String("KILL {2}: {0}/{1}", + Global.upgradeMaxAmmoValue, Global.upgradeMaxAmmoMaxValue[1], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.upgradeMaxAmmoHudId[1] = Last Text ID; + For Global Variable(loopIterator1, 0, Count Of(All Players(Team 1)), 1); + Set Max Ammo(All Players(Team 1)[Global.loopIterator1], 0, Max Ammo(All Players(Team 1)[Global.loopIterator1], 0) * 2); + Set Max Ammo(All Players(Team 1)[Global.loopIterator1], 1, Max Ammo(All Players(Team 1)[Global.loopIterator1], 1) * 2); + Set Ammo(All Players(Team 1)[Global.loopIterator1], 0, Max Ammo(All Players(Team 1)[Global.loopIterator1], 0)); + Set Ammo(All Players(Team 1)[Global.loopIterator1], 1, Max Ammo(All Players(Team 1)[Global.loopIterator1], 1)); + End; + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - +50% DAMAGE - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[1]) == True; + } + + actions + { + Destroy HUD Text(Global.upgradeMaxAmmoHudId[1]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "+50% DAMAGE"), Right, 12, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeMaxAmmoHudId[1] = Last Text ID; + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("Bulletstorm: Your weapon can hold unlimited ammo"), + Custom String("KILL {2}: {0}/{1}", Global.upgradeMaxAmmoValue, Global.upgradeMaxAmmoMaxValue[2], Hero(Zenyatta)), Left, 15, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.upgradeMaxAmmoHudId[2] = Last Text ID; + Global.damageDealt = 50; + All Players(Team 1).damageDealt = 100 + Global.damageDealt + All Players(Team 1).abilities[13] * 5; + Set Damage Dealt(All Players(Team 1), All Players(Team 1).damageDealt); + Global.challengeCount += 1; + } +} + +rule("GLOBAL: UPGRADE - PERK BULLETSTORM - DONE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + (Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[2]) == True; + } + + actions + { + Destroy HUD Text(Global.upgradeMaxAmmoHudId[2]); + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("{0}", Icon String(Checkmark)), Custom String( + "Bulletstorm"), Right, 11, Color(Green), Color(Green), Color(Green), Visible To, Default Visibility); + Global.upgradeMaxAmmoHudId[2] = Last Text ID; + Global.perk[1] = 1; + Create HUD Text(All Players(Team 1), Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + All Players(Team 1).abilityHUD[19] = Last Text ID; + Global.challengeCount += 1; + } +} + +disabled rule("=== GAME PHASES ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: ASSEMBLING PHASE - MAKE CHALLENGE HUDS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Assembling Heroes == True; + } + + actions + { + If(Global.isDebug); + Set Match Time(1); + Else; + Disable Inspector Recording; + Set Match Time(20); + End; + Create In-World Text(All Players(Team 1), Custom String(" {0}\r\nREPAIR\r\n {1}", Hero Icon String(Hero(Torbjörn)), + Ability Icon String(Hero(Bastion), Button(Secondary Fire))), Global.gatePosition + Vector(0, 1.400, 0), 1.200, Do Not Clip, + Visible To, Color(White), Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("TEAM CHALLENGES {0}/12", Global.challengeCount), Left, 11, Color( + White), Color(Blue), Color(White), Visible To and String, Default Visibility); + "UPGRADE - GATE'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Ability Icon String(Hero(Reinhardt), Button(Secondary Fire)), Custom String( + "GATE'S MAX HEALTH: {0} HP", Global.upgradeGateMaxHealthMaxValue[0]), Custom String("REPAIR GATE {0}/{1} HP", + Global.upgradeGateMaxHealthValue, Global.upgradeGateMaxHealthMaxValue[0]), Left, 12, Color(Orange), Color(White), Color(White), + Visible To and String, Default Visibility); + Global.upgradeGateMaxHealthHudId[0] = Last Text ID; + "UPGRADE - PLAYER'S MAX HEALTH" + Create HUD Text(All Players(Team 1), Icon String(Plus), Custom String("PLAYER'S MAX HEALTH +50%"), Custom String( + "HEAL PLAYERS {0}/{1} HP", Round To Integer(Global.upgradePlayerMaxHealthValue, Down), + Global.upgradePlayerMaxHealthMaxValue[0]), Left, 13, Color(Orange), Color(White), Color(White), Visible To and String, + Default Visibility); + Global.upgradePlayerMaxHealthHudId[0] = Last Text ID; + "UPGRADE - CRITICAL DAMAGE" + Create HUD Text(All Players(Team 1), Icon String(Skull), Custom String("CRITICAL DAMAGE 150%"), Custom String( + "KILL WIDOW WITH HEADSHOT: {0}/{1}", Global.upgradeCriticalDamageValue, Global.upgradeCriticalDamageMaxValue[0]), Left, 14, + Color(Orange), Color(White), Color(White), Visible To and String, Default Visibility); + Global.upgradeCriticalDamageHudId[0] = Last Text ID; + "UPGRADE - MAX AMMO" + Create HUD Text(All Players(Team 1), Icon String(Asterisk), Custom String("MAX AMMO 200%"), Custom String("KILL {2}: {0}/{1}", + Global.upgradeMaxAmmoValue, Global.upgradeMaxAmmoMaxValue[0], Hero(Zenyatta)), Left, 15, Color(Orange), Color(White), Color( + White), Visible To and String, Default Visibility); + Global.upgradeMaxAmmoHudId[0] = Last Text ID; + Create HUD Text(All Players(Team 1), Custom String("HOLD {0} - Reload to open the shop", Input Binding String(Button(Reload))), + Null, Null, Top, 1000, Color(Yellow), Color(White), Color(White), Visible To and String, Default Visibility); + } +} + +rule("GLOBAL: SETUP PHASE") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is In Setup == True; + } + + actions + { + If(Global.isDebug); + Set Match Time(1); + Else; + Pause Match Time; + Create HUD Text(All Players(Team 1), Custom String("PRESS {0} TO VOTE FOR START | {1}/{2}", Button(Interact), Count Of( + Filtered Array(All Players(Team 1), Current Array Element.vote[0] == 1)), Count Of(All Players(Team 1))), Null, Null, Top, 50, + Color(Red), Color(White), Color(White), Visible To and String, Default Visibility); + Global.globalHUDs[0] = Last Text ID; + Set Match Time(20); + While(Count Of(Filtered Array(All Players(Team 1), Current Array Element.vote[0] == 1)) <= Count Of(All Players(Team 1)) / 2); + Filtered Array(All Players(Team 1), Is Button Held(Current Array Element, Button(Interact))).vote[0] = 1; + Wait(0.100, Ignore Condition); + End; + Destroy HUD Text(Global.globalHUDs[0]); + Unpause Match Time; + End; + Set Objective Description(All Players(All Teams), Custom String("DEFEND GATE"), Visible To and String); + } +} + +rule("GLOBAL: GAME IN PROGRESS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + } + + actions + { + Set Match Time(3599); + Pause Match Time; + Disable Built-In Game Mode Scoring; + Disable Built-In Game Mode Announcer; + Disable Built-In Game Mode Completion; + Disable Game Mode HUD(All Players(All Teams)); + Disable Game Mode In-World UI(All Players(All Teams)); + Global.gateHealth = Global.gateMaxHealth; + Global.gateHealthChase = Global.gateHealth; + Global.gateProgressBarColorComponent = 255; + Global.gateProgressBarColorCurrent = Color(White); + Create Progress Bar HUD Text(All Players(Team 1), Global.gateHealthChase * 100 / Global.gateMaxHealth, Custom String( + "GATE {0}/{1}", Global.gateHealth, Global.gateMaxHealth), Top, 1, Global.gateProgressBarColorCurrent, Color(White), + Visible To Values and Color, Default Visibility); + Create HUD Text(All Players(Team 1), Null, Null, Custom String("SURVIVED TIME: {0}:{1}", Global.timeMinutes, + Global.timeSeconds < 10 ? Custom String("0{0}", Global.timeSeconds) : Global.timeSeconds), Top, 2, Color(White), Color(White), + Color(White), Visible To and String, Default Visibility); + Start Rule(GameLogicWave0, Do Nothing); + } +} + +disabled rule("=== GAME - MAIN LOGIC ===") +{ + event + { + Ongoing - Global; + } +} + +rule("GLOBAL: DEFEAT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.isDebug == False; + Global.gateHealth <= 0; + } + + actions + { + Declare Team Victory(Team 2); + } +} + +rule("GLOBAL: TIMER - MAIN GAME LOOP") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + } + + actions + { + Wait(1, Ignore Condition); + Global.timeSeconds += 1; + If(Global.timeSeconds == 60); + Global.timeSeconds = 0; + Global.timeMinutes += 1; + Global.time5Minutes = Round To Integer(Global.timeMinutes / 5, Down); + Global.time10Minutes = Round To Integer(Global.timeMinutes / 10, Down); + Global.spawnPositionMaxId += 1; + Else If(Global.timeSeconds == 30); + Global.spawnPositionMaxId += 1; + End; + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GAME LOGIC - ADD NEXT HERO IN GAME") +{ + event + { + Subroutine; + GameLogicAddNextHeroInGame; + } + + actions + { + "ALL HEROES WAS ADDED IN GAME" + Abort If(Global.defaultHeroBotsPoolCurrentId == Count Of(Global.defaultHeroBotsPool) - 1); + Global.defaultHeroBotsPoolCurrentId += 1; + "ВРЕМЕННЫЙ КОСТЫЛЬ ЧТОБЫ ЭХО ЗАМЕНИЛА ХАМСТЕРА" + If(Global.defaultHeroBotsPool[Global.defaultHeroBotsPoolCurrentId] == Hero(Echo)); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Wrecking Ball)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Wrecking Ball))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.100, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Abort; + End; + "ABORT IF NEXT HERO IN ARRAY ORDER IS NULL" + Abort If(Global.defaultHeroBotsPool[Global.defaultHeroBotsPoolCurrentId] == Null); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.100, Ignore Condition); + Create Dummy Bot(Global.defaultHeroBotsPool[Global.defaultHeroBotsPoolCurrentId], Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("SUBROUTINE: GAME LOGIC - SET BOT PROPERTIES") +{ + event + { + Subroutine; + GameLogicSetBotProperties; + } + + actions + { + Abort If(Event Player.botIsOrisaChild == True); + If(Global.timeMinutes >= 10); + If(Filtered Array(Global.lastBoss, Current Array Element == Hero Of(Event Player)) == False); + If(Global.activeBoss == False); + Global.activeBoss = Event Player; + Event Player.isBoss = 1; + End; + End; + End; + End; + "PROPERTIES BY DEFAULT" + Set Gravity(Event Player, 100); + Set Damage Dealt(Event Player, 100); + Set Respawn Max Time(Event Player, 10); + Start Scaling Player(Event Player, 1, False); + "INDIVIDUAL HERO'S PROPERTIES" + If(Hero Of(Event Player) == Hero(Zenyatta)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 30); + Set Max Health(Event Player, 10 * (100 + 10 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 1.500, False); + Else; + If(20 + 3 * Number Of Players(Team 1) + 3 * Global.timeMinutes > 75); + Set Move Speed(Event Player, 75); + Else; + Set Move Speed(Event Player, 20 + 3 * Count Of(All Players(Team 1)) + 3 * Global.timeMinutes); + End; + Set Max Health(Event Player, 100 + 10 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 20); + Set Max Health(Event Player, 5 * (70 + 20 * Count Of(All Players(Team 1)) + + 10 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + If(30 + Global.timeMinutes + 2.500 * Global.time5Minutes > 40); + Set Move Speed(Event Player, 40); + Else; + Set Move Speed(Event Player, 30 + Global.timeMinutes + 2.500 * Global.time5Minutes); + End; + Set Ultimate Charge(Event Player, 0); + Set Max Health(Event Player, 70 + 20 * Count Of(All Players(Team 1)) + + 10 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + If(Event Player.isBoss == 1); + Set Damage Dealt(Event Player, 2 * (85 + 15 * Count Of(All Players(Team 1)) + + 25 * Global.time5Minutes + 50 * Global.time10Minutes)); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 5 * (100 + 25 * Count Of(All Players(Team 1)) + + 5 * Global.timeMinutes + 15 * Global.time5Minutes + 40 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Event Player.botCounter = 0; + Set Damage Dealt(Event Player, 85 + 15 * Count Of(All Players(Team 1)) + 25 * Global.time5Minutes + 50 * Global.time10Minutes); + Set Move Speed(Event Player, 100); + Set Max Health(Event Player, 100 + 25 * Count Of(All Players(Team 1)) + + 5 * Global.timeMinutes + 15 * Global.time5Minutes + 40 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Bastion)); + If(Event Player.isBoss == 1); + Set Move Speed(Event Player, 50); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Minutes + 10 * Global.time10Minutes); + Start Scaling Player(Event Player, 3, False); + Set Max Health(Event Player, 5 * (155 + 150 * Count Of(All Players(Team 1)) + + 20 * Global.timeMinutes + 40 * Global.time5Minutes + 65 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Else; + Set Move Speed(Event Player, 80); + Set Damage Dealt(Event Player, 85 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Minutes + 10 * Global.time10Minutes); + Start Scaling Player(Event Player, 2, False); + Set Max Health(Event Player, 155 + 150 * Count Of(All Players(Team 1)) + + 20 * Global.timeMinutes + 40 * Global.time5Minutes + 65 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Orisa)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 5 * (220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.time5Minutes + 100 * Global.time10Minutes) + * (Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Set Move Speed(Event Player, 30 + 5 * Global.time5Minutes); + Else; + Start Scaling Player(Event Player, 1.800, False); + Set Max Health(Event Player, 220 + Count Of(All Players(Team 1)) * 80 + 50 * Global.time5Minutes + 100 * Global.time10Minutes); + Set Move Speed(Event Player, 90 + 5 * Global.time5Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Echo)); + If(Event Player.isBoss == 1); + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 70 + 5 * Global.time5Minutes); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 5 * (90 + 25 * Count Of(All Players(Team 1)) + + 15 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Start Scaling Player(Event Player, 2, False); + Else; + Set Gravity(Event Player, 40); + Set Move Speed(Event Player, 130 + 5 * Global.time5Minutes); + Set Respawn Max Time(Event Player, 18); + Set Max Health(Event Player, 90 + 25 * Count Of(All Players(Team 1)) + + 15 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes); + End; + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + If(Event Player.isBoss == 1); + Start Scaling Player(Event Player, 1.500, False); + Set Move Speed(Event Player, 70); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Minutes + 10 * Global.time10Minutes); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 5 * (55 + 25 * Count Of(All Players(Team 1)) + + 15 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes) * ( + Global.upgradeBossHealthValue >= Global.upgradeCriticalDamageMaxValue[2] ? 0.900 : 1)); + Else; + Set Move Speed(Event Player, 110); + Set Damage Dealt(Event Player, 100 + 5 * Count Of(All Players(Team 1)) + 5 * Global.time5Minutes + 10 * Global.time10Minutes); + Set Respawn Max Time(Event Player, 15); + Set Max Health(Event Player, 55 + 25 * Count Of(All Players(Team 1)) + + 15 * Global.timeMinutes + 25 * Global.time5Minutes + 50 * Global.time10Minutes); + End; + End; + Wait(0.250, Ignore Condition); + "FILL HEALTH" + Heal(Event Player, Null, 100000); + } +} + +disabled rule("=== GATE ===") +{ + event + { + Ongoing - Global; + } +} + +rule("Subroutine: GATE REPAIR") +{ + event + { + Subroutine; + GateRepair; + } + + actions + { + "UPGRADE - GATE'S MAX HEALTH" + If(Global.upgradeGateMaxHealthValue < Global.upgradeGateMaxHealthMaxValue[2]); + If(Global.gateMaxHealth - Global.gateHealth > 10 * ( + Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1] ? 2 : 1) * (Event Player.isNanoed == 1 ? 2 : 1)); + Global.upgradeGateMaxHealthValue += 10 * (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1] ? 2 : 1) * ( + Event Player.isNanoed == 1 ? 2 : 1); + Else; + Global.upgradeGateMaxHealthValue += Global.gateMaxHealth - Global.gateHealth; + End; + End; + "HEAL GATE" + If(Global.gateMaxHealth - Global.gateHealth > 10 * ( + Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1] ? 2 : 1) * (Event Player.isNanoed == 1 ? 2 : 1)); + Global.gateHealth += 10 * (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[1] ? 2 : 1) * ( + Event Player.isNanoed == 1 ? 2 : 1); + Else; + Global.gateHealth += Global.gateMaxHealth - Global.gateHealth; + End; + "CHARGE ULTIMATE" + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + } +} + +rule("GATE REPAIR") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + ((Hero Of(Event Player) == Hero(Torbjörn) && Weapon(Event Player) == 2) || (Hero Of(Event Player) == Hero(Reinhardt) || Hero Of( + Event Player) == Hero(Brigitte) || Hero Being Duplicated(Event Player) == Hero(Reinhardt))) == True; + Is Firing Primary(Event Player) == True; + Global.gateHealth < Global.gateMaxHealth; + Is In View Angle(Event Player, Global.gateRepairPosition, 80) == True; + Distance Between(Position Of(Event Player), Global.gatePosition) < (Hero Of(Event Player) == Hero(Brigitte) ? 5 : 3.500); + } + + actions + { + If(Hero Of(Event Player) == Hero(Reinhardt)); + Wait(0.100, Ignore Condition); + End; + Call Subroutine(GateRepair); + If(Hero Of(Event Player) == Hero(Torbjörn)); + Wait(Is Using Ability 2(Event Player) == True ? 0.350 : 0.700, Ignore Condition); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Wait(0.850, Ignore Condition); + Else; + Wait(0.500, Ignore Condition); + End; + Loop If Condition Is True; + } +} + +rule("SUBROUTINE: GATE PROGRESS BAR COLOR") +{ + event + { + Subroutine; + GateProgressBarColor; + } + + actions + { + Stop Chasing Global Variable(gateHealthChase); + Chase Global Variable Over Time(gateHealthChase, Global.gateHealth, 0.100, Destination and Duration); + "GATE WAS DAMAGED" + If(Global.gateHealth < Global.gateHealthEvent); + For Global Variable(loopIterator1, 0, 3, 1); + Global.gateProgressBarColorCurrent = Color(Red); + Wait(0.100, Ignore Condition); + Global.gateProgressBarColorCurrent = Color(White); + Wait(0.100, Ignore Condition); + End; + "GATE WAS REPAIRED" + Else; + Global.gateProgressBarColorCurrent = Color(Green); + Wait(0.100, Ignore Condition); + Global.gateProgressBarColorCurrent = Color(Yellow); + Wait(0.100, Ignore Condition); + End; + Global.gateHealthEvent = Global.gateHealth; + Global.gateProgressBarColorComponent = Global.gateHealth * 255 / Global.gateMaxHealth; + Global.gateProgressBarColorCurrent = Custom Color(255, Global.gateProgressBarColorComponent, Global.gateProgressBarColorComponent, + 255); + } +} + +disabled rule("=== COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("ALL: INIT") +{ + event + { + Player Joined Match; + All; + All; + } + + actions + { + "ALL (COMMON) INIT" + Event Player.isDead = True; + Disable Kill Feed(Event Player); + Disable Game Mode In-World UI(Event Player); + Disable Death Spectate Target HUD(Event Player); + "BOT INIT" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotInit); + "PLAYER INIT" + Else; + Call Subroutine(PlayerInit); + End; + } +} + +rule("SUBROUTINE: BOT - INIT") +{ + event + { + Subroutine; + BotInit; + } + + actions + { + "INIT VARS" + Event Player.hasBadStatus = False; + Event Player.isRespawning = False; + Event Player.botDoesUniqueBehaviour = False; + Event Player.botEventPosition = Vector(9999, 999, 9999); + "DISABLE ALL FOR BOT" + Disable Hero HUD(Event Player); + Disable Messages(Event Player); + Disable Text Chat(Event Player); + Disable Scoreboard(Event Player); + Disable Game Mode HUD(Event Player); + Disable Death Spectate All Players(Event Player); + Disable Voice Chat(Event Player, True, True, True); + "INIT AI NAVIGATION VARS" + Call Subroutine(BotResetPathFinding); + } +} + +rule("SUBROUTINE: PLAYER - INIT") +{ + event + { + Subroutine; + PlayerInit; + } + + actions + { + "TEAM CHALLENGE - PLAYER'S MAX HEALTH" + If(Global.upgradePlayerMaxHealthValue >= Global.upgradePlayerMaxHealthMaxValue[0]); + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + End; + If(Is Game In Progress); + Disable Game Mode HUD(Event Player); + End; + } +} + +rule("ALL: RESPAWN") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + (Hero Of(Event Player) != Event Player.currentHero || Event Player.isDead == True) == True; + } + + actions + { + Event Player.isDead = False; + "BOT RESPAWN" + If(Is Dummy Bot(Event Player)); + Call Subroutine(BotRespawn); + If(Global.isDebugAINavigation); + Create Beam Effect(All Players(All Teams), Good Beam, Eye Position(Event Player), Event Player.botNextNodePosition, Color(Green), + Visible To Position and Radius); + End; + "PLAYER RESPAWN" + Else; + Call Subroutine(PlayerRespawn); + End; + "MUST BE AFTER ALL RESPAWN SUBROUTINES!" + Event Player.currentHero = Hero Of(Event Player); + } +} + +rule("SUBROUTINE: BOT - RESPAWN") +{ + event + { + Subroutine; + BotRespawn; + } + + actions + { + "RESET COMMON PROPERTIES" + Event Player.isRespawning = True; + Enable Nameplates(Event Player, All Players(Team 1)); + Call Subroutine(BotResetPathFinding); + Call Subroutine(GameLogicSetBotProperties); + "INDIVIDUAL HERO'S RESPAWN SCRIPTS" + If(Hero Of(Event Player) == Hero(Bastion)); + Call Subroutine(BotBastionRespawn); + Else If(Hero Of(Event Player) == Hero(Zenyatta)); + Call Subroutine(BotZenyattaRespawn); + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + Call Subroutine(BotWidowRespawn); + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Call Subroutine(BotBallRespawn); + Else If(Hero Of(Event Player) == Hero(Orisa)); + Call Subroutine(BotOrisaRespawn); + Else If(Hero Of(Event Player) == Hero(Echo)); + Call Subroutine(BotEchoRespawn); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Call Subroutine(BotReinRespawn); + End; + Event Player.isRespawning = False; + } +} + +rule("SUBROUTINE: PLAYER - RESPAWN") +{ + event + { + Subroutine; + PlayerRespawn; + } + + actions + { + "TEAM CHALLENGE - MAX AMMO" + If(Hero Of(Event Player) != Event Player.currentHero && Global.upgradeMaxAmmoValue >= Global.upgradeMaxAmmoMaxValue[0]); + Set Max Ammo(Event Player, 0, Ammo(Event Player, 0) * 2); + Set Max Ammo(Event Player, 1, Ammo(Event Player, 1) * 2); + Set Ammo(Event Player, 0, Max Ammo(Event Player, 0)); + Set Ammo(Event Player, 1, Max Ammo(Event Player, 1)); + End; + "PLAYER RESPAWN" + Set Status(Event Player, Null, Phased Out, 3); + Set Facing(Event Player, Vector(-1, 0, 0), To World); + If(Ability Cooldown(Players On Hero(Hero(Mercy), Team 1), Button(Ability 2)) >= 30 * (Players On Hero(Hero(Mercy), Team 1) + .abilities[6] ? Players On Hero(Hero(Mercy), Team 1).abilities[6] * 0.250 : 1) - 1); + Wait(0.250, Ignore Condition); + Teleport(Event Player, Event Player.deathPosition); + Else; + Teleport(Event Player, Global.playerSpawnPositions[Slot Of(Event Player) == Count Of(Global.playerSpawnPositions) ? Random Integer( + 0, Count Of(Global.playerSpawnPositions) - 1) : Slot Of(Event Player)]); + End; + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + } +} + +rule("PLAYER: DEATH") +{ + event + { + Player Died; + Team 1; + All; + } + + actions + { + If(Hero Of(Event Player) == Hero(Roadhog)); + Event Player.abilities[8] -= 1; + Wait(Global.perk[2] ? 5 : 10, Ignore Condition); + Event Player.abilities[8] += 1; + End; + Event Player.deathPosition = Position Of(Event Player); + Event Player.isDead = True; + } +} + +rule("BOT: DEATH") +{ + event + { + Player Died; + Team 2; + All; + } + + actions + { + If(Event Player.isBoss == 1); + If( + Global.upgradePerkSharpshooterValue >= Global.upgradeCriticalDamageMaxValue[1] && Global.upgradeBossHealthValue < Global.upgradeCriticalDamageMaxValue[2]); + Global.upgradeBossHealthValue += 1; + End; + Event Player.isBoss = 0; + Global.activeBoss = Null; + End; + Event Player.isDead = True; + Event Player.hasBadStatus = False; + Event Player.botDoesUniqueBehaviour = False; + Disable Nameplates(Event Player, All Players(Team 1)); + "BOT HAS 1 EFFECT IN VAR (NOT ARRAY)" + Skip If(!Entity Exists(Event Player.botEffects), 1); + Destroy Effect(Event Player.botEffects); + "BOT HAS MORE THEN 1 EFFECT IN VAR (ARRAY)" + Skip If(Count Of(Event Player.botEffects) == 0, 3); + For Player Variable(Event Player, botLoopIterator1, 0, Count Of(Event Player.botEffects), 1); + Destroy Effect(Event Player.botEffects[Event Player.botLoopIterator1]); + End; + } +} + +disabled rule("=== BOT COMMON MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BAD STATUS") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.hasBadStatus == False; + (Has Status(Event Player, Hacked) || Has Status(Event Player, Frozen) || Has Status(Event Player, Knocked Down) || Has Status( + Event Player, Asleep) || Has Status(Event Player, Stunned)) == True; + } + + actions + { + Event Player.hasBadStatus = True; + "PROCESS BAD STATUS" + If(Hero Of(Event Player) == Hero(Widowmaker)); + Start Rule(BotWidowBadStatus, Do Nothing); + End; + Wait Until(!Has Status(Event Player, Knocked Down) && !Has Status(Event Player, Asleep) && !Has Status(Event Player, Frozen) + && !Has Status(Event Player, Stunned), 15); + Event Player.hasBadStatus = False; + } +} + +rule("SUBROUTINE: BOT - LANDING FROM SKY") +{ + event + { + Subroutine; + BotLandingFromSky; + } + + actions + { + Stop Throttle In Direction(Event Player); + "SET RESPAWN POSITION" + Event Player.botEventPosition = Random Value In Array(Global.bigBossSpawnPositions); + "CREATE EFFECTS" + Create Effect(All Players(Team 1), Light Shaft, Color(Red), Event Player.botEventPosition, 3, Visible To); + Event Player.botEffects[0] = Last Created Entity; + "RESPAWN IN LIGHT SHAFT EFFECT" + Teleport(Event Player, Event Player.botEventPosition + Vector(0, 25, 0)); + Wait(0.100, Ignore Condition); + "SLOW LANDING" + Set Gravity(Event Player, 50); + While(Is In Air(Event Player) == True); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(Orange), Position Of(Event Player) + Vector(0, -2.700, 0), 2); + Wait(0.250, Ignore Condition); + End; + Set Gravity(Event Player, 100); + Destroy Effect(Event Player.botEffects[0]); + "LANDING EFFECTS" + Play Effect(All Players(Team 1), Wrecking Ball Piledriver Impact Effect, Custom Color(105, 87, 46, 255), Position Of(Event Player), + 8); + Play Effect(All Players(Team 1), Doomfist Meteor Strike Impact Sound, Color(White), Position Of(Event Player), 150); + } +} + +rule("SUBROUTINE: BOT - APPEAR FROM UNDERGROUND") +{ + event + { + Subroutine; + BotAppearFromUnderground; + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 1); + Wait(0.200, Ignore Condition); + Set Gravity(Event Player, 20); + Disable Movement Collision With Environment(Event Player, True); + Teleport(Event Player, Global.zenSpawnPositions[Random Integer(Min(Global.timeMinutes, Count Of(Global.zenSpawnPositions) - 10), + Min(Global.spawnPositionMaxId, Count Of(Global.zenSpawnPositions) - 4))] + Vector(0, -1.500, 0)); + Wait(0.100, Ignore Condition); + Play Effect(All Players(Team 1), Sigma Accretion Impact Effect, Custom Color(220, 175, 100, 255), Eye Position(Event Player), 3); + Play Effect(All Players(Team 1), Sigma Accretion Impact Sound, Color(Gray), Eye Position(Event Player), 50); + Apply Impulse(Event Player, Up, 3.500, To World, Cancel Contrary Motion); + Wait(0.400, Ignore Condition); + Clear Status(Event Player, Knocked Down); + Set Gravity(Event Player, 100); + Enable Movement Collision With Environment(Event Player); + } +} + +disabled rule("=== PLAYER MECHANICS ===") +{ + event + { + Ongoing - Global; + } +} + +rule("PLAYER: HEALTH REGEN") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + actions + { + Stop Heal Over Time(Event Player.healOverTimeId); + Event Player.eventHealth = Health(Event Player); + Wait(4, Ignore Condition); + "TOOK DAMAGE, RESET REGENERATION TIMER" + Loop If(Is Alive(Event Player) && Event Player.eventHealth > Health(Event Player)); + Start Heal Over Time(Event Player, Null, 3, Max Health(Event Player) / 3); + Event Player.healOverTimeId = Last Heal Over Time ID; + } +} + +disabled rule("=== ZENYATTA ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ZEN - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Zenyatta; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + } + + actions + { + Set Ammo(Event Player, 0, 0); + Communicate(Event Player, Hello); + Wait(1.500, Ignore Condition); + Abort If(Is Dead(Event Player) == True); + Kill(Event Player, Null); + } +} + +rule("BOT: ZEN - DEATH") +{ + event + { + Player Died; + Team 2; + Zenyatta; + } + + actions + { + "EFFECT" + Play Effect(All Players(Team 1), Junkrat Frag Launcher Explosion Effect, Color(Red), Eye Position(Event Player), 2.500); + Play Effect(All Players(Team 1), Ashe Dynamite Explosion Sound, Color(Red), Eye Position(Event Player), 70); + "DAMAGE AND APPLY IMPULSE TO PLAYERS" + Event Player.botPlayersInRadius = Players Within Radius(Position Of(Event Player), 2.500, All Teams, Surfaces And Enemy Barriers); + For Player Variable(Event Player, botLoopIterator1, 0, Count Of(Event Player.botPlayersInRadius), 1); + Apply Impulse(Event Player.botPlayersInRadius[Event Player.botLoopIterator1], Direction Towards(Position Of(Event Player), + Eye Position(Event Player.botPlayersInRadius[Event Player.botLoopIterator1])), 5, To World, Incorporate Contrary Motion); + If(Team Of(Event Player.botPlayersInRadius[Event Player.botLoopIterator1]) == Team 1); + Damage(Event Player.botPlayersInRadius[Event Player.botLoopIterator1], Event Player, 50); + End; + End; + "DAMAGE GATE" + If(Distance Between(Position Of(Event Player), Global.gatePosition) < 3 && Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.gateHealth -= 125; + Else; + Global.gateHealth -= 25 + 5 * Global.time5Minutes; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Respawn(Event Player); + Abort; + End; + "KILLED BY PLAYER" + Teleport(Event Player, Vector(0, -999, 0)); + Wait(2, Ignore Condition); + Respawn(Event Player); + Wait(2, Ignore Condition); + } +} + +rule("SUBROUTINE: ZEN - RESPAWN") +{ + event + { + Subroutine; + BotZenyattaRespawn; + } + + actions + { + Call Subroutine(BotAppearFromUnderground); + Event Player.botTargetPosition = Global.gatePosition; + Event Player.botIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WRECKING BALL ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BALL - REACHED THE GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Set Ammo(Event Player, 0, 0); + Wait(1, Ignore Condition); + Set Ultimate Charge(Event Player, 100); + Start Holding Button(Event Player, Button(Ultimate)); + Wait Until(Is Using Ultimate(Event Player), 0.600); + Abort If(Is Dead(Event Player)); + Kill(Event Player, Null); + Play Effect(All Players(Team 1), Junkrat RIP Tire Explosion Effect, Color(Orange), Eye Position(Event Player), 6); + Play Effect(All Players(Team 1), DVa Self Destruct Explosion Sound, Color(White), Eye Position(Event Player), 250); + If(Distance Between(Position Of(Event Player), Global.gatePosition) < 3.500 && Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Enemy Barriers Block LOS)); + If(Event Player.isBoss == 1); + Global.gateHealth -= 300; + Else; + Global.gateHealth -= 150 + 10 * Global.time5Minutes; + End; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Damage(Players Within Radius(Eye Position(Event Player), 7, Team 1, Surfaces And All Barriers), Event Player, 200); + } +} + +rule("BOT: BALL - ALTERNATIVE FORM") +{ + event + { + Ongoing - Each Player; + Team 2; + Wrecking Ball; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is In Alternate Form(Event Player) == False; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is In Alternate Form(Event Player), 10); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: BALL - DEATH") +{ + event + { + Player Died; + Team 2; + Wrecking Ball; + } + + actions + { + Stop Holding Button(Event Player, Button(Ability 1)); + Stop Holding Button(Event Player, Button(Ultimate)); + } +} + +rule("SUBROUTINE: BALL - RESPAWN") +{ + event + { + Subroutine; + BotBallRespawn; + } + + actions + { + "RESPAWN IN AIR" + Teleport(Event Player, Random Value In Array(Global.ballSpawnPositions) + Vector(0, 20, 0)); + Stop Holding Button(Event Player, Button(Ultimate)); + Wait(0.250, Ignore Condition); + "LANDING" + Start Holding Button(Event Player, Button(Crouch)); + Wait Until(Is On Ground(Event Player), 9999); + Stop Holding Button(Event Player, Button(Crouch)); + "LANDING IMPACT EFFECT" + Play Effect(All Players(Team 1), Sigma Accretion Impact Sound, Color(White), Event Player, 150); + Play Effect(All Players(Team 1), Doomfist Meteor Strike Impact Effect, Color(Gray), Position Of(Event Player), 10); + Create Effect(All Players(Team 1), Bad Aura, Color(Orange), Eye Position(Event Player), 1.500, Visible To Position and Radius); + Event Player.botEffects[0] = Last Created Entity; + "PATH FINDING TO GATE" + Event Player.botTargetPosition = Global.gatePosition; + Event Player.botIsPathFinding = True; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +disabled rule("=== ECHO ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ECHO - FLY ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Is Using Ability 1(Event Player) == False; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), 0); + Press Button(Event Player, Button(Ability 1)); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - BEAM ABILITY") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Is Using Ability 1(Event Player) == False; + Event Player.botDoesUniqueBehaviour == True; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - BAD STATUS - RESET BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.hasBadStatus == True; + } + + actions + { + If(Event Player.botDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + Wait Until(Event Player.hasBadStatus, 7); + } +} + +rule("BOT: ECHO - CAN'T SEE PORTAL - APPLY IMPULSE") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == True; + Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Wait(0.300, Abort When False); + Apply Impulse(Event Player, Vector(Random Integer(-1, 1), 1, Random Integer(-1, 1)), 20, To World, Incorporate Contrary Motion); + Wait(1, Ignore Condition); + If(!Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS)); + Event Player.botTargetPosition = Global.botEchoRespawnPosition; + Start Rule(BotStartPathFinding, Restart Rule); + Else; + Call Subroutine(BotResetPathFinding); + End; + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + } + + actions + { + If(Event Player.botDoesUniqueBehaviour == False); + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Current Array Element.isInMenu == False && (Hero Of(Current Array Element) == Hero(Sombra) && Is Using Ability 1( + Current Array Element)) == False && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), + Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + End; + "TELEPORT PLAYER SO FAR" + If(Event Player.botDoesUniqueBehaviour && Distance Between(Position Of(Event Player.botEchoCapturedPlayer), + Global.botEchoRespawnPosition) < 4); + Play Effect(All Players(Team 1), Bad Pickup Effect, Color(White), Global.botEchoRespawnPosition, 1); + Teleport(Event Player.botEchoCapturedPlayer, Random Value In Array(Global.botEchoTeleportPositions)); + Set Status(Event Player.botEchoCapturedPlayer, Event Player, Knocked Down, 1); + Call Subroutine(BotEchoDetachPlayer); + End; + "BEGIN TO FLY TO THE PORTAL WITH A PLAYER" + If(Event Player.botDoesUniqueBehaviour); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + "BOT SEES THE PORTAL" + If(Is In Line of Sight(Position Of(Event Player), Global.botEchoRespawnPosition, Barriers Do Not Block LOS)); + "RESET PATH FINDING" + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + "BOT DOES NOT SEE THE PORTAL" + Else If(!Event Player.botIsPathFinding); + Event Player.botTargetPlayer = Event Player.botEchoCapturedPlayer; + Stop Holding Button(Event Player, Button(Jump)); + Start Rule(BotStartPathFinding, Restart Rule); + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: ECHO - DEFEND PORTAL") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer == Null; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - CAN SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer), Barriers Do Not Block LOS) == True; + Event Player.botSeePlayer.isInMenu == False; + } + + actions + { + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPlayer); + } +} + +rule("BOT: ECHO - PATH FINDING TO PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Event Player.botDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer), Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.botTargetPlayer = Event Player.botSeePlayer; + Stop Holding Button(Event Player, Button(Jump)); + Call Subroutine(BotStartPathFinding); + } +} + +rule("BOT: ECHO - ATTACH PLAYER BY BEAM") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.hasBadStatus == False; + Event Player.botSeePlayer != Null; + Event Player.isRespawning == False; + Event Player.botEchoCapturedPlayer == Null; + Event Player.botDoesUniqueBehaviour == False; + Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer), Barriers Do Not Block LOS) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) < 3; + } + + actions + { + Event Player.botDoesUniqueBehaviour = True; + Event Player.botEchoCapturedPlayer = Event Player.botSeePlayer; + Set Status(Event Player.botEchoCapturedPlayer, Event Player, Stunned, 0.700); + Set Status(Event Player.botEchoCapturedPlayer, Event Player, Hacked, 10); + Attach Players(Event Player.botEchoCapturedPlayer, Event Player, Vector(0, 0, 2)); + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ECHO - PLAYER DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Echo; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Is Dead(Event Player.botEchoCapturedPlayer) != Null; + } + + actions + { + If(Event Player.botDoesUniqueBehaviour); + Call Subroutine(BotEchoDetachPlayer); + End; + If(Event Player.botIsPathFinding); + Call Subroutine(BotResetPathFinding); + End; + Call Subroutine(BotEchoFlyToPortal); + } +} + +rule("BOT: ECHO - DEATH") +{ + event + { + Player Died; + Team 2; + Echo; + } + + actions + { + Call Subroutine(BotEchoDetachPlayer); + Stop Holding Button(Event Player, Button(Jump)); + Wait(5, Ignore Condition); + Teleport(Event Player, Vector(0, 999, 0)); + Start Forcing Player To Be Hero(Event Player, Hero(Orisa)); + } +} + +rule("SUBROUTINE: ECHO - RESPAWN") +{ + event + { + Subroutine; + BotEchoRespawn; + } + + actions + { + Event Player.botCounter = 0; + Event Player.botEffects = Empty Array; + Create Effect(All Players(Team 1), Good Aura, Color(Sky Blue), Global.botEchoRespawnPosition, Event Player.botCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, botEffects, Append To Array, Last Created Entity); + Create Effect(All Players(Team 1), Bad Aura, Color(Sky Blue), Global.botEchoRespawnPosition, Event Player.botCounter, + Visible To Position and Radius); + Modify Player Variable(Event Player, botEffects, Append To Array, Last Created Entity); + Create Effect(All Players(Team 1), Energy Sound, Color(White), Global.botEchoRespawnPosition, 200, Visible To); + Modify Player Variable(Event Player, botEffects, Append To Array, Last Created Entity); + Chase Player Variable Over Time(Event Player, botCounter, 3, 0.800, Destination and Duration); + Play Effect(All Players(Team 1), Sombra EMP Explosion Effect, Color(Sky Blue), Global.botEchoRespawnPosition, 12); + Play Effect(All Players(Team 1), Sombra EMP Explosion Sound, Null, Global.botEchoRespawnPosition, 100); + Wait(3, Ignore Condition); + Teleport(Event Player, Global.botEchoRespawnPosition); + Play Effect(All Players(Team 1), Good Explosion, Color(White), Global.botEchoRespawnPosition, 2.500); + Play Effect(All Players(Team 1), Debuff Impact Sound, Null, Global.botEchoRespawnPosition, 100); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PLAYER") +{ + event + { + Subroutine; + BotEchoFlyToPlayer; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), 300, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), + 1, To World, Replace existing throttle, Direction and Magnitude); + Stop Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - FLY TO PORTAL") +{ + event + { + Subroutine; + BotEchoFlyToPortal; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 100, To World, + Direction and Turn Rate); + Start Throttle In Direction(Event Player, Direction Towards(Eye Position(Event Player), Global.botEchoRespawnPosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Start Holding Button(Event Player, Button(Jump)); + } +} + +rule("SUBROUTINE: ECHO - DETACH PLAYER") +{ + event + { + Subroutine; + BotEchoDetachPlayer; + } + + actions + { + Detach Players(Event Player.botEchoCapturedPlayer); + Clear Status(Event Player.botEchoCapturedPlayer, Hacked); + "IF PLAYER INSIDE THE WALL" + If(Is In Line of Sight(Eye Position(Event Player), Eye Position(Event Player.botEchoCapturedPlayer), Barriers Do Not Block LOS)); + Teleport(Event Player.botEchoCapturedPlayer, Position Of(Event Player)); + End; + Event Player.botDoesUniqueBehaviour = False; + Event Player.botEchoCapturedPlayer = Null; + } +} + +disabled rule("=== REINHARDT ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: REIN - SET PLAYER AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + && Current Array Element.isInMenu == False && (Hero Of(Current Array Element) == Hero(Sombra) && Is Using Ability 1( + Current Array Element)) == False), Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), + Barriers Do Not Block LOS)) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET CLOSEST PLAYER TO BOT AS TARGET AND FOLLOW HIM" + Event Player.botTargetPlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Current Array Element.isInMenu == False && (Hero Of(Current Array Element) == Hero(Sombra) && Is Using Ability 1( + Current Array Element)) == False && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), + Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Position Of(Event Player.botTargetPlayer)), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - SET GATE AS TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + "BOT DOESN'T FOLLOW PLAYER" + Event Player.botTargetPlayer == -1; + } + + actions + { + Call Subroutine(BotResetPathFinding); + "SET GATE AS TARGET" + Event Player.botTargetPosition = Global.gatePosition; + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: REIN - TARGET DEAD") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botTargetPlayer != -1; + (Is Dead(Event Player.botTargetPlayer) || Event Player.botTargetPlayer.isInMenu || (Hero Of(Event Player.botTargetPlayer) == Hero( + Sombra) && Is Using Ability 1(Event Player.botTargetPlayer))) == True; + } + + actions + { + Call Subroutine(BotResetPathFinding); + } +} + +rule("BOT: REIN - ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) + : Global.gatePosition) < 4; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + "TARGET IS PLAYER" + Abort If(Event Player.botTargetPlayer != -1); + If(Event Player.isBoss == 1); + "TARGET IS GATE" + Global.gateHealth -= 25 + 10 * Global.time10Minutes; + Else; + Global.gateHealth -= 5 + 5 * Global.time5Minutes; + End; + Start Rule(GateProgressBarColor, Restart Rule); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: REIN - STOP ATTACK TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + "CAN ATTACK TARGET" + Distance Between(Position Of(Event Player), Event Player.botTargetPlayer != -1 ? Position Of(Event Player.botTargetPlayer) + : Global.gatePosition) > 4; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + } +} + +rule("BOT: REIN - USE SHIELD") +{ + event + { + Player Took Damage; + Team 2; + Reinhardt; + } + + conditions + { + Distance Between(Position Of(Event Player), Position Of(Event Player.botTargetPlayer)) > 3; + } + + actions + { + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Attacker)), 200, To World, + Direction and Turn Rate); + Start Holding Button(Event Player, Button(Secondary Fire)); + Wait Until(Distance Between(Position Of(Event Player), Position Of(Event Player.botTargetPlayer)) < 3, 3); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("BOT: REIN - CHARGE IN GATE") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botTargetPlayer == -1; + Is Using Ability 1(Event Player) == False; + Is In Line of Sight(Eye Position(Event Player), Global.gatePosition, Barriers Do Not Block LOS) == True; + Is In View Angle(Event Player, Global.gatePosition, 7.500) == True; + } + + actions + { + Start Holding Button(Event Player, Button(Ability 1)); + Wait Until(Is Using Ability 1(Event Player), 1); + Stop Holding Button(Event Player, Button(Ability 1)); + } +} + +rule("BOT: REIN - DEATH") +{ + event + { + Ongoing - Each Player; + Team 2; + Reinhardt; + } + + actions + { + Stop Holding Button(Event Player, Button(Primary Fire)); + Stop Holding Button(Event Player, Button(Secondary Fire)); + } +} + +rule("SUBROUTINE: REIN - RESPAWN") +{ + event + { + Subroutine; + BotReinRespawn; + } + + actions + { + Call Subroutine(BotAppearFromUnderground); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + } +} + +disabled rule("=== WIDOW ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: WIDOW - SEE PLAYER") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.botSeePlayer == Null; + Event Player.hasBadStatus == False; + "CAN SEE PLAYER" + Is True For Any(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + && Current Array Element.isInMenu == False && (Hero Of(Current Array Element) == Hero(Sombra) && Is Using Ability 1( + Current Array Element)) == False), Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), + Barriers Do Not Block LOS)) == True; + } + + actions + { + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Current Array Element.isInMenu == False && (Hero Of(Current Array Element) == Hero(Sombra) && Is Using Ability 1( + Current Array Element)) == False && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), + Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + Event Player.botWidowShotTime = Total Time Elapsed + (Global.timeMinutes >= 9 ? Random Real(2, 5) : Random Real(5, 10)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer)), 9999, To World, + Direction and Turn Rate); + } +} + +rule("BOT: WIDOW - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Is Reloading(Event Player) == False; + Event Player.botSeePlayer != Null; + Event Player.hasBadStatus == False; + Total Time Elapsed >= Event Player.botWidowShotTime; + } + + actions + { + Press Button(Event Player, Button(Primary Fire)); + Stop Facing(Event Player); + Event Player.botSeePlayer = Null; + } +} + +rule("BOT: WIDOW - Aim Sound") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Alive(Event Player) == True; + Is In Line of Sight(Eye Position(Players On Hero(Hero(Widowmaker), Team 2)), Eye Position(Event Player), Barriers Do Not Block LOS) + == True; + Is Alive(Players On Hero(Hero(Widowmaker), Team 2)) == True; + Players On Hero(Hero(Widowmaker), Team 2).botSeePlayer == True; + } + + actions + { + Play Effect(Event Player, Explosion Sound, Color(White), Event Player, 100); + Wait(1, Abort When False); + Loop If Condition Is True; + } +} + +rule("BOT: WIDOW - TELEPORT TO NEW POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Widowmaker; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.hasBadStatus == False; + Total Time Elapsed >= Event Player.botWidowTeleportTime; + } + + actions + { + Event Player.botWidowTeleportTime = Total Time Elapsed + 28; + Event Player.botWidowShotTime = Total Time Elapsed + (Global.timeMinutes >= 9 ? Random Real(1, 3) : Random Real(3, 6)); + Play Effect(All Players(Team 1), Bad Pickup Effect, Color(White), Event Player, 1); + Wait(0.100, Ignore Condition); + Teleport(Event Player, Filtered Array(Global.sniperPositions, Distance Between(Event Player.botEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.sniperPositions) - 2)]); + Wait(0.100, Ignore Condition); + Event Player.botEventPosition = Position Of(Event Player); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(Team 1), Debuff Impact Sound, Color(White), Event Player, 100); + } +} + +rule("BOT: WIDOW - DEATH") +{ + event + { + Player Died; + Team 2; + Widowmaker; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + Wait(0.250, Ignore Condition); + Destroy Effect(Event Player.botEffects[0]); + } +} + +rule("SUBROUTINE: WIDOW - RESPAWN") +{ + event + { + Subroutine; + BotWidowRespawn; + } + + actions + { + "RESPAWN ON RANDOM SNIPER POSITION" + Teleport(Event Player, Filtered Array(Global.sniperPositions, Distance Between(Event Player.botEventPosition, + Current Array Element) > 5)[Random Integer(0, Count Of(Global.sniperPositions) - 2)]); + Wait(0.100, Ignore Condition); + Event Player.botEventPosition = Position Of(Event Player); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(White), Event Player, 2); + Play Effect(All Players(Team 1), Debuff Impact Sound, Color(White), Event Player, 100); + Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Objective Position(2)), To World); + Wait(0.700, Ignore Condition); + Start Holding Button(Event Player, Button(Secondary Fire)); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.botEffects[0] = Last Created Entity; + Wait Until(Is Dead(Event Player), 99999); + Destroy Effect(Event Player.botEffects[0]); + } +} + +rule("SUBROUTINE: WIDOW - BAD STATUS") +{ + event + { + Subroutine; + BotWidowBadStatus; + } + + actions + { + Stop Facing(Event Player); + Destroy Effect(Event Player.botEffects[0]); + Wait Until(!Event Player.hasBadStatus, 15); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Eye Position(Event Player), Update Every Frame( + Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 999, Null, + Event Player, False)), Color(Red), Visible To Position and Radius); + Event Player.botEffects[0] = Last Created Entity; + } +} + +disabled rule("=== BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: BASTION - MAIN LOGIC - LOOP") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Event Player.botSeePlayer = Sorted Array(Filtered Array(All Living Players(Team 1), Has Spawned(Current Array Element) + == True && Current Array Element.isInMenu == False && (Hero Of(Current Array Element) == Hero(Sombra) && Is Using Ability 1( + Current Array Element)) == False && Is In Line of Sight(Eye Position(Event Player), Eye Position(Current Array Element), + Barriers Do Not Block LOS) == True), Distance Between(Position Of(Event Player), Position Of(Current Array Element)))[0]; + "SEE THE PLAYER" + If(Event Player.botSeePlayer != Null); + Stop Holding Button(Event Player, Button(Secondary Fire)); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Event Player.botSeePlayer) - Vector(0, 0.500, + 0)), 100, To World, Direction and Turn Rate); + "SELF REPAIRING" + Else If(!Is Firing Secondary(Event Player) && Health(Event Player) < Max Health(Event Player)); + Start Holding Button(Event Player, Button(Secondary Fire)); + End; + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - ARTILLERY") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer == True; + Is Reloading(Event Player) == False; + Event Player.botDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.botSeePlayer), 30) == True; + Distance Between(Position Of(Event Player), Position Of(Event Player.botSeePlayer)) > 18; + Distance Between(Eye Position(Event Player), Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Up * 99, Null, Event Player, False)) >= 35; + } + + actions + { + "TRYING TO CAPTURE TARGET" + Wait(0.800, Abort When False); + "CAPTURE TARGET" + Event Player.botDoesUniqueBehaviour = True; + Stop Throttle In Direction(Event Player); + Create Beam Effect(All Players(All Teams), Torbjörn Turret Sight Beam, Update Every Frame(Eye Position(Event Player)), + Update Every Frame(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 1000, All Living Players(Team 1), Event Player, True)), Color(Sky Blue), Visible To Position and Radius); + Event Player.botEffects[1] = Last Created Entity; + Wait(1.400, Ignore Condition); + Destroy Effect(Event Player.botEffects[1]); + Abort If(Is Dead(Event Player)); + Event Player.botEventPosition = Position Of(Event Player.botSeePlayer); + "SHOOT FROM ARTILLERY" + Event Player.botBastionArtilleryDidShotsCount = 0; + For Player Variable(Event Player, botLoopIterator1, 0, 4, 1); + Event Player.botBastionArtilleryDidShotsCount += 1; + Play Effect(All Players(Team 1), Wrecking Ball Minefield Explosion Sound, Color(White), Eye Position(Event Player), 250); + Play Effect(All Players(Team 1), Pharah Barrage Explosion Effect, Color(Orange), Eye Position(Event Player) + World Vector Of( + Vector(0, 1.400, -0.700), Event Player, Rotation), 2); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) + World Vector Of(Vector(0, 1.400, + -0.700), Event Player, Rotation), Eye Position(Event Player) + World Vector Of(Vector(Random Real(-1, 1), Random Integer(40, + 80), Random Real(0.500, 1.500)), Event Player, Rotation), Color(Orange), Visible To); + Event Player.botEffects[2] = Last Created Entity; + Wait(0.100, Ignore Condition); + Destroy Effect(Event Player.botEffects[2]); + Wait(0.400, Ignore Condition); + If(Is Dead(Event Player)); + Break; + End; + End; + Start Throttle In Direction(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 1, + To World, Replace existing throttle, Direction and Magnitude); + Wait(1.500, Ignore Condition); + Start Rule(BotBastionArtilleryDamage, Do Nothing); + Wait(4, Ignore Condition); + } +} + +rule("BOT: BASTION - PRIMARY FIRE") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == False; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botSeePlayer != Null; + Event Player.botDoesUniqueBehaviour == False; + Is In View Angle(Event Player, Position Of(Event Player.botSeePlayer), 40) == True; + } + + actions + { + Start Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Stop Holding Button(Event Player, Button(Primary Fire)); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("BOT: BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Bastion; + } + + actions + { + Stop Holding Button(Event Player, Button(Secondary Fire)); + For Player Variable(Event Player, botLoopIterator1, 0, 3, 1); + Play Effect(All Players(Team 1), Bastion Tank Cannon Explosion Effect, Color(White), Event Player, 1); + Play Effect(All Players(Team 1), Bastion Tank Cannon Explosion Sound, Color(White), Event Player, 100); + Wait(0.250, Ignore Condition); + End; + } +} + +rule("SUBROUTINE: BASTION - RESPAWN") +{ + event + { + Subroutine; + BotBastionRespawn; + } + + actions + { + Abort If(Event Player.botIsOrisaChild == True); + Call Subroutine(BotLandingFromSky); + Set Ammo(Event Player, 0, 0); + Wait Until(!Is Reloading(Event Player), 99999); + Event Player.botTargetPosition = Objective Position(2); + } +} + +rule("SUBROUTINE: BASTION - ARTILLERY DAMAGE") +{ + event + { + Subroutine; + BotBastionArtilleryDamage; + } + + actions + { + Event Player.botDoesUniqueBehaviour = False; + "EXPLOSIONS OF ARTILLERY" + For Player Variable(Event Player, botLoopIterator2, 0, Event Player.botBastionArtilleryDidShotsCount, 1); + Event Player.botEventPosition = Ray Cast Hit Position(Event Player.botEventPosition + Vector(0, 50, 0), + Event Player.botEventPosition + Vector(Random Integer(-4, 4), -15, Random Integer(-4, 4)), Null, Event Player, True); + Damage(Players Within Radius(Event Player.botEventPosition, 8, Team 1, Surfaces And Enemy Barriers), Event Player, 50); + Play Effect(All Players(Team 1), Bastion Tank Cannon Explosion Sound, Color(White), Event Player.botEventPosition, 150); + Play Effect(All Players(Team 1), Pharah Rocket Launcher Explosion Effect, Color(Orange), Event Player.botEventPosition, 5); + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Event Player.botEventPosition, + Event Player.botEventPosition + Vector(0, 60, 0), Color(Orange), Visible To); + Event Player.botEffects[1] = Last Created Entity; + Wait(0.100, Ignore Condition); + Destroy Effect(Event Player.botEffects[1]); + Wait(0.400, Ignore Condition); + End; + } +} + +disabled rule("=== ORISA + BASTION ===") +{ + event + { + Ongoing - Global; + } +} + +rule("BOT: ORISA-BASTION - REACHED TARGET POSITION") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.botIsPathFinding == True; + Distance Between(Position Of(Event Player), Global.botOrisaTargetPosition) < 1.500; + } + + actions + { + Call Subroutine(BotResetPathFinding); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Vector(X Component Of(Global.gatePosition), -999, + Z Component Of(Global.gatePosition))), 80, To World, Direction and Turn Rate); + Start Facing(Global.botOrisaChild, Direction Towards(Eye Position(Event Player), Is In Line of Sight(Eye Position(Event Player), + Global.gatePosition, Barriers Do Not Block LOS) ? Global.gatePosition : Sorted Array(Filtered Array(All Players(Team 1), + Is Alive(Current Array Element)), Distance Between(Eye Position(Event Player), Position Of(Current Array Element)))[0]), 200, + To World, Direction and Turn Rate); + Press Button(Event Player, Button(Ability 1)); + Wait Until(Y Component Of(Facing Direction Of(Event Player)) < -0.300, 99999); + Press Button(Event Player, Button(Ability 2)); + Wait(0.800, Ignore Condition); + Global.botOrisaChild.botDoesUniqueBehaviour = False; + Disallow Button(Event Player, Button(Ability 2)); + } +} + +rule("BOT: ORISA-BASTION - SHOOT") +{ + event + { + Ongoing - Each Player; + Team 2; + Bastion; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Event Player.botIsOrisaChild == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botDoesUniqueBehaviour == False; + } + + actions + { + Event Player.botDoesUniqueBehaviour = True; + While(Is Alive(Event Player)); + Create Effect(All Players(Team 1), Bad Aura, Color(Purple), Eye Position(Event Player) - Vector(0, 0.700, 0) + Facing Direction Of( + Event Player) * 3.200, 1, Visible To Position and Radius); + Event Player.botEffects[3] = Last Created Entity; + Wait(1.500, Ignore Condition); + Destroy Effect(Event Player.botEffects[3]); + Abort If(Is Dead(Event Player)); + Press Button(Event Player, Button(Primary Fire)); + Press Button(Event Player, Button(Reload)); + Event Player.botRayCastHitPosition = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + + Facing Direction Of(Event Player) * 999, All Players(Team 1), All Players(Team 2), True); + "ANTI-SHIELD BUG" + Event Player.botRayCastHitPosition = Event Player.botRayCastHitPosition + Direction Towards(Event Player.botRayCastHitPosition, + Eye Position(Event Player)) * 0.200; + Create Beam Effect(All Players(All Teams), Zarya Particle Beam, Eye Position(Event Player) - Vector(0, 0.700, 0) + + Facing Direction Of(Event Player) * 3, Event Player.botRayCastHitPosition, Color(Purple), Visible To Position and Radius); + Event Player.botEffects[4] = Last Created Entity; + Damage(Players Within Radius(Event Player.botRayCastHitPosition, 4, Team 1, Surfaces And All Barriers), Event Player, 0.040); + Play Effect(All Players(Team 1), Pharah Concussive Blast Effect, Color(Purple), Event Player.botRayCastHitPosition, 4); + Play Effect(All Players(Team 1), Pharah Concussive Blast Sound, Color(Purple), Event Player.botRayCastHitPosition, 250); + Play Effect(All Players(Team 1), Bad Explosion, Color(Purple), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 3.300, 2); + Play Effect(All Players(Team 1), Sombra EMP Explosion Sound, Color(Purple), Eye Position(Event Player), 170); + If(Distance Between(Event Player.botRayCastHitPosition, Global.gatePosition) < 4 && Is In Line of Sight( + Event Player.botRayCastHitPosition, Global.gatePosition, Enemy Barriers Block LOS)); + Global.gateHealth -= 80 + 10 * Global.time5Minutes; + Start Rule(GateProgressBarColor, Restart Rule); + End; + Wait(0.150, Ignore Condition); + Destroy Effect(Event Player.botEffects[4]); + Wait(0.100, Ignore Condition); + Wait Until(!Is Reloading(Event Player), 2.500); + End; + } +} + +rule("BOT: ORISA-BASTION - CAN'T SEE THE TARGET") +{ + event + { + Ongoing - Each Player; + Team 2; + Orisa; + } + + conditions + { + Is Dummy Bot(Event Player) == True; + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + Event Player.isRespawning == False; + Event Player.botIsPathFinding == False; + Is In Line of Sight(Eye Position(Event Player), Global.gatePosition, Barriers Do Not Block LOS) == False; + } + + actions + { + Event Player.botTargetPosition = Global.botOrisaTargetPosition; + Start Rule(BotStartPathFinding, Restart Rule); + } +} + +rule("BOT: ORISA-BASTION - DEATH") +{ + event + { + Player Died; + Team 2; + Orisa; + } + + actions + { + Allow Button(Event Player, Button(Ability 2)); + Kill(Global.botOrisaChild, Null); + Detach Players(Global.botOrisaChild); + Clear Status(Global.botOrisaChild, Phased Out); + Set Damage Dealt(Global.botOrisaChild, 100); + Global.botOrisaChild.botIsOrisaChild = False; + Global.botOrisaChild = Null; + Global.botOrisaParent = Null; + Start Forcing Player To Be Hero(Event Player, Hero(Widowmaker)); + } +} + +rule("SUBROUTINE: ORISA - RESPAWN") +{ + event + { + Subroutine; + BotOrisaRespawn; + } + + actions + { + Global.botOrisaParent = Event Player; + "WAITING FOR ANY BASTION TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero(Bastion)), + 99999); + "SETUP BASTION AS CHILD" + Global.botOrisaChild = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Bastion))[0]; + Global.botOrisaChild.botIsOrisaChild = True; + Global.botOrisaChild.botDoesUniqueBehaviour = True; + Wait(2, Ignore Condition); + Respawn(Global.botOrisaChild); + Start Scaling Player(Global.botOrisaChild, 1.800, False); + Set Damage Dealt(Global.botOrisaChild, 2000); + Set Status(Global.botOrisaChild, Null, Phased Out, 9999); + Disable Nameplates(Global.botOrisaChild, All Players(All Teams)); + Set Facing(Global.botOrisaChild, Vector(X Component Of(Facing Direction Of(Event Player)), 9999, Z Component Of( + Facing Direction Of(Event Player))), To World); + Start Holding Button(Global.botOrisaChild, Button(Ability 1)); + Wait Until(Is In Alternate Form(Global.botOrisaChild), 5); + Stop Holding Button(Global.botOrisaChild, Button(Ability 1)); + Teleport(Global.botOrisaChild, Position Of(Event Player)); + Attach Players(Global.botOrisaChild, Global.botOrisaParent, Vector(0, 1.800, 0.230)); + Call Subroutine(BotLandingFromSky); + Start Facing(Event Player, Direction Towards(Position Of(Event Player), Event Player.botNextNodePosition), 360, To World, + Direction and Turn Rate); + Event Player.botTargetPosition = Global.botOrisaTargetPosition; + Start Rule(BotStartPathFinding, Do Nothing); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 0 - ZENS, REINS, BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 0; + } + + actions + { + "CREATE BOTS - ZEN" + While(Count Of(All Players(Team 2)) < 13); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "BALL" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Wrecking Ball))) == 0); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, Ignore Condition); + End; + "REPLACE DEAD ZEN TO REIN" + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Reinhardt))) != 3); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Reinhardt), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 1 - WIDOW") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 1; + } + + actions + { + Global.isNewWaveGameLogicProcessing = True; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.200, Ignore Condition); + Create Dummy Bot(Hero(Widowmaker), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + Global.isNewWaveGameLogicProcessing = False; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 3 - BALL") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 3; + } + + actions + { + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Wrecking Ball), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule("GLOBAL: GAME LOGIC - MIN 6 - BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 6; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) == 0); + "WAITING FOR ANY ZEN TO DIE" + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + "REPLACE HIM TO A NEW HERO" + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("GLOBAL: GAME LOGIC - MIN 9 - ECHO, +1 BASTION") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 9; + } + + actions + { + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Widowmaker))) > 0); + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Widowmaker)), 99999); + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Widowmaker))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Echo))) == 0); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Echo), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + While(Count Of(Filtered Array(All Players(Team 2), Hero Of(Current Array Element) == Hero(Bastion))) < 2); + Wait Until(Is True For Any(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) == Hero( + Zenyatta)), 99999); + Global.defaultCurrentBot = Filtered Array(All Players(Team 2), Is Dead(Current Array Element) && Hero Of(Current Array Element) + == Hero(Zenyatta))[0]; + Wait(0.200, Ignore Condition); + Destroy Dummy Bot(Team 2, Slot Of(Global.defaultCurrentBot)); + Wait(0.500, Ignore Condition); + Create Dummy Bot(Hero(Bastion), Team 2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + End; + "FILL EMPTY SLOTS BY ZENS" + While(Count Of(All Players(Team 2)) < 13); + Wait(1, Ignore Condition); + Create Dummy Bot(Hero(Zenyatta), Team 2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + End; + } +} + +rule("Ana Nano Variable") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + } + + actions + { + Player Closest To Reticle(Event Player, Team 1).isNanoed = 1; + } +} + +rule("isNanoed") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isNanoed == True; + } + + actions + { + If(Is Dead(Event Player)); + Event Player.isNanoed = 0; + End; + Wait(8, Ignore Condition); + Event Player.isNanoed = 0; + } +} + +rule("money on kill") +{ + event + { + Player Dealt Final Blow; + Team 1; + All; + } + + actions + { + If(Hero Of(Victim) == Hero(Zenyatta)); + All Players(Team 1).money[0] += 10 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 10 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + If(Global.upgradeMaxAmmoValue < Global.upgradeMaxAmmoMaxValue[2]); + Global.upgradeMaxAmmoValue += Victim.isBoss == 1 ? 10 : 1; + End; + Else If(Hero Of(Victim) == Hero(Reinhardt)); + All Players(Team 1).money[0] += 20 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 20 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Wrecking Ball)); + All Players(Team 1).money[0] += 30 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 30 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Widowmaker)); + All Players(Team 1).money[0] += 50 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 50 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Bastion)); + All Players(Team 1).money[0] += 70 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 70 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Echo)); + All Players(Team 1).money[0] += 90 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 90 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Else If(Hero Of(Victim) == Hero(Orisa)); + All Players(Team 1).money[0] += 120 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + Global.startMoney += 120 * (Victim.isBoss ? 3 : 1) * Global.moneyMultiplier; + } +} + +rule("Abilities and Hero Talents by Shingen and LemonAid") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.damageDealt = 100; + Event Player.playerHealth = 100; + Event Player.money[0] = 2400 + Global.startMoney; + If(Custom String("{0}", Event Player) == Custom String("ShuriZma")); + Create HUD Text(Event Player, Custom String("Serverload: {0}, AVG {1}, Peak {2}", Server Load, Server Load Average, + Server Load Peak), Null, Null, Left, -10000, Color(Red), Color(White), Color(White), Visible To and String, + Default Visibility); + End; + } +} + +rule("Team 1 (Ability): Quick Fix") +{ + event + { + Player Earned Elimination; + Team 1; + All; + } + + conditions + { + Event Player.abilities[3] == True; + } + + actions + { + Heal(Event Player, Null, Event Player.abilities[3] * 50); + Set Move Speed(Event Player, 100 + Event Player.abilities[3] * 20); + Wait(5, Restart When True); + Set Move Speed(Event Player, 100); + } +} + +rule("Team 1 (Ability): Heavyweight") +{ + event + { + Player Dealt Knockback; + Team 1; + All; + } + + conditions + { + Event Player.abilities[4] == True; + } + + actions + { + Damage(Victim, Event Player, Event Player.abilities[4] * 25 / Event Player.damageDealt * Event Damage); + } +} + +rule("Team 1 (Ability): Charged") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[5] == True; + Ultimate Charge Percent(Event Player) < Event Player.abilities[5] * 20; + } + + actions + { + Set Ultimate Charge(Event Player, Event Player.abilities[5] * 20); + If(Is Duplicating(Event Player)); + Wait(0.100, Ignore Condition); + Set Ultimate Charge(Event Player, Event Player.abilities[5] * 20); + End; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Team 1 (Ability): Haste Primary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Primary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Primary Fire), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Primary Fire))); + } +} + +rule("Team 1 (Ability): Haste Secondary Fire") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Secondary Fire)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Secondary Fire), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Secondary Fire))); + } +} + +rule("Team 1 (Ability): Haste Ability 1") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 1)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 1), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 1))); + } +} + +rule("Team 1 (Ability): Haste Ability 2") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Ability 2)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Ability 2), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, + Button(Ability 2))); + } +} + +rule("Team 1 (Ability): Haste Jump") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Jump)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Jump), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, Button( + Jump))); + } +} + +rule("Team 1 (Ability): Haste Crouch") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[6] == True; + Ability Cooldown(Event Player, Button(Crouch)) > 0.100; + } + + actions + { + Set Ability Cooldown(Event Player, Button(Crouch), (1 - 0.250 * Event Player.abilities[6]) * Ability Cooldown(Event Player, Button( + Crouch))); + } +} + +rule("Team 1 (Ability): Heavy Impact") +{ + event + { + Player Took Damage; + Team 2; + All; + } + + conditions + { + Attacker.abilities[7] == True; + } + + actions + { + Abort If(Random Real(-0.020, 1) > Event Damage / Max Health(Event Player)); + Set Status(Event Player, Attacker, Stunned, 1 * Attacker.abilities[7]); + Wait(5, Ignore Condition); + } +} + +rule("Team 1 (Ability): Resilience") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[11] == True; + Normalized Health(Event Player) < Event Player.abilities[11] * 0.300; + } + + actions + { + Set Damage Received(Event Player, 70); + Wait Until(!(Event Player.abilities[11] && Normalized Health(Event Player) < Event Player.abilities[11] * 0.300), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Auto Repair") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.automaticRepair == True; + Global.gateHealth < Global.gateMaxHealth; + } + + actions + { + If(Global.gateMaxHealth - Global.gateHealth > 5 * Global.automaticRepair * ( + Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 2 : 1)); + Global.gateHealth += 5 * Global.automaticRepair * ( + Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 2 : 1); + Global.upgradeGateMaxHealthValue += 5 * Global.automaticRepair; + Else; + Global.gateHealth += Global.gateMaxHealth - Global.gateHealth; + Global.upgradeGateMaxHealthValue += Global.gateMaxHealth - Global.gateHealth; + End; + "UPDATE GATE'S HEALTH BAR" + Start Rule(GateProgressBarColor, Restart Rule); + Wait(5, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Hero Talent Text") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + Is Alive(Event Player) == True; + } + + actions + { + If(Hero Of(Event Player) == Hero(Ana)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Ana), Button(Ability 1)), Custom String( + "Sleep Paralysis: Slept enemies cannot be woken up by damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Ana), Button(Ability 2)), Custom String( + "Multinade: Ana throws multiple Biotic Grenades")); + Else If(Hero Of(Event Player) == Hero(Ashe)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Ashe), Button(Ability 2)), Custom String( + "Wildfire: Shooting a burning enemy ignites other nearby enemies")); + Event Player.heroTalentText[2] = Array(Icon String(Fire), Custom String( + "Flare trigger: Coach gun instantly damages all burning enemies")); + Else If(Hero Of(Event Player) == Hero(Baptiste)); + Event Player.heroTalentText[1] = Array(Icon String(Poison), Custom String( + "Corrode: Regenerative Burst will damage and poison enemies")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Breakthrough: Immortality Field HP threshold increased to 100%; allies inside gain ultimate")); + Else If(Hero Of(Event Player) == Hero(Bastion)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Bomblets: Bullets shot during sentry configuration are explosive")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ability 1)), Custom String( + "Tesla: A powerful mounted laser will automatically attack one enemy at a time")); + Else If(Hero Of(Event Player) == Hero(Brigitte)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Brigitte), Button(Ability 1)), Custom String( + "Heavy Iron: Hitting enemies with Whip Flail will root them in pace")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Brigitte), Button(Ultimate)), Custom String( + "Endeavor: Gain a health, damage and speed boost when your barrier breaks")); + Else If(Hero Of(Event Player) == Hero(Cassidy)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Cassidy), Button(Ability 2)), Custom String( + "Panic: Flashbang puts enemies in fear; deal +120% more damage to enemies in fear")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Cassidy), Button(Ultimate)), Custom String( + "Clocked: Deadeye deals more damage and knocks enemies down")); + Else If(Hero Of(Event Player) == Hero(Doomfist)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Jump)), Custom String( + "Phase Shifter: Immune to damage while any ability is active")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Doomfist), Button(Ultimate)), Custom String( + "Fissure: Meteor Strike leaves a large fissure behind that burns enemies over it")); + Else If(Hero Of(Event Player) == Hero(D.Va)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(D.Va), Button(Secondary Fire)), Custom String( + "Voltage Grid: Defense Matrix will damage and root enemies it's casted over")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(D.Va), Button(Ability 1)), Custom String( + "Shooting Star: Boosters set enemies on fire")); + Else If(Hero Of(Event Player) == Hero(Echo)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Focusing Optics: Focusing Beam damage ramp starts at 90% health")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Secondary Fire)), Custom String( + "Streamline: Fire many more sticky bombs per burst")); + Else If(Hero Of(Event Player) == Hero(Genji)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Genji), Button(Ability 1)), Custom String( + "Venomous Strike: Swift Strike poisons enemies; heal for poison damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Genji), Button(Ultimate)), Custom String( + "Dragon's Breath: Dragonblade fires large explosive energy charges")); + Else If(Hero Of(Event Player) == Hero(Hanzo)); + Event Player.heroTalentText[1] = Array(Icon String(Bolt), Custom String( + "Stormbreak: Enemies eliminated by hanzo unleash a thundercloud")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Hanzo), Button(Ability 2)), Custom String( + "Punch II: Storm Arrows deal more damage and stun and knockback enemies")); + Else If(Hero Of(Event Player) == Hero(Junkrat)); + Event Player.heroTalentText[1] = Array(Icon String(Fire), Custom String("Pyromania: All explosive attacks inflict fire damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Junkrat), Button(Ability 2)), Custom String( + "Short Fused: Steel Trap sets off violent explosions once triggered")); + Else If(Hero Of(Event Player) == Hero(Lúcio)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Lúcio), Button(Secondary Fire)), Custom String( + "Healing Wave: Sound wave heals allies for 30% of their max HP")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Lúcio), Button(Ability 1)), Custom String( + "Reverse Amp: Amp It Up inflicts the opposite effect of the currently played song to enemies")); + Else If(Hero Of(Event Player) == Hero(Mei)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Mei), Button(Ultimate)), Custom String( + "Cold Snap: Instantly freeze nearby enemies once Cryo-Freeze expires")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Mei), Button(Ability 2)), Custom String( + "Icebound: While Ice Wall is up, Icicles freeze and deal much more damage")); + Else If(Hero Of(Event Player) == Hero(Mercy)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Mercy), Button(Ability 2)), Custom String( + "Angelic blessing: Healing an ally slowly charges their ultimate")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Mercy), Button(Ultimate)), Custom String( + "Holy light missiles: Unleash blasts of holy light missiles during valkyrie")); + Else If(Hero Of(Event Player) == Hero(Moira)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Moira), Button(Secondary Fire)), Custom String( + "Hose: Biotic Grasp primary will damage and push enemies back")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Moira), Button(Ability 2)), Custom String( + "Flourish: Biotic Orbs are 3x more effective")); + Else If(Hero Of(Event Player) == Hero(Orisa)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Orisa), Button(Ability 1)), Custom String( + "Immovable Object: During Fortify, become immune and convert 50% of taken damage to healing")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Orisa), Button(Secondary Fire)), Custom String( + "Unstoppable Force: Halt! is much larger and pushes enemies. When triggered, it explodes violently")); + Else If(Hero Of(Event Player) == Hero(Pharah)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ability 2)), Custom String( + "Head Trauma: Concussive Blast stuns and damages enemies for 25% of their max health")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Pharah), Button(Ability 1)), Custom String( + "Thunderbird: Gain 150 shields and deal 4x the damage to barriers and objects")); + Else If(Hero Of(Event Player) == Hero(Reaper)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Reaper), Button(Ability 1)), Custom String( + "shadow streak: shadow step creates a beam that damages enemies who cross")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Reaper), Button(Ultimate)), Custom String( + "Loom: Traumatize enemies in front of you when using Wraith Form")); + Else If(Hero Of(Event Player) == Hero(Reinhardt)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Reinhardt), Button(Ability 2)), Custom String( + "Fire Blast: Fire Strike explodes as it deals damage, setting enemies on fire")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Reinhardt), Button(Ultimate)), Custom String( + "Epicenter: Earth shatter travels in all directions")); + Else If(Hero Of(Event Player) == Hero(Roadhog)); + Event Player.heroTalentText[1] = Array(Icon String(Poison), Custom String("Stench: Roadhog constantly damages enemies nearby")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Roadhog), Button(Ability 1)), Custom String( + "Rusted Anchor: Hook deals more damage; Eliminations will reset hook cooldown")); + Else If(Hero Of(Event Player) == Hero(Sigma)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Sigma), Button(Ability 1)), Custom String( + "Gravity Well: Kinetic Grasp gives invincibility")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Sigma), Button(Ultimate)), Custom String( + "Gravity Channels: Gravitic Flux damages enemies for 75% of max hp instead of 50%")); + Else If(Hero Of(Event Player) == Hero(Soldier: 76)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Pharah), Button(Ultimate)), Custom String( + "Triple Threat: 2 more rockets are fired alongside Helix Rockets")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Soldier: 76), Button(Ability 1)), Custom String( + "Shoulder Check: Sprinting into enemies will damage and tackle them to the ground")); + Else If(Hero Of(Event Player) == Hero(Sombra)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Sombra), Button(Secondary Fire)), Custom String( + "Malware: Enemies hacked or in fear take +100% more damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Sombra), Button(Ultimate)), Custom String( + "Glitch: EMP leaves behind a large hack zone ")); + Else If(Hero Of(Event Player) == Hero(Symmetra)); + Event Player.heroTalentText[1] = Array(Icon String(Bolt), Custom String( + "High Voltage: Enemies eliminated by Symmetra explode and damage other enemies")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Symmetra), Button(Ultimate)), Custom String( + "Energy Source: While Photon Barrier is active, all players regenerate health and gain ultimate")); + Else If(Hero Of(Event Player) == Hero(Torbjörn)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Torbjörn), Button(Ability 2)), Custom String( + "Melting point: Unleash heatwaves during overload and molten core")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Torbjörn), Button(Ultimate)), Custom String( + "Roots Of Magma: Enemies trapped in Molten Core blots cannot move")); + Else If(Hero Of(Event Player) == Hero(Tracer)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Tracer), Button(Ability 2)), Custom String( + "Vortex: Recall pulls and roots enemies towards the activation point")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Tracer), Button(Ultimate)), Custom String( + "Chain Reaction: Pulse Bomb creates chain explosions on enemies damaged by it")); + Else If(Hero Of(Event Player) == Hero(Widowmaker)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Widowmaker), Button(Ultimate)), Custom String( + "Kiss Of Death: Scoped critical hits against enemies below 30% health explode and instantly die")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Widowmaker), Button(Ability 2)), Custom String( + "Epidemic: Enemies hurt by Venom Mine unleash toxic pulses; heal for dealt damage")); + Else If(Hero Of(Event Player) == Hero(Winston)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Winston), Button(Ability 2)), Custom String( + "Blast Barrier: Barrier Projector damages enemies inside the area")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Winston), Button(Ultimate)), Custom String( + "Next Generation: Eliminations during Primal Rage add +15% ultimate charge towards the next")); + Else If(Hero Of(Event Player) == Hero(Wrecking Ball)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ultimate)), Custom String( + "Mirror Ball: Reflect 100% of taken damage to nearby enemies")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Wrecking Ball), Button(Ability 2)), Custom String( + "Distort: Adaptive Shields damages and hacks nearby enemies")); + Else If(Hero Of(Event Player) == Hero(Zarya)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Zarya), Button(Ability 1)), Custom String( + "Augment: Health and barrier hp increased by 50%; barrier sized doubled")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Echo), Button(Ability 2)), Custom String( + "Perpetual Energy: secondary inflicts burn damage that continues to last until the enemy dies")); + Else If(Hero Of(Event Player) == Hero(Zenyatta)); + Event Player.heroTalentText[1] = Array(Ability Icon String(Hero(Baptiste), Button(Ability 2)), Custom String( + "Vigor: The ally under the effect of Harmony Orb is immune to damage")); + Event Player.heroTalentText[2] = Array(Ability Icon String(Hero(Zenyatta), Button(Ultimate)), Custom String( + "Perfect Balance: Transcendence damages enemies in a large proximity")); + End; + } +} + +rule("Ana: Multinade") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Event Player.abilityCountdown = 4; + While(Event Player.abilityCountdown > 0); + Wait(0.100, Ignore Condition); + Set Ability Cooldown(Event Player, Button(Ability 2), 0); + Cancel Primary Action(Event Player); + Wait(0.100, Ignore Condition); + Press Button(Event Player, Button(Ability 2)); + Event Player.abilityCountdown -= 1; + End; + Wait(2, Ignore Condition); + } +} + +rule("Brigitte: Endeavor") +{ + event + { + Ongoing - Each Player; + Team 1; + Brigitte; + } + + conditions + { + Ability Cooldown(Event Player, Button(Secondary Fire)) >= 0.100; + Event Player.abilities[12] == True; + } + + actions + { + Create Effect(All Players(Team 1), Ring, Color(Orange), Event Player, 0.400, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Play Effect(All Players(Team 1), Ring Explosion, Color(Orange), Eye Position(Event Player), 15); + Heal(Players Within Radius(Event Player, 15, Team Of(Event Player), Off), Event Player, 200); + Event Player.damageDealt *= 2.500; + Set Move Speed(Event Player, 100 * 1.750); + Add Health Pool To Player(Event Player, Armor, Max Health(Event Player) / 2, False, True); + Event Player.hpPool[1] = Last Created Health Pool; + Wait Until(Is Dead(Event Player), 6); + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Set Move Speed(Event Player, 100); + Remove Health Pool From Player(Event Player.hpPool[1]); + Destroy Effect(Event Player.effects_[1]); + } +} + +rule("Mercy: Aurora") +{ + event + { + Ongoing - Each Player; + Team 1; + Mercy; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ultimate(Event Player) == True; + } + + actions + { + Wait(1.500, Ignore Condition); + Event Player.abilityProjectile1 = Eye Position(Event Player); + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(All Teams), Event Player, True); + Create Beam Effect(All Players(All Teams), Mercy Heal Beam, Event Player, Event Player.abilityProjectile1, Color(White), + Visible To Position and Radius); + Event Player.effects_[3] = Last Created Entity; + Chase Player Variable At Rate(Event Player, abilityProjectile1, Event Player.abilityEnd, 70, Destination and Rate); + While(Event Player.abilityEnd != Event Player.abilityProjectile1); + Play Effect(All Players(Team 1), Good Explosion, Color(Yellow), Event Player.abilityProjectile1, 1); + Wait(0.100, Ignore Condition); + End; + Destroy Effect(Event Player.effects_[3]); + Play Effect(All Players(Team 1), Good Explosion, Color(White), Event Player.abilityProjectile1, 5); + Play Effect(All Players(Team 1), Bad Explosion, Color(Orange), Event Player.abilityProjectile1, 5); + Damage(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 120); + Loop If Condition Is True; + } +} + +rule("Lucio: Healing Wave") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(Team 1), Good Explosion, Color(Green), Eye Position(Event Player) + Facing Direction Of(Event Player) * 4, + 4); + Heal(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 4, 4, Team Of(Event Player), Surfaces), + Event Player, Max Health(Filtered Array(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) + * 4, 4, Team Of(Event Player), Surfaces), Is Alive(Current Array Element))) * 0.300); + } +} + +rule("Lucio: Reverse Amp") +{ + event + { + Ongoing - Each Player; + Team 1; + Lúcio; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + If(Is Using Ability 1(Event Player)); + Set Status(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Rooted, 4); + Else; + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 16.250); + End; + Play Effect(All Players(Team 1), Ring Explosion, Is Using Ability 1(Event Player) ? Color(Green) : Color(Yellow), Event Player, 1); + Wait(0.400, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Moira] Hose") +{ + event + { + Ongoing - Each Player; + Team 1; + Moira; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Event Player.abilities[8] == True; + Ability Resource(Event Player, Button(Primary Fire)) > False; + } + + actions + { + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Facing Direction Of(Event Player), 15, To World, + Cancel Contrary Motion); + Apply Impulse(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), Distance Between( + Event Player, Current Array Element) <= 15 && !Is In Line of Sight(Current Array Element, Event Player, + Enemy Barriers Block LOS) && !Has Status(Current Array Element, Phased Out)), Up, 8, To World, Cancel Contrary Motion); + Start Damage Over Time(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 25), + Distance Between(Event Player, Current Array Element) <= 15 && Is In Line of Sight(Event Player, Current Array Element, + Enemy Barriers Block LOS)), Event Player, 1, 15); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Baptiste: Corrode") +{ + event + { + Ongoing - Each Player; + Team 1; + Baptiste; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(Team 1), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 20); + Wait(0.200, Ignore Condition); + Play Effect(All Players(Team 1), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Damage(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 25); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, + 12); + } +} + +rule("Baptiste: Breakthrough") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Status(Event Player, Unkillable) == True; + (Event Player.abilities[12] ? Players On Hero(Hero(Baptiste), Team Of(Event Player)) : Empty Array).abilities[12] == True; + } + + actions + { + Heal(Event Player, Event Player, 10000); + Set Status(Event Player, Null, Invincible, 0.800); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ashe: Taunt") +{ + event + { + Ongoing - Each Player; + Team 1; + Ashe; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Damage(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, Burning)), + Event Player, 125); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Frozen, + 0.016); + Set Status(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Event Player, Burning)), Null, Stunned, + 2); + } +} + +rule("D.Va: Voltage Grid") +{ + event + { + Ongoing - Each Player; + Team 1; + D.Va; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(Team 1), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 2, 0.500); + Play Effect(All Players(Team 1), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 5, 0.500); + Play Effect(All Players(Team 1), Bad Explosion, Color(Turquoise), Eye Position(Event Player) + Facing Direction Of(Event Player) + * 8, 0.500); + Wait(0.300, Ignore Condition); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Damage(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 25); + Wait(0.100, Ignore Condition); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 2, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 5, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Set Status(Players Within Radius(Eye Position(Event Player) + Facing Direction Of(Event Player) * 8, 2.500, Opposite Team Of( + Team Of(Event Player)), Off), Event Player, Rooted, 0.500); + Loop If Condition Is True; + } +} + +rule("D.Va: Shooting Star") +{ + event + { + Player Dealt Knockback; + Team 1; + D.Va; + } + + conditions + { + Event Ability == Button(Ability 1); + Event Player.abilities[12] == True; + } + + actions + { + Damage(Victim, Event Player, 40); + Set Status(Victim, Null, Burning, 3); + Start Damage Over Time(Victim, Event Player, 3, 35); + Play Effect(All Players(Team 1), Bad Explosion, Color(Red), Victim, 1); + } +} + +rule("Genji: Dragon's Breath") +{ + event + { + Ongoing - Each Player; + Team 1; + Genji; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is Firing Primary(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Create Effect(All Players(Team 1), Good Aura, Color(Lime Green), Event Player.abilityProjectile1, 1, + Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Event Player.abilityProjectile1 = Eye Position(Event Player); + Chase Player Variable At Rate(Event Player, abilityProjectile1, Event Player.abilityEnd, 80, Destination and Rate); + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True); + Wait Until(Event Player.abilityEnd == Event Player.abilityProjectile1, 1); + Destroy Effect(Event Player.effects_[1]); + Play Effect(All Players(Team 1), Ring Explosion Sound, Color(Green), Event Player.abilityProjectile1, 100); + Play Effect(All Players(Team 1), Bad Explosion, Color(Lime Green), Event Player.abilityProjectile1, 5); + Play Effect(All Players(Team 1), Bad Explosion, Color(Green), Event Player.abilityProjectile1, 5); + Damage(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 100); + } +} + +rule("[Hanzo] Stormbreak (stormEffects6)") +{ + event + { + Player Died; + Team 2; + All; + } + + conditions + { + Attacker.abilities[8] == True; + Hero Of(Attacker) == Hero(Hanzo); + } + + actions + { + Event Player.stormProjectile = Eye Position(Event Player); + Event Player.stormEndPoint = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Up * 12, Null, + All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, stormProjectile, Event Player.stormEndPoint, 4, Destination and Rate); + Create Effect(All Players(Team 1), Cloud, Color(White), Vector(False, -0.500, False) + Event Player.stormProjectile, 4, + Visible To Position and Radius); + Event Player.stormEffects[3] = Last Created Entity; + Create Effect(All Players(Team 1), Bad Aura, Color(White), Event Player.stormProjectile, 3, Visible To Position and Radius); + Event Player.stormEffects[4] = Last Created Entity; + Create Effect(All Players(Team 1), Cloud, Color(White), Event Player.stormProjectile, 3.500, Visible To Position and Radius); + Event Player.stormEffects[5] = Last Created Entity; + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.stormProjectile, Ray Cast Hit Position( + Event Player.stormProjectile, Vector(0.100, 0, 0) + Event Player.stormProjectile + Down * 1000, Null, All Players(All Teams), + False), Color(Aqua), Visible To Position and Radius); + Event Player.stormEffects[6] = Last Created Entity; + While(Distance Between(Event Player.stormProjectile, Event Player.stormEndPoint) > 1); + Wait(0.600, Ignore Condition); + Damage(Players Within Radius(Ray Cast Hit Position(Event Player.stormProjectile, Event Player.stormProjectile + Down * 1000, Null, + All Players(All Teams), False), 3, Team Of(Event Player), Surfaces), Attacker, 50); + Play Effect(All Players(Team 1), Bad Pickup Effect, Color(Aqua), Ray Cast Hit Position(Event Player.stormProjectile, + Event Player.stormProjectile + Down * 1000, Null, All Players(All Teams), False), 3); + Play Effect(All Players(Team 1), Good Explosion, Color(Blue), Ray Cast Hit Position(Event Player.stormProjectile, + Event Player.stormProjectile + Down * 1000, Null, All Players(All Teams), False), 3); + End; + Destroy Effect(Event Player.stormEffects[3]); + Destroy Effect(Event Player.stormEffects[4]); + Destroy Effect(Event Player.stormEffects[5]); + Destroy Effect(Event Player.stormEffects[6]); + } +} + +rule("McCree: Panic - Damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Cassidy; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), + Event Player.fearedUntil >= Total Time Elapsed), All Players(Team Of(Event Player)), 220, + Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Wait Until(!Event Player.abilities[8], 99999); + Stop Damage Modification(Event Player.modificationDamage[1]); + } +} + +rule("Reinhardt: Epicenter") +{ + event + { + Ongoing - Each Player; + Team 1; + Reinhardt; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Is On Ground(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, Knocked Down, 2.500); + Play Effect(All Players(Team 1), Ring Explosion, Color(Orange), Position Of(Event Player), 10); + Damage(Filtered Array(Players Within Radius(Event Player, 20, Opposite Team Of(Team Of(Event Player)), Surfaces), !Has Status( + Current Array Element, Knocked Down)), Event Player, 50); + Wait(0.100, Ignore Condition); + Play Effect(All Players(Team 1), Ring Explosion, Color(Orange), Position Of(Event Player), 20); + Wait(0.100, Ignore Condition); + Play Effect(All Players(Team 1), Ring Explosion, Color(Orange), Position Of(Event Player), 30); + Wait(0.100, Ignore Condition); + Play Effect(All Players(Team 1), Ring Explosion, Color(Orange), Position Of(Event Player), 40); + Wait(5, Ignore Condition); + } +} + +rule("[Soldier: 76] Rocket Assault Rifle") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Event Player.abilityProjectile2 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(-2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.abilityProjectile1 = Ray Cast Hit Position(Eye Position(Event Player), Ray Cast Hit Position(Eye Position( + Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, Null, Null, False) + World Vector Of( + Vector(2, 0, 0), Event Player, Rotation), Null, Null, False); + Event Player.abilityPosition = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, + 0), Event Player, Rotation); + Event Player.abilityEnd = Eye Position(Event Player) + Facing Direction Of(Event Player) + World Vector Of(Vector(0, -0.250, 0), + Event Player, Rotation); + Chase Player Variable At Rate(Event Player, abilityPosition, Event Player.abilityProjectile1, 60, Destination and Rate); + Chase Player Variable At Rate(Event Player, abilityEnd, Event Player.abilityProjectile2, 60, Destination and Rate); + Wait Until(Event Player.abilityPosition == 0 && Event Player.abilityEnd == 0, 2.500); + } +} + +rule("[Soldier: 76] First Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.abilityProjectile1 != Event Player.abilityPosition; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(Team 1), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.abilityPosition, 0.400); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(Team 1), Explosion Sound, Color(Orange), Event Player.abilityPosition, 100); + Play Effect(All Players(Team 1), Good Explosion, Color(Sky Blue), Event Player.abilityPosition, 2.500); + Play Effect(All Players(Team 1), Bad Explosion, Color(Team 1), Event Player.abilityPosition, 2.500); + Stop Chasing Player Variable(Event Player, abilityPosition); + Wait(0.100, Ignore Condition); + Damage(Players Within Radius(Event Player.abilityPosition, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 80); + Stop Chasing Player Variable(Event Player, abilityPosition); + Event Player.abilityPosition = 0; + Event Player.abilityProjectile1 = 0; + Wait(0.100, Ignore Condition); + } +} + +rule("[Soldier: 76] Second Rocket Effect") +{ + event + { + Ongoing - Each Player; + All; + Soldier: 76; + } + + conditions + { + Event Player.abilityProjectile2 != Event Player.abilityEnd; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(Team 1), Good Explosion, Random Value In Array(Array(Color(Sky Blue), Color(Aqua))), + Event Player.abilityEnd, 0.400); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + Play Effect(All Players(Team 1), Explosion Sound, Color(Orange), Event Player.abilityEnd, 100); + Play Effect(All Players(Team 1), Good Explosion, Color(Sky Blue), Event Player.abilityEnd, 2.500); + Play Effect(All Players(Team 1), Bad Explosion, Color(Team 1), Event Player.abilityEnd, 2.500); + Stop Chasing Player Variable(Event Player, abilityEnd); + Damage(Players Within Radius(Event Player.abilityEnd, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Event Player.abilityEnd = 0; + Event Player.abilityProjectile2 = 0; + } +} + +rule("Soldier: 76 - Init rockets") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Event Player.abilityProjectile1 = Event Player.abilityPosition; + Event Player.abilityProjectile2 = Event Player.abilityEnd; + } +} + +rule("[Soldier: 76] Shoulder Check") +{ + event + { + Ongoing - Each Player; + Team 1; + Soldier: 76; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[12] == True; + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 3; + Is Alive(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) == True; + } + + actions + { + Damage(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Event Player, 55); + Set Status(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Null, Knocked Down, 1.500); + Apply Impulse(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Facing Direction Of(Event Player), 15, + To World, Cancel Contrary Motion); + Apply Impulse(Event Player, Vector(0, 8, 15), 15, To Player, Cancel Contrary Motion); + Play Effect(All Players(Team 1), Bad Explosion, Color(White), Closest Player To(Event Player, Opposite Team Of(Team Of( + Event Player))), 1); + Set Ability Cooldown(Event Player, Button(Melee), 0); + Press Button(Event Player, Button(Melee)); + Wait(1, Ignore Condition); + } +} + +rule("Torbjorn: Melting Point") +{ + event + { + Ongoing - Each Player; + Team 1; + Torbjörn; + } + + conditions + { + Event Player.abilities[8] == True; + (Is Using Ability 2(Event Player) || Is Using Ultimate(Event Player)) == True; + } + + actions + { + Play Effect(All Players(Team 1), Good Explosion, Color(Orange), Event Player, 8); + Play Effect(All Players(Team 1), Bad Explosion, Color(Yellow), Event Player, 8); + Play Effect(All Players(Team 1), Ring Explosion, Color(Orange), Position Of(Event Player), 16); + Start Damage Over Time(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, + 25); + Set Status(Players Within Radius(Event Player, 10, Opposite Team Of(Team Of(Event Player)), Off), Null, Burning, 3); + Play Effect(All Players(Team 1), Ring Explosion Sound, Color(White), Event Player, 100); + Wait(0.750, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Tracer: Vortex") +{ + event + { + Ongoing - Each Player; + Team 1; + Tracer; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Heal(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, 0); + Damage(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 10); + Play Effect(All Players(Team 1), Ring Explosion, Color(Red), Position Of(Event Player), 24); + Play Effect(All Players(Team 1), Ring Explosion, Color(Yellow), Position Of(Event Player), 18); + Play Effect(All Players(Team 1), Ring Explosion, Color(Green), Position Of(Event Player), 12); + Play Effect(All Players(Team 1), Ring Explosion, Color(Aqua), Position Of(Event Player), 6); + Set Environment Credit Player(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), + Event Player); + } +} + +rule("Tracer: Vortex 2") +{ + event + { + Player Received Healing; + Team 2; + All; + } + + conditions + { + Healer.abilities[8] == True; + Hero Of(Healer) == Hero(Tracer); + Is Using Ability 2(Healer) == True; + Event Ability == Null; + Event Damage <= 20; + } + + actions + { + Apply Impulse(Event Player, Up, 5, To World, Cancel Contrary Motion); + Wait(0.100, Ignore Condition); + Apply Impulse(Event Player, Direction Towards(Event Player, Healer), Distance Between(Event Player, Healer) * 3.500, To World, + Cancel Contrary Motion); + Set Status(Event Player, Null, Rooted, 1.300); + } +} + +rule("Tracer: Chain Reaction") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Is True For Any(Filtered Array(All Players(Team Of(Event Player)), Current Array Element.chainReactionOn), Distance Between( + Event Player, Current Array Element) <= 8 && True) == True; + Event Player.chainReactionImmune == False; + Event Player.chainReactionOn == False; + Is Alive(Event Player) == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Event Player.chainReactionOn = True; + Play Effect(All Players(Team 1), Good Explosion, Color(Sky Blue), Event Player, 3); + } +} + +rule("Tracer: Chain Reaction 2") +{ + event + { + Ongoing - Each Player; + Team 2; + All; + } + + conditions + { + Event Player.chainReactionOn == True; + } + + actions + { + Wait(0.100, Ignore Condition); + Play Effect(All Players(Team 1), Good Explosion, Color(Aqua), Event Player, 3); + Damage(Event Player, Players On Hero(Hero(Tracer), Opposite Team Of(Team Of(Event Player))), 200); + Wait(0.500, Ignore Condition); + Event Player.chainReactionImmune = True; + Event Player.chainReactionOn = False; + Wait(2, Ignore Condition); + Event Player.chainReactionImmune = False; + } +} + +rule("[Winston] Electric Field") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player.abilityProjectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 65); + Destroy Effect(Event Player.effects_[1]); + Event Player.abilityActive = True; + Create Effect(All Players(Team 1), Orb, Color(White), Event Player.abilityProjectile1, 1, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Stop Chasing Player Variable(Event Player, abilityResource); + Event Player.abilityProjectile1 = Eye Position(Event Player); + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Down * 1000, Null, + All Players(All Teams), False); + Wait(0.100, Ignore Condition); + Event Player.abilityResource = 5; + Wait(0.250, Ignore Condition); + Chase Player Variable At Rate(Event Player, abilityResource, 20, 7, Destination and Rate); + Chase Player Variable At Rate(Event Player, abilityProjectile1, Event Player.abilityEnd, Event Player.abilityResource, + Destination and Rate); + Wait(8.650, Restart When True); + Event Player.abilityActive = False; + } +} + +rule("[Winston] Electric Field 2") +{ + event + { + Ongoing - Each Player; + Team 1; + Winston; + } + + conditions + { + Event Player.abilityActive == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(Team 1), Ring Explosion, Color(Aqua), Event Player.abilityProjectile1, 5); + Damage(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 33); + Play Effect(All Players(Team 1), Ring Explosion, Color(Blue), Event Player.abilityProjectile1, 10); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + Damage(Players Within Radius(Event Player.abilityProjectile1, 6, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 80); + Play Effect(All Players(Team 1), Bad Explosion, Color(Turquoise), Event Player.abilityProjectile1, 12); + Destroy Effect(Event Player.effects_[1]); + Play Effect(All Players(Team 1), Ring Explosion Sound, Color(White), Event Player.abilityProjectile1, 125); + } +} + +rule("Winston: Next Generation") +{ + event + { + Player Earned Elimination; + Team 1; + Winston; + } + + conditions + { + Ultimate Charge Percent(Event Player) <= 80; + Is Using Ultimate(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 15); + } +} + +rule("Pharah: Head Trauma") +{ + event + { + Player Dealt Knockback; + Team 1; + Pharah; + } + + conditions + { + Event Ability == Button(Ability 2); + Event Player.abilities[8] == True; + Victim != Event Player; + } + + actions + { + Damage(Victim, Event Player, Max Health(Victim) * 0.300); + Set Status(Victim, Event Player, Knocked Down, 1); + Play Effect(All Players(Team 1), Good Explosion, Color(Team 1), Victim, 1); + } +} + +rule("Pharah: Thunderbird") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[12] == True; + Hero Of(Event Player) == Hero(Pharah); + } + + actions + { + Event Player.damageDealt *= 4; + Start Damage Modification(All Players(All Teams), Event Player, 25, Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Add Health Pool To Player(Event Player, Shields, 150, True, True); + Event Player.hpPool[1] = Last Created Health Pool; + Wait Until(!Event Player.abilities[12] || Hero Of(Event Player) != Hero(Pharah), 99999); + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Stop Damage Modification(Event Player.modificationDamage[1]); + Remove Health Pool From Player(Event Player.hpPool[1]); + } +} + +rule("Orisa: Unstoppable Force") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Event Player.genDirection = Facing Direction Of(Event Player); + Event Player.abilityActive = True; + Create Effect(All Players(Team 1), Sphere, Color(Green), Event Player.abilityProjectile1, 4, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Event Player.abilityProjectile1 = Eye Position(Event Player) + Facing Direction Of(Event Player) * 0.500; + Event Player.abilityEnd = Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 100, Null, All Players(All Teams), False); + Chase Player Variable At Rate(Event Player, abilityProjectile1, Event Player.abilityEnd, 25, Destination and Rate); + Wait(0.250, Ignore Condition); + Wait Until((!Event Player.genAvailable && Is Button Held(Event Player, Button(Secondary Fire))) || ( + Event Player.abilityProjectile1 == Event Player.abilityEnd), 99999); + Stop Chasing Player Variable(Event Player, abilityProjectile1); + Wait(0.500, Ignore Condition); + Damage(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 100); + Play Effect(All Players(Team 1), Good Explosion, Color(Lime Green), Event Player.abilityProjectile1, 5); + Destroy Effect(Event Player.effects_[1]); + Event Player.abilityActive = False; + } +} + +rule("Orisa: Availability for Halt!") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Firing Secondary(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Event Player.genAvailable = True; + Wait Until(!Is Button Held(Event Player, Button(Secondary Fire)), 99999); + Event Player.genAvailable = False; + } +} + +rule("Orisa: Drag effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Event Player.abilities[12] == True; + Event Player.abilityActive == True; + } + + actions + { + Apply Impulse(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Is Alive(Event Player) ? Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of( + Event Player)), Surfaces) : Empty Array, Event Player.abilityProjectile1), 8, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), + Direction Towards(Event Player.abilityProjectile1, Event Player.abilityEnd), 20, To World, Cancel Contrary Motion); + Apply Impulse(Players Within Radius(Event Player.abilityProjectile1, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Up, 5, + To Player, Cancel Contrary Motion); + Wait(0.200, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Orisa: Immoveable Object - Reduce dmg") +{ + event + { + Ongoing - Each Player; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Set Damage Received(Event Player, 100 * 0.003); + Wait Until(!Is Using Ability 1(Event Player), 99999); + Set Damage Received(Event Player, 100); + } +} + +rule("Orisa: Immovable Object - Healing") +{ + event + { + Player Took Damage; + Team 1; + Orisa; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Heal(Event Player, Null, Event Damage * 3); + } +} + +rule("[Reaper] Shadow Streak (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.abilities[8] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Event Player.abilityPosition = Position Of(Event Player) + Vector(0, 1, 0); + Wait(2, Abort When False); + Event Player.abilityEnd = Position Of(Event Player) + Vector(0, 1, 0); + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player.abilityEnd, Event Player.abilityPosition, Color(Black), + Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Event Player.abilityActive = True; + Wait Until(Is Dead(Event Player) || Is Using Ability 2(Event Player), 99999); + Destroy Effect(Event Player.effects_[1]); + Event Player.abilityActive = False; + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage start to end (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.abilities[8] == True; + Ray Cast Hit Player(Event Player.abilityPosition, Event Player.abilityEnd, All Living Players(Opposite Team Of(Team Of( + Event Player))), Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.abilityActive == True; + } + + actions + { + Play Effect(All Players(Team 1), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.abilityPosition, + Event Player.abilityEnd, All Living Players(All Teams), Event Player, True), 1); + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.abilityPosition, Event Player.abilityEnd, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("[Reaper] Shadow Streak - Damage end to start (Sethh)") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Event Player.abilities[8] == True; + Ray Cast Hit Player(Event Player.abilityEnd, Event Player.abilityPosition, All Players(Opposite Team Of(Team Of(Event Player))), + Event Player, False) != Null; + Is Using Ability 2(Event Player) == False; + Event Player.abilityActive == True; + } + + actions + { + Damage(Players Within Radius(Ray Cast Hit Player(Event Player.abilityEnd, Event Player.abilityPosition, All Living Players( + Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 4, Opposite Team Of(Team Of( + Event Player)), Off), Event Player, 40); + Play Effect(All Players(Team 1), Moira Fade Disappear Effect, Color(White), Ray Cast Hit Player(Event Player.abilityEnd, + Event Player.abilityPosition, All Living Players(All Teams), Event Player, True), 1); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Reaper: Loom") +{ + event + { + Ongoing - Each Player; + Team 1; + Reaper; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Hacked, 1.500); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, Rooted, 1.500); + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 45), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Event Player, 45); + } +} + +rule("Sigma: Gravity Well") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Damage(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Event Player, Current Array Element, Barriers Do Not Block LOS)), Event Player, 25); + Set Status(Filtered Array(Players in View Angle(Event Player, Opposite Team Of(Team Of(Event Player)), 90), Is In Line of Sight( + Current Array Element, Event Player, Barriers Do Not Block LOS)), Null, Rooted, 2); + Set Status(Event Player, Null, Invincible, 1); + Play Effect(Event Player, Ring Explosion, Color(Blue), Eye Position(Event Player), 50); + Wait(0.300, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Sigma: Gravity Channels") +{ + event + { + Ongoing - Each Player; + Team 1; + Sigma; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ultimate(Event Player)), Event Player, 150, + Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Wait Until(!Event Player.abilities[12], 99999); + Stop Damage Modification(Event Player.modificationDamage[1]); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Wait(0.700, Abort When False); + Cancel Primary Action(Event Player); + } +} + +rule("Echo: Streamline") +{ + event + { + Ongoing - Each Player; + Team 1; + Echo; + } + + conditions + { + Event Player.abilities[12] == True; + Is Firing Secondary(Event Player) == True; + Is Duplicating(Event Player) == False; + } + + actions + { + Set Projectile Speed(Event Player, 100); + Wait(0.150, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Bomblets") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is Firing Primary(Event Player) == True; + Is In Alternate Form(Event Player) == True; + Event Player.abilities[8] == True; + } + + actions + { + Play Effect(All Players(Team 1), Bad Pickup Effect, Color(Orange), Null + Ray Cast Hit Position(Eye Position(Event Player), + Eye Position(Event Player) + Facing Direction Of(Event Player) * 60, All Living Players(Opposite Team Of(Team Of( + Event Player))), All Players(Team Of(Event Player)), True), 2); + Damage(Players Within Radius(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of( + Event Player) * 60, All Living Players(Opposite Team Of(Team Of(Event Player))), All Players(Team Of(Event Player)), True), 2, + Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 12); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bastion: Taser - Loop damage") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Is True For Any(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive(Current Array Element) + && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status(Current Array Element, + Phased Out) && Distance Between(Event Player, Current Array Element) <= 25) == True; + Is Alive(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Play Effect(All Players(Team 1), Explosion Sound, Color(White), Event Player.abilityPlayer, 80); + Play Effect(All Players(Team 1), Bad Pickup Effect, Color(Aqua), Event Player.abilityPlayer, 1); + Event Player.abilityPlayer = Filtered Array(Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player))), Is Alive( + Current Array Element) && Is In Line of Sight(Event Player, Current Array Element, Barriers Do Not Block LOS) && !Has Status( + Current Array Element, Phased Out) && Distance Between(Event Player, Current Array Element) <= 25); + Damage(Players Within Radius(Event Player.abilityPlayer, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 30); + Wait(0.450, Ignore Condition); + Loop If Condition Is True; + Event Player.abilityPlayer = Null; + } +} + +rule("Bastion: Taser - Visual beam") +{ + event + { + Ongoing - Each Player; + Team 1; + Bastion; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Create Beam Effect(All Players(All Teams), Bad Beam, Event Player + Vector(False, 1, False), + Event Player.abilityPlayer != Null ? Event Player.abilityPlayer : Event Player, Color(Aqua), + Visible To Position Radius and Color); + Event Player.effects_[1] = Last Created Entity; + Wait Until(!Event Player.abilities[12], 99999); + Destroy Effect(Event Player.effects_[1]); + } +} + +rule("Sombra: Malware") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(Opposite Team Of(Team Of(Event Player))), Has Status(Current Array Element, + Hacked) || Current Array Element.fearedUntil >= Total Time Elapsed), All Players(Team Of(Event Player)), 200, + Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Wait Until(!Event Player.abilities[8], 99999); + Stop Damage Modification(Event Player.modificationDamage[1]); + } +} + +rule("Sombra: Glitch") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Event Player.abilityActive = True; + Event Player.abilityPosition = Position Of(Event Player); + Create Effect(All Players(Team 1), Sphere, Color(Purple), Event Player.abilityPosition, 15, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Wait(8, Ignore Condition); + Destroy Effect(Event Player.effects_[1]); + Event Player.abilityActive = False; + } +} + +rule("Sombra: Glitch - Loop") +{ + event + { + Ongoing - Each Player; + Team 1; + Sombra; + } + + conditions + { + Event Player.abilityActive == True; + } + + actions + { + Set Status(Players Within Radius(Event Player.abilityPosition, 15, Opposite Team Of(Team Of(Event Player)), Off), Null, Hacked, + 0.750); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Mei: Cold Snap") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Event Player.abilities[8] == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Create Effect(All Players(Team 1), Bad Aura, Color(Sky Blue), Event Player, 1, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Wait Until(!Is Using Ability 1(Event Player), 99999); + Destroy Effect(Event Player.effects_[1]); + Damage(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Frozen, 2); + Set Status(Players Within Radius(Eye Position(Event Player), 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Rooted, 2); + Play Effect(All Players(Team 1), Ring Explosion, Color(White), Position Of(Event Player), 20); + Play Effect(All Players(Team 1), Ring Explosion, Color(Sky Blue), Position Of(Event Player), 20); + Play Effect(All Players(Team 1), Ring Explosion, Color(Aqua), Position Of(Event Player) + Vector(0, 1, 0), 20); + } +} + +rule("Mei: Icebound") +{ + event + { + Ongoing - Each Player; + Team 1; + Mei; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Is Firing Secondary(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Create Effect(All Players(Team 1), Ring, Color(Aqua), Event Player, 0.400, Visible To Position and Radius); + Event Player.effects_[2] = Last Created Entity; + Set Projectile Speed(Event Player, 200); + Wait Until(!Is Firing Secondary(Event Player), 99999); + Destroy Effect(Event Player.effects_[2]); + Set Projectile Speed(Event Player, 100); + } +} + +rule("Wrecking Ball: Mirror Ball") +{ + event + { + Player Took Damage; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 4.500, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage); + Wait(0.100, Ignore Condition); + } +} + +rule("Wrecking Ball: Distort") +{ + event + { + Ongoing - Each Player; + Team 1; + Wrecking Ball; + } + + conditions + { + Event Player.abilities[12] == True; + Is Using Ability 2(Event Player) == True; + } + + actions + { + Play Effect(All Players(Team 1), Ring Explosion, Color(Purple), Position Of(Event Player), 20); + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 80); + Wait(0.100, Ignore Condition); + Play Effect(All Players(Team 1), Ring Explosion, Color(Violet), Position Of(Event Player), 18); + Set Status(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Null, Hacked, Count Of( + Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces)) * 1.500); + Play Effect(All Players(Team 1), Ring Explosion Sound, Color(Violet), Position Of(Event Player), 125); + Play Effect(All Players(Team 1), Junkrat RIP Tire Explosion Sound, Color(Purple), Position Of(Event Player), 16); + Play Effect(All Players(Team 1), Explosion Sound, Color(Violet), Position Of(Event Player), 80); + } +} + +rule("Symmetra: High voltage") +{ + event + { + Player Dealt Final Blow; + Team 1; + Symmetra; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Wait(0.250, Ignore Condition); + Play Effect(All Players(Team 1), Good Explosion, Color(Blue), Victim, 10); + Play Effect(All Players(Team 1), Bad Explosion, Color(Aqua), Victim, 8); + Damage(Players Within Radius(Victim, 10, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 150); + } +} + +rule("Symmetra: Energy Source") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is True For Any(Players On Hero(Hero(Symmetra), Team Of(Event Player)), Is Using Ultimate(Current Array Element) + && Current Array Element.abilities[12]) == True; + } + + actions + { + Start Heal Over Time(Event Player, Event Player, 1, 40); + Play Effect(All Players(Team 1), Good Explosion, Color(Blue), Event Player, 0.100); + Set Ultimate Charge(Event Player, Ultimate Charge Percent(Event Player) + 2); + Wait(0.900, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Junkrat: Pyromania") +{ + event + { + Player Dealt Knockback; + Team 1; + Junkrat; + } + + conditions + { + Event Player.abilities[8] == True; + Event Ability != Button(Melee); + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 2, 30); + Set Status(Victim, Null, Burning, 2); + } +} + +rule("Zenyatta: Perfect Balance") +{ + event + { + Ongoing - Each Player; + Team 1; + Zenyatta; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Start Damage Over Time(Players Within Radius(Event Player, 12, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 0.750, 200); + Play Effect(All Players(Team 1), Ring Explosion, Color(Orange), Event Player, 24); + Wait(0.600, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Stench") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Create Effect(All Players(Team 1), Ring, Color(Violet), Event Player, 8, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Wait Until(!Event Player.abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Destroy Effect(Event Player.effects_[1]); + } +} + +rule("Roadhog: Stench effect") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Distance Between(Event Player, Closest Player To(Event Player, Opposite Team Of(Team Of(Event Player)))) <= 8; + Event Player.abilities[8] == True; + } + + actions + { + Damage(Players Within Radius(Event Player, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 9); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Roadhog: Rusted Anchor") +{ + event + { + Ongoing - Each Player; + Team 1; + Roadhog; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Start Damage Modification(Filtered Array(All Players(All Teams), Is Using Ability 1(Event Player)), Event Player, 400, + Receivers Damagers and Damage Percent); + Event Player.modificationDamage[1] = Last Damage Modification ID; + Wait Until(!Event Player.abilities[8] || Hero Of(Event Player) != Hero(Roadhog), 99999); + Stop Damage Modification(Event Player.modificationDamage[1]); + } +} + +rule("Roadhog: Rusted Anchor - Reset cooldown") +{ + event + { + Player Earned Elimination; + Team 1; + Roadhog; + } + + conditions + { + Event Player.abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ability 1(Event Player), 3); + Set Ability Cooldown(Event Player, Button(Ability 1), False); + } +} + +rule("Zarya: Augment") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[8] == True; + } + + actions + { + Start Scaling Barriers(Event Player, 2, True); + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5 + 50; + Set Max Health(Event Player, Event Player.playerHealth); + Wait Until(!Event Player.abilities[8] || Hero Of(Event Player) != Hero(Zarya), 99999); + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + Stop Scaling Barriers(Event Player); + } +} + +rule("Zarya: Perpetual Energy") +{ + event + { + Player Dealt Knockback; + Team 1; + Zarya; + } + + conditions + { + Event Ability == Button(Secondary Fire); + Event Player.abilities[12] == True; + Victim != Event Player; + } + + actions + { + Start Damage Over Time(Victim, Event Player, 9999, 15); + Victim.botEffects[5] = Last Damage Over Time ID; + Set Status(Victim, Null, Burning, 9999); + Wait Until(Is Dead(Victim), 9999); + Clear Status(Victim, Burning); + Stop Damage Over Time(Victim.botEffects[5]); + } +} + +rule("Doomfist: Phase Shifter") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + (Is Firing Secondary(Event Player) || Is Using Ability 1(Event Player) || Is Using Ability 2(Event Player)) == True; + Event Player.abilities[8] == True; + } + + actions + { + Set Status(Event Player, Null, Phased Out, 1); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Is Using Ultimate(Event Player) == True; + Event Player.abilities[12] == True; + } + + actions + { + Wait Until(!Is Using Ultimate(Event Player), 99999); + Event Player.abilityPosition = Position Of(Event Player); + Event Player.abilityActive = True; + Wait Until(Is Dead(Event Player), 8); + Event Player.abilityActive = False; + } +} + +rule("Doomfist: Fissure") +{ + event + { + Ongoing - Each Player; + Team 1; + Doomfist; + } + + conditions + { + Event Player.abilityActive == True; + Event Player.abilities[12] == True; + } + + actions + { + Create Effect(All Players(Team 1), Ring, Color(Orange), Event Player.abilityPosition, 8, Visible To Position and Radius); + Event Player.effects_[1] = Last Created Entity; + Create Effect(All Players(Team 1), Cloud, Color(Orange), Event Player.abilityPosition, 8, Visible To Position and Radius); + Event Player.effects_[2] = Last Created Entity; + Play Effect(All Players(Team 1), Ring Explosion, Color(Orange), Event Player.abilityPosition, 16); + While(Event Player.abilityActive == True); + Damage(Players Within Radius(Event Player.abilityPosition, 8, Opposite Team Of(Team Of(Event Player)), Off), Event Player, 34); + Wait(0.235, Ignore Condition); + End; + Destroy Effect(Event Player.effects_[1]); + Destroy Effect(Event Player.effects_[2]); + } +} + +rule("Team 1 (perk): Bulletstorm") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.perk[1] == True; + (Ammo(Event Player, 0) < Max Ammo(Event Player, 0) || Ammo(Event Player, 1) < Max Ammo(Event Player, 1)) == True; + } + + actions + { + Set Ammo(Event Player, 0, 1000); + Set Ammo(Event Player, 1, 1000); + } +} + +rule("Team 1 Challenges") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + If(Global.perk[2] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Up You Go"), Left, 917, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.abilityHUD[17] = Last Text ID; + End; + If(Global.perk[0] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Sharpshooter"), Left, 918, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.abilityHUD[18] = Last Text ID; + End; + If(Global.perk[1] == 1); + Create HUD Text(Event Player, Null, Null, Custom String("Bulletstorm"), Left, 919, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Event Player.abilityHUD[19] = Last Text ID; + End; + If(Global.maxHealthDone == 50); + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + End; + } +} + +rule("Stuff to do when Player leaves") +{ + event + { + Player Left Match; + Team 1; + All; + } + + actions + { + Global.automaticRepair -= Event Player.abilities[16]; + } +} + +rule("Refund") +{ + event + { + Subroutine; + Refund; + } + + actions + { + "Refund Money" + Event Player.money[0] += Event Player.money[1]; + Event Player.money[1] = 0; + "Reset Headhunter" + Event Player.abilities[1] = 0; + "Reset Ambush" + Event Player.abilities[2] = 0; + "Reset QuickFix" + Event Player.abilities[3] = 0; + "Reset HeavyWeight" + Event Player.abilities[4] = 0; + "Reset Charged" + Event Player.abilities[5] = 0; + "Reset Haste" + Event Player.abilities[6] = 0; + "Reset HeavyImpact" + Event Player.abilities[7] = 0; + "Reset HeroTalent1" + Event Player.abilities[8] = 0; + "Reset SecondWind" + Event Player.abilities[9] = 0; + "Reset BindingHeal" + Event Player.abilities[10] = 0; + "Reset Resilience" + Event Player.abilities[11] = 0; + "Reset HeroTalent2" + Event Player.abilities[12] = 0; + "Reset Damage" + Event Player.abilities[13] = 0; + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.damageDealt); + "Reset Health" + Event Player.abilities[14] = 0; + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + If(Global.maxHealthDone == 0); + End; + "Reset Healing" + Event Player.abilities[15] = 0; + Set Healing Dealt(Event Player, 100 + Event Player.abilities[15] * 5); + "Reset automaticRepair" + Global.automaticRepair -= Event Player.abilities[16]; + Event Player.abilities[16] = 0; + } +} + +rule("Lucio Dash HUD Creation") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + } + + actions + { + If(Event Player.lucioDashActive == False); + Event Player.lucioDashActive = True; + Create HUD Text(Event Player, Null, Null, Custom String("{0} Slam on ground - Press: {1}", Ability Icon String(Hero(Wrecking Ball), + Button(Crouch)), Input Binding String(Button(Crouch))), Left, 1000, Color(White), Color(White), Color(White), + Visible To and String, Default Visibility); + Event Player.lucioDashIcon = Last Text ID; + End; + } +} + +rule("Lucio Dash Remove HUD") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) != Hero(Lúcio); + Event Player.lucioDashActive == True; + } + + actions + { + Destroy HUD Text(Event Player.lucioDashIcon); + Event Player.lucioDashActive = False; + } +} + +rule("Lucio Dash") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Hero Of(Event Player) == Hero(Lúcio); + Event Player.lucioDashActive == True; + Is On Ground(Event Player) == False; + Is Button Held(Event Player, Button(Crouch)) == True; + } + + actions + { + Apply Impulse(Event Player, Down, 20, To World, Cancel Contrary Motion); + } +} + +rule("Ana Self-Nano") +{ + event + { + Ongoing - Each Player; + Team 1; + Ana; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + Ultimate Charge Percent(Event Player) == 100; + Is Dummy Bot(Event Player) == False; + } + + actions + { + Abort If(Global.selfNanoWorkshopSetting == False && Number Of Players(Team 1) > 1); + Wait(0.100, Ignore Condition); + If(Is Using Ultimate(Event Player) == False); + Create Dummy Bot(Hero(Ana), Team Of(Event Player), -1, Position Of(Event Player) + Backward, Eye Position(Event Player)); + Event Player.anaEntityID = Last Created Entity; + Wait(0.100, Ignore Condition); + Set Ultimate Charge(Event Player.anaEntityID, 100); + Start Facing(Event Player.anaEntityID, Direction Towards(Eye Position(Event Player.anaEntityID), Position Of(Event Player) + Up), + 1000, To World, Direction and Turn Rate); + Set Invisible(Event Player.anaEntityID, All); + Set Status(Event Player.anaEntityID, Null, Phased Out, 9999); + Wait(0.150, Ignore Condition); + Press Button(Event Player.anaEntityID, Button(Ultimate)); + Set Ultimate Charge(Event Player, 0); + Wait(0.150, Ignore Condition); + Teleport(Event Player.anaEntityID, Position Of(First Of(Spawn Points(Team Of(Event Player))))); + Wait(10, Ignore Condition); + Destroy Dummy Bot(Team Of(Event Player), Slot Of(Event Player.anaEntityID)); + End; + } +} + +disabled rule("Map Editor Walls") +{ + event + { + Ongoing - Global; + } +} + +rule("Initial Global") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.allPositions = Empty Array; + Global.allDirections = Empty Array; + Global.firstPosition = Empty Array; + Global.secondPosition = Empty Array; + Global.firstPoint = Empty Array; + Global.secondPoint = Empty Array; + Global.second = Empty Array; + Global.z = Empty Array; + Global.wallId = Empty Array; + Global.beamType = Empty Array; + } +} + +rule("Initial Player") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + actions + { + Event Player.filterPosition = 0; + Event Player.lastSavedPosition = 0; + Event Player.closestBodyPosition = 0; + Event Player.fullBodyPosition = 0; + Event Player.previousPositionIntersection = 0; + Event Player.activeWall = Empty Array; + Event Player.closestWall = Empty Array; + } +} + +rule("Collision Logic") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + } + + actions + { + Event Player.lastSavedPosition = (Eye Position(Event Player) + Position Of(Event Player)) / 2; + Wait(0.100, Ignore Condition); + Event Player.closestWall = Filtered Array(Global.allPositions, Distance Between(Global.allPositions[Current Array Index], + Event Player) <= Distance Between(Global.allPositions[Current Array Index], Global.firstPosition[Current Array Index]) + || Event Player.activeWall[Current Array Index] == 1 || (Dot Product(Direction Towards(Current Array Element, + Event Player.lastSavedPosition), Global.allDirections[Current Array Index]) > 0) != (Dot Product(Direction Towards( + Current Array Element, Event Player), Global.allDirections[Current Array Index]) > 0)); + For Player Variable(Event Player, x, 0, Count Of(Event Player.closestWall), 1); + Global.z = Index Of Array Value(Global.allPositions, Event Player.closestWall[Event Player.x]); + If(Global.wallId[Global.z] == 1 || Global.wallId[Global.z] == 3 || Global.wallId[Global.z] == 5); + If(Y Component Of(Global.firstPosition[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.firstPosition[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestBodyPosition = Global.firstPosition[Global.z]; + Else If(Y Component Of(Global.secondPosition[Global.z]) >= Y Component Of(Position Of(Event Player)) && Y Component Of( + Global.secondPosition[Global.z]) <= Y Component Of(Eye Position(Event Player) + Vector(Empty Array, 0.200, Empty Array))); + Event Player.closestBodyPosition = Global.secondPosition[Global.z]; + Else; + Event Player.closestBodyPosition = Position Of(Event Player); + End; + Event Player.fullBodyPosition = Vector(X Component Of(Eye Position(Event Player)), Y Component Of( + Event Player.closestBodyPosition), Z Component Of(Eye Position(Event Player))); + Event Player.filterPosition = Event Player.fullBodyPosition + Global.allDirections[Global.z] * Dot Product( + Global.allPositions[Global.z] - Event Player.fullBodyPosition, Global.allDirections[Global.z]) / Dot Product( + Global.allDirections[Global.z], Global.allDirections[Global.z]); + If(Global.wallId[Global.z] == 1 || Global.wallId[Global.z] == 3); + If((Dot Product(Direction Towards(Global.allPositions[Global.z], Event Player.lastSavedPosition), Global.allDirections[Global.z]) + > 0) != (Dot Product(Direction Towards(Global.allPositions[Global.z], Event Player.fullBodyPosition), + Global.allDirections[Global.z]) > 0)); + Event Player.intersectionLength = Dot Product(Global.allPositions[Global.z] - Event Player.fullBodyPosition, + Global.allDirections[Global.z]) / Dot Product(Direction Towards(Event Player.lastSavedPosition, Event Player.fullBodyPosition), + Global.allDirections[Global.z]); + Event Player.previousPositionIntersection = Event Player.fullBodyPosition + Direction Towards(Event Player.lastSavedPosition, + Event Player.fullBodyPosition) * Vector(1, Empty Array, 1) * Event Player.intersectionLength; + If(Dot Product(Direction Towards(Global.firstPosition[Global.z], Vector(X Component Of(Global.secondPosition[Global.z]), + Y Component Of(Global.firstPosition[Global.z]), Z Component Of(Global.secondPosition[Global.z]))), Direction Towards( + Global.firstPosition[Global.z], Event Player.previousPositionIntersection)) >= 0 && Dot Product(Direction Towards( + Global.firstPosition[Global.z], Vector(X Component Of(Global.firstPosition[Global.z]), Y Component Of( + Global.secondPosition[Global.z]), Z Component Of(Global.firstPosition[Global.z]))), Direction Towards( + Global.firstPosition[Global.z], Event Player.previousPositionIntersection)) >= 0 && Dot Product(Direction Towards( + Global.secondPosition[Global.z], Vector(X Component Of(Global.secondPosition[Global.z]), Y Component Of( + Global.firstPosition[Global.z]), Z Component Of(Global.secondPosition[Global.z]))), Direction Towards( + Global.secondPosition[Global.z], Event Player.previousPositionIntersection)) >= 0 && Dot Product(Direction Towards( + Global.secondPosition[Global.z], Vector(X Component Of(Global.firstPosition[Global.z]), Y Component Of( + Global.secondPosition[Global.z]), Z Component Of(Global.firstPosition[Global.z]))), Direction Towards( + Global.secondPosition[Global.z], Event Player.previousPositionIntersection)) >= 0); + Cancel Primary Action(Event Player); + Teleport(Event Player, Event Player.previousPositionIntersection + Direction Towards(Event Player.previousPositionIntersection, + Event Player.lastSavedPosition) * Vector(1, Empty Array, 1) * 2); + End; + End; + End; + Event Player.thickness = 0; + If(Global.wallId[Global.z] == 5); + Event Player.thickness = 4; + Else; + Event Player.thickness = 1; + End; + If(Distance Between(Event Player.fullBodyPosition, Event Player.filterPosition) <= Event Player.thickness && Dot Product( + Direction Towards(Global.firstPosition[Global.z], Vector(X Component Of(Global.secondPosition[Global.z]), Y Component Of( + Global.firstPosition[Global.z]), Z Component Of(Global.secondPosition[Global.z]))), Direction Towards( + Global.firstPosition[Global.z], Event Player.filterPosition)) >= 0 && Dot Product(Direction Towards( + Global.firstPosition[Global.z], Vector(X Component Of(Global.firstPosition[Global.z]), Y Component Of( + Global.secondPosition[Global.z]), Z Component Of(Global.firstPosition[Global.z]))), Direction Towards( + Global.firstPosition[Global.z], Event Player.filterPosition)) >= 0 && Dot Product(Direction Towards( + Global.secondPosition[Global.z], Vector(X Component Of(Global.secondPosition[Global.z]), Y Component Of( + Global.firstPosition[Global.z]), Z Component Of(Global.secondPosition[Global.z]))), Direction Towards( + Global.secondPosition[Global.z], Event Player.filterPosition)) >= 0 && Dot Product(Direction Towards( + Global.secondPosition[Global.z], Vector(X Component Of(Global.firstPosition[Global.z]), Y Component Of( + Global.secondPosition[Global.z]), Z Component Of(Global.firstPosition[Global.z]))), Direction Towards( + Global.secondPosition[Global.z], Event Player.filterPosition)) >= 0); + If(!Global.isGrounded); + Set Gravity(Event Player, 100); + End; + If(Event Player.activeWall[Global.z] == False); + Event Player.activeWall[Global.z] = 1; + If((Global.wallId[Global.z] == 1 || Global.wallId[Global.z] == 3) && Global.isGrounded == False); + Set Gravity(Event Player, 100); + Else If(Global.wallId[Global.z] == 5); + Disable Movement Collision With Environment(Event Player, False); + End; + End; + If(Global.wallId[Global.z] == 1); + Apply Impulse(Event Player, Direction Towards(Event Player.filterPosition, Event Player.fullBodyPosition) * Vector(1, Empty Array, + 1), 0.001, To World, Cancel Contrary Motion); + Set Move Speed(Event Player, 100 - Dot Product(Direction Towards(Eye Position(Event Player), Eye Position(Event Player) + + World Vector Of(Throttle Of(Event Player), Event Player, Rotation)), Direction Towards(Event Player.filterPosition, + Event Player.fullBodyPosition) * -1) * 100); + Else If(Global.wallId[Global.z] == 3); + Apply Impulse(Event Player, Direction Towards(Event Player.filterPosition, Event Player.fullBodyPosition), Speed Of(Event Player), + To World, Cancel Contrary Motion); + End; + Else; + Event Player.activeWall[Global.z] = 0; + Set Move Speed(Event Player, 100); + End; + End; + End; + Loop; + } +} + +rule("Reset") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Count Of(Filtered Array(Event Player.activeWall, Current Array Element != 0)) == 0; + } + + actions + { + Enable Movement Collision With Environment(Event Player); + } +} + +rule("Wall Data") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.allPositions = Array(Vector(155.968, 12.470, -30.507), Vector(155.962, 12.472, -62.500), Vector(81.153, 6.453, -103.851), + Vector(69.148, 6.474, -104.548)); + Global.allDirections = Array(Vector(-1, 0, -0.002), Vector(1, 0, -0.001), Vector(0, 0, 1), Vector(0.001, 0, 1)); + Global.firstPosition = Array(Vector(155.971, 11.047, -31.771), Vector(155.964, 11.050, -61.229), Vector(79.761, 5.030, -103.852), + Vector(67.738, 5.022, -104.547)); + Global.secondPosition = Array(Vector(155.965, 13.894, -29.242), Vector(155.960, 13.894, -63.771), Vector(82.544, 7.876, -103.851), + Vector(70.558, 7.925, -104.550)); + Global.firstPoint = Array(Vector(155.971, 13.894, -31.771), Vector(155.964, 13.894, -61.229), Vector(79.761, 7.876, -103.852), + Vector(67.738, 7.925, -104.547)); + Global.secondPoint = Array(Vector(155.965, 11.047, -29.242), Vector(155.960, 11.050, -63.771), Vector(82.544, 5.030, -103.851), + Vector(70.558, 5.022, -104.550)); + Global.z = 3; + Global.beamType = Array(1, 1, 1, 1); + Global.showWalls = True; + Global.wallId = Array(5, 5, 5, 5); + } +} + +disabled rule("NEW SHOP") +{ + event + { + Ongoing - Global; + } +} + +rule("Setting Shop Position") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.shopCamPosition = 900 * Up; + Global.shopPositionAngle[1] = Direction From Angles(Horizontal Angle From Direction(Forward), Vertical Angle From Direction( + Forward) - 90); + Global.shopPositionAngle[0] = Cross Product(Global.shopPositionAngle[1], Forward); + Global.shopBasePosition = Global.shopCamPosition - 9 * Global.shopPositionAngle[1] + 142 * Forward; + } +} + +rule("Create Shop Buttons") +{ + event + { + Ongoing - Global; + } + + actions + { + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), + Global.shopBasePosition - 41 * Global.shopPositionAngle[1] + 90 * Global.shopPositionAngle[0], 2.500, Do Not Clip, Visible To, + Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃"), + Global.shopBasePosition - 41 * Global.shopPositionAngle[1] - 90 * Global.shopPositionAngle[0], 2.500, Do Not Clip, Visible To, + Color(White), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Refund"), + Global.shopBasePosition + 45 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 3, Do Not Clip, Visible To, + Color(Green), Default Visibility); + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("[{0}] Leave", + Input Binding String(Button(Reload))), + Global.shopBasePosition + 45 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 3, Do Not Clip, + Visible To and String, Color(Green), Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("{0}$\n", Local Player.money[0]), + Global.shopBasePosition + 36.500 * Global.shopPositionAngle[1], 3, Do Not Clip, Visible To and String, Color(White), + Default Visibility); + Create In-World Text(Local Player.isInMenu ? Local Player : Empty Array, Custom String("▲"), Update Every Frame( + Global.shopBasePosition - (4 + Vertical Facing Angle Of(Local Player)) + * Global.shopPositionAngle[1] + Horizontal Facing Angle Of(Local Player) * Global.shopPositionAngle[0]), 4, Do Not Clip, + Visible To Position and Color, Custom Color(245 + 10 * Sine From Radians(4 * Total Time Elapsed), 205 + 50 * Sine From Radians( + 4 * Total Time Elapsed), 200 * Sine From Radians(4 * Total Time Elapsed), 255), Default Visibility); + "Headhunter" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[1] ? Custom String("Headhunter II\n  800$") : Custom String("Headhunter I\n  800$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[1] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Ambush" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[2] ? Custom String("Ambush II\n 800$") : Custom String("Ambush I\n 800$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[2] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Quick Fix" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[3] ? Custom String("Quick Fix II\n  700$") : Custom String("Quick Fix I\n  700$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[3] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavyweight" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[4] ? Custom String("Heavyweight II\n  1000$") : Custom String("Heavyweight I\n  1000$"), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] + 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[4] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Charged" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[5] ? Custom String("Charged II\n  700$") : Custom String("Charged I\n  700$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[5] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Haste" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[6] ? Custom String("Haste II\n 700$") : Custom String("Haste I\n 700$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[6] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Heavy Impact" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[7] ? Custom String("Heavy Impact II\n  1000$") : Custom String("Heavy Impact I\n  1000$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[7] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 1" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 1\n  1200$"), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] + 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[8] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "Second Wind" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[9] ? Custom String("Second Wind II\n   900$") : Custom String("Second Wind I\n   900$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[9] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Binding Heal" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[10] ? Custom String("Binding Heal II\n   700$") : Custom String("Binding Heal I\n   700$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[10] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Resilience" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), + Local Player.abilities[11] ? Custom String("Resilience II\n  800$") : Custom String("Resilience I\n  800$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[11] < 2 ? Color(Green) : Color(Gray), Default Visibility); + "Hero Talent 2" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("Hero Talent 2\n  1200$"), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] - 22.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Local Player.abilities[12] < 1 ? Color(Green) : Color(Gray), Default Visibility); + "PlusDamage" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Damage\n  400$"), + Global.shopBasePosition + 20 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealth" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Health\n 400$"), + Global.shopBasePosition - 2.500 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String("+5% Healing\n  400$"), + Global.shopBasePosition - 25 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To and String, Color(Green), Default Visibility); + "PlusHealing" + Create In-World Text(Filtered Array(All Players(Team 1), Current Array Element.isInMenu), Custom String( + "+{0} Auto-Repair\n    400$", Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Global.shopBasePosition - 47.500 * Global.shopPositionAngle[1] - 67.500 * Global.shopPositionAngle[0], 2.500, Do Not Clip, + Visible To String and Color, Global.automaticRepair < 5 ? Color(Green) : Color(Gray), Default Visibility); + "Use Update Every Frame to avoid showing the String when the cursor is out of bounds, resulting in 0\r\n ROW 0" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -33.750 ? Array(Custom String("Leave Buy Menu\n"), Custom String( + ""), Custom String(""), Custom String("Refund your money\n"))[Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) + / 45, Down)] : Custom String("")), Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, + Visible To and String, Color(White), Default Visibility); + "ROW 1" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) + 11.250) < 22.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < -11.250 ? Array(Custom String("Increase your damage by 5%\n"), + Local Player.abilities[9] ? Custom String( + "Second Wind II: 60% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds") + : Custom String( + "Second Wind I: 30% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds"), + Local Player.abilities[5] ? Custom String("Charged II: Ultimates cost 40% less\n") : Custom String( + "Charged I: Ultimates cost 20% less\n"), Local Player.abilities[1] ? Custom String( + "Headhunter II: Critical hits deal 80% more damage\n") : Custom String("Headhunter I: Critical hits deal 40% more damage\n")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), + Default Visibility); + "ROW 2" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 36.250) < 47.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 11.250 ? Array(Custom String("Increase your health by 5%\n"), + Local Player.abilities[10] ? Custom String("Binding Heal II: Heal yourself for 50% the amount when healing allies\n") + : Custom String("Binding Heal I: Heal yourself for 25% the amount when healing allies\n"), + Local Player.abilities[6] ? Custom String( + " Haste II: Ability cooldown is reduced by 50%\nDoes not affect abilities with multiple charges") : Custom String( + " Haste I: Ability cooldown is reduced by 25%\nDoes not affect abilities with multiple charges"), + Local Player.abilities[2] ? Custom String("Ambush II: Deal 60% more damage when attacking enemies from behind or above\n") + : Custom String("Ambush I: Deal 30% more damage when attacking enemies from behind or above\n"))[Round To Integer(( + Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), + Default Visibility); + "ROW 3" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 83.750) < 72.500 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 33.750 ? Array(Custom String("Increase your healing by 5%\n"), + Local Player.abilities[11] ? Custom String("Resilience II: Take 30% less damage while below 60% health\n") : Custom String( + "Resilience I: Take 30% less damage while below 30% health\n"), Local Player.abilities[7] ? Custom String( + "Heavy Impact II: Every hit has a chance to stun the enemy for 2 seconds\n") : Custom String( + "Heavy Impact I: Every hit has a chance to stun the enemy for 1 second\n"), Local Player.abilities[3] ? Custom String( + "Quick Fix II: Eliminations restore 100 HP and shortly increase speed by 40%\n") : Custom String( + "Quick Fix I: Eliminations restore 50 HP and shortly increase speed by 20%\n"))[Round To Integer((Horizontal Facing Angle Of( + Local Player) + 90) / 45, Down)] : Custom String("")), Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, + Do Not Clip, Visible To and String, Color(White), Default Visibility); + "ROW 4" + Create In-World Text(Update Every Frame(Local Player.isInMenu && Absolute Value(Horizontal Facing Angle Of(Local Player)) + < 90 && Absolute Value(Vertical Facing Angle Of(Local Player) - 133) < 99.250 ? Local Player : Empty Array), + Update Every Frame(Vertical Facing Angle Of(Local Player) < 56.250 ? Array(Custom String( + "Increase your auto-repair by {0}/5s\n", Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 10 : 5), + Custom String("{0}", Local Player.heroTalentText[2][1]), Custom String("{0}", Local Player.heroTalentText[1][1]), + Local Player.abilities[4] ? Custom String( + "Heavyweight II: Your knock back attacks deal 50% more damage and knock back\n            You receive 33% less knock back") + : Custom String( + "Heavyweight I: Your knock back attacks deal 25% more damage and knock back\n            You receive 20% less knock back")) + [Round To Integer((Horizontal Facing Angle Of(Local Player) + 90) / 45, Down)] : Custom String("")), + Global.shopBasePosition - 75 * Global.shopPositionAngle[1], 2.500, Do Not Clip, Visible To and String, Color(White), + Default Visibility); + } +} + +rule("Toggle Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + !Is Dummy Bot(Event Player) == True; + Is Button Held(Event Player, Button(Reload)) == True; + !Is Communicating Any Emote(Event Player) == True; + } + + actions + { + If(Event Player.isInMenu == False); + Wait Until(!Is Button Held(Event Player, Button(Reload)), 0.500); + If(!Is Button Held(Event Player, Button(Reload))); + Abort; + End; + End; + Event Player.isInMenu = !Event Player.isInMenu; + } +} + +rule("Open Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + } + + actions + { + Event Player.playerFacing = Facing Direction Of(Event Player); + Start Camera(Event Player, Global.shopCamPosition, Global.shopCamPosition + Forward, 0); + Disable Hero HUD(Event Player); + Call Subroutine(DisablePlayer); + Set Aim Speed(Event Player, 200); + } +} + +rule("Close Shop") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == False; + } + + actions + { + Stop Camera(Event Player); + Enable Hero HUD(Event Player); + Call Subroutine(EnablePlayer); + Set Aim Speed(Event Player, 100); + Set Facing(Event Player, Event Player.playerFacing, To World); + } +} + +rule("Subroutine: Disable Player") +{ + event + { + Subroutine; + DisablePlayer; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + Set Primary Fire Enabled(Event Player, False); + Set Secondary Fire Enabled(Event Player, False); + Set Ability 1 Enabled(Event Player, False); + Set Ability 2 Enabled(Event Player, False); + Set Melee Enabled(Event Player, False); + Set Jump Enabled(Event Player, False); + Set Crouch Enabled(Event Player, False); + Disallow Button(Event Player, Button(Ultimate)); + } +} + +rule("Subroutine: Enable Player") +{ + event + { + Subroutine; + EnablePlayer; + } + + actions + { + Stop Forcing Throttle(Event Player); + Set Primary Fire Enabled(Event Player, True); + Set Secondary Fire Enabled(Event Player, True); + Set Ability 1 Enabled(Event Player, True); + Set Ability 2 Enabled(Event Player, True); + Set Melee Enabled(Event Player, True); + Set Jump Enabled(Event Player, True); + Set Crouch Enabled(Event Player, True); + Allow Button(Event Player, Button(Ultimate)); + } +} + +rule("Buy Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Primary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + Event Player.isInMenu = !Event Player.isInMenu; + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.money[1] != 0); + Call Subroutine(Refund); + Else; + Small Message(Local Player, Custom String("You don't have anything to refund!")); + End; + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Event Player.abilities[13] += 1; + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.damageDealt); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[9] != 2); + If(Event Player.money[0] >= 900); + Event Player.money[0] -= 900; + Event Player.money[1] += 900; + Event Player.abilities[9] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[5] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[5] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[1] != 2); + If(Event Player.money[0] >= 800); + Event Player.money[0] -= 800; + Event Player.money[1] += 800; + Event Player.abilities[1] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Event Player.abilities[14] += 1; + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[10] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[10] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[6] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[6] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[2] != 2); + If(Event Player.money[0] >= 800); + Event Player.money[0] -= 800; + Event Player.money[1] += 800; + Event Player.abilities[2] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Event Player.abilities[15] += 1; + Set Healing Dealt(Event Player, 100 + Event Player.abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[11] != 2); + If(Event Player.money[0] >= 800); + Event Player.money[0] -= 800; + Event Player.money[1] += 800; + Event Player.abilities[11] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[7] != 2); + If(Event Player.money[0] >= 1000); + Event Player.money[0] -= 1000; + Event Player.money[1] += 1000; + Event Player.abilities[7] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[3] != 2); + If(Event Player.money[0] >= 700); + Event Player.money[0] -= 700; + Event Player.money[1] += 700; + Event Player.abilities[3] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Global.automaticRepair != 5); + If(Event Player.money[0] >= 400); + Event Player.money[0] -= 400; + Event Player.money[1] += 400; + Global.automaticRepair += 1; + Event Player.abilities[16] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[12] != 1); + If(Event Player.money[0] >= 1200); + Event Player.money[0] -= 1200; + Event Player.money[1] += 1200; + Event Player.abilities[12] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[8] != 1); + If(Event Player.money[0] >= 1200); + Event Player.money[0] -= 1200; + Event Player.money[1] += 1200; + Event Player.abilities[8] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[4] != 2); + If(Event Player.money[0] >= 1000); + Event Player.money[0] -= 1000; + Event Player.money[1] += 1000; + Event Player.abilities[4] += 1; + Else; + Small Message(Event Player, Custom String("Not enough money!")); + End; + End; + End; + End; + } +} + +rule("Refund Single Ability") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.isInMenu == True; + Is Button Held(Event Player, Button(Secondary Fire)) == True; + (Absolute Value(Horizontal Facing Angle Of(Event Player)) < 90 && Absolute Value(Vertical Facing Angle Of(Event Player)) + + 11.250 < 67) == True; + } + + actions + { + "ROW 0" + If(Vertical Facing Angle Of(Event Player) < -33.750); + "LEAVE SHOP" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + "REFUND" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + End; + "ROW 1" + Else If(Vertical Facing Angle Of(Event Player) < -11.250); + "+5% DAMAGE" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[13] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Event Player.abilities[13] -= 1; + Event Player.damageDealt = 100 + Global.damageDealt + Event Player.abilities[13] * 5; + Set Damage Dealt(Event Player, Event Player.damageDealt); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "SECOND WIND" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[9] != 0); + Event Player.money[0] += 900; + Event Player.money[1] -= 900; + Event Player.abilities[9] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "CHARGED" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[5] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[5] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEADHUNTER" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[1] != 0); + Event Player.money[0] += 800; + Event Player.money[1] -= 800; + Event Player.abilities[1] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 2" + Else If(Vertical Facing Angle Of(Event Player) < 11.250); + "+5% HEALTH" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[14] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Event Player.abilities[14] -= 1; + Event Player.playerHealth = 100 + Global.maxHealthDone + Event Player.abilities[14] * 5; + Set Max Health(Event Player, Event Player.playerHealth); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "BINDING HEAL" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[10] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[10] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HASTE" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[6] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[6] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "AMBUSH" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[2] != 0); + Event Player.money[0] += 800; + Event Player.money[1] -= 800; + Event Player.abilities[2] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 3" + Else If(Vertical Facing Angle Of(Event Player) < 33.750); + "+5% HEALING" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[15] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Event Player.abilities[15] -= 1; + Set Healing Dealt(Event Player, 100 + Event Player.abilities[15] * 5); + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "RESILIENCE" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[11] != 0); + Event Player.money[0] += 800; + Event Player.money[1] -= 800; + Event Player.abilities[11] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVY IMPACT" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[7] != 0); + Event Player.money[0] += 1000; + Event Player.money[1] -= 1000; + Event Player.abilities[7] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "QUICK FIX" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[3] != 0); + Event Player.money[0] += 700; + Event Player.money[1] -= 700; + Event Player.abilities[3] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + "ROW 4" + Else If(Vertical Facing Angle Of(Event Player) < 56.250); + "+5 AUTO-REPAIR" + If(Horizontal Facing Angle Of(Event Player) + 99.750 < 55); + If(Event Player.abilities[16] != 0); + Event Player.money[0] += 400; + Event Player.money[1] -= 400; + Global.automaticRepair -= 1; + Event Player.abilities[16] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 2" + Else If(Horizontal Facing Angle Of(Event Player) + 22.500 < 22.500); + If(Event Player.abilities[12] != 0); + Event Player.money[0] += 1200; + Event Player.money[1] -= 1200; + Event Player.abilities[12] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HERO TALENT 1" + Else If(Horizontal Facing Angle Of(Event Player) + 11.250 < 56); + If(Event Player.abilities[8] != 0); + Event Player.money[0] += 1200; + Event Player.money[1] -= 1200; + Event Player.abilities[8] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + "HEAVYWEIGHT" + Else If(Horizontal Facing Angle Of(Event Player) + 0 > 45); + If(Event Player.abilities[4] != 0); + Event Player.money[0] += 1000; + Event Player.money[1] -= 1000; + Event Player.abilities[4] -= 1; + Else; + Small Message(Event Player, Custom String("You don't have that ability!")); + End; + End; + End; + } +} + +rule("Create Player HUD") +{ + event + { + Player Joined Match; + Team 1; + All; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("{0}", Hero Icon String(Hero Of(Event Player))), Custom String("{0}{1}", + Event Player, Event Player.isInMenu ? Custom String("(In Shop)") : Custom String("")), Custom String("{0}{1}", Is Alive( + Event Player) ? Custom String("{0} HP", Round To Integer(Health(Event Player), Up)) : Custom String("Dead"), Custom String( + ", {0}$", Event Player.money)), Left, Local Player == Event Player ? -1 : Slot Of(Event Player), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), Is Dead(Event Player) ? Color( + Red) : (Health(Event Player) > Max Health(Event Player) * 0.500 ? Color(Green) : Color(Orange)), + Visible To Sort Order String and Color, Default Visibility); + Create HUD Text(Event Player.abilities[13] || Global.damageDealt ? Event Player : Null, Null, Null, Custom String("+{0}% Damage", + Global.damageDealt + Event Player.abilities[13] * 5), Left, 913, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[9] ? Event Player : Null, Null, Null, Custom String("Second Wind {0}", + Event Player.abilities[9] == 1 ? Custom String("I") : Custom String("II")), Left, 908, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[5] ? Event Player : Null, Null, Null, Custom String("Charged {0}", + Event Player.abilities[5] == 1 ? Custom String("I") : Custom String("II")), Left, 905, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[1] ? Event Player : Null, Null, Null, Custom String("Headhunter {0}", + Event Player.abilities[1] == 1 ? Custom String("I") : Custom String("II")), Left, 901, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[14] || Global.maxHealthDone ? Event Player : Null, Null, Null, Custom String("+{0}% Health", + Global.maxHealthDone + Event Player.abilities[14] * 5), Left, 914, Color(White), Color(White), Color(Turquoise), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[10] ? Event Player : Null, Null, Null, Custom String("Binding Heal {0}", + Event Player.abilities[10] == 1 ? Custom String("I") : Custom String("II")), Left, 909, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[6] ? Event Player : Null, Null, Null, Custom String("Haste {0}", + Event Player.abilities[6] == 1 ? Custom String("I") : Custom String("II")), Left, 906, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[2] ? Event Player : Null, Null, Null, Custom String("Ambush {0}", + Event Player.abilities[2] == 1 ? Custom String("I") : Custom String("II")), Left, 902, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[15] ? Event Player : Null, Null, Null, Custom String("+{0}% Healing", + Event Player.abilities[15] * 5), Left, 915, Color(White), Color(White), Color(Turquoise), Visible To and String, + Default Visibility); + Create HUD Text(Event Player.abilities[11] ? Event Player : Null, Null, Null, Custom String("Resilience {0}", + Event Player.abilities[11] == 1 ? Custom String("I") : Custom String("II")), Left, 910, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[7] ? Event Player : Null, Null, Null, Custom String("Heavy Impact {0}", + Event Player.abilities[7] == 1 ? Custom String("I") : Custom String("II")), Left, 907, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[3] ? Event Player : Null, Null, Null, Custom String("Quick Fix {0}", + Event Player.abilities[3] == 1 ? Custom String("I") : Custom String("II")), Left, 903, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Global.automaticRepair ? Event Player : Null, Null, Null, Custom String("{0} total Auto-Repair/5s", + Global.automaticRepair * (Global.upgradeGateMaxHealthValue >= Global.upgradeGateMaxHealthMaxValue[2] ? 10 : 5)), Left, 916, + Color(White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[12] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.heroTalentText[2][0], Event Player.heroTalentText[2][1]), Top, 902, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[12] ? Event Player : Null, Null, Null, Custom String("Hero Talent 2"), Left, 912, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[8] ? Event Player : Null, Null, Null, Custom String("{0} {1}", + Event Player.heroTalentText[1][0], Event Player.heroTalentText[1][1]), Top, 901, Color(White), Color(White), Color(Green), + Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[8] ? Event Player : Null, Null, Null, Custom String("Hero Talent 1"), Left, 911, Color( + White), Color(White), Color(Turquoise), Visible To and String, Default Visibility); + Create HUD Text(Event Player.abilities[4] ? Event Player : Null, Null, Null, Custom String("Heavyweight {0}", + Event Player.abilities[4] == 1 ? Custom String("I") : Custom String("II")), Left, 904, Color(White), Color(White), Color( + Turquoise), Visible To and String, Default Visibility); + } +} + +rule("Boss Rotation") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.activeBoss == True; + } + + actions + { + If(Global.bossRotation == 0 || Global.bossRotation == 3); + Global.bossRotation = 1; + Global.lastBoss[1] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 1); + Global.bossRotation = 2; + Global.lastBoss[2] = Hero Of(Global.activeBoss); + Else If(Global.bossRotation == 2); + Global.bossRotation = 3; + Global.lastBoss[3] = Hero Of(Global.activeBoss); + End; + } +} + +rule("BOSS HUD") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.timeMinutes == 10; + } + + actions + { + Create HUD Text(All Players(Team 1), Global.activeBoss ? Custom String("Boss: {0}, HP: {1}/{2}", Hero Of(Global.activeBoss), + Health(Global.activeBoss), Max Health(Global.activeBoss)) : Custom String(""), Null, Null, Top, 900, Color(Red), Color(White), + Color(White), Visible To and String, Default Visibility); + } +} + +rule("DEBUG - SKIP TIME") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.isDebug == True; + (Is Button Held(Event Player, Button(Primary Fire)) && Is Button Held(Event Player, Button(Crouch))) == True; + } + + actions + { + Global.timeSeconds = 59; + } +} + +disabled rule("DEBUG COLLECTION - Make Invincible, Show Player Coords") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Global.isDebug == True; + } + + actions + { + Create HUD Text(Local Player, Custom String("{0}", Position Of(Local Player)), Null, Null, Left, 0, Color(Yellow), Color(White), + Color(White), Visible To and String, Default Visibility); + Set Status(Event Player, Null, Invincible, 9999); + Set Status(Event Player, Null, Phased Out, 9999); + } +} + +rule("OPTIONAL ENDING - CREATE EXFIL POINT") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + } + + actions + { + Create HUD Text(All Players(Team 1), Custom String("Exfiltration available! (optional - ends the mode)"), Null, Null, Top, 50, + Color(Red), Color(White), Color(White), Visible To and String, Default Visibility); + Global.globalHUDs[1] = Last Text ID; + Create In-World Text(All Players(Team 1), Custom String( + "Exfiltration available! Gather here!\n{0}/{1} Players ready to exfiltrate!", Count Of(Filtered Array(All Players(Team 1), + Distance Between(Vector(186, 11, -46.500), Current Array Element) <= 9)), Count Of(All Players(Team 1))), Vector(186, 15, + -46.500), 1.200, Do Not Clip, Visible To and String, Color(Green), Default Visibility); + Wait(3, Ignore Condition); + Destroy HUD Text(Global.globalHUDs[1]); + } +} + +rule("OPTIONAL ENDING - EXFIL PLAYERS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.challengeCount == 12; + Count Of(Filtered Array(All Players(Team 1), Distance Between(Vector(186, 11, -46.500), All Players(Team 1)) <= 9)) > Count Of( + All Players(Team 1)) / 2; + } + + actions + { + Big Message(All Players(Team 1), Custom String("GG! YOU SUCCESSFULLY RAN AWAY, WHILE LEAVING THE GATE TO THE ENEMY!")); + Destroy All Dummy Bots; + Disable Movement Collision With Environment(All Players(Team 1), True); + Start Accelerating(All Players(Team 1), Up, 100, 5, To World, Direction Rate and Max Speed); + Wait(5, Ignore Condition); + Declare Team Victory(Team 1); + } +} + +rule("Team 1 (Ability): Second Wind save life") +{ + event + { + Player Took Damage; + Team 1; + All; + } + + conditions + { + Event Player.abilities[9] == True; + Event Player.secondWindActive == True; + Health(Event Player) == 1; + } + + actions + { + Small Message(All Players(All Teams), Custom String("{0} received a second wind!", Event Player)); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(Green), Event Player, 1); + Clear Status(Event Player, Unkillable); + Set Player Health(Event Player, Max Health(Event Player)); + Event Player.lastSecondWind = 30; + Event Player.secondWindActive = 0; + } +} + +rule("Team 1 (Ability): Second Wind after buying") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Event Player.abilities[9] == True; + Event Player.secondWindActive == False; + Event Player.lastSecondWind == 0; + } + + actions + { + If(Random Integer(1, 100) > Event Player.abilities[9] * 30); + Wait(30, Ignore Condition); + Loop; + End; + Set Status(Event Player, Null, Unkillable, 9999); + Event Player.secondWindActive = 1; + } +} + +rule("Team 1 (Ability): Second Wind counter") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Is Game In Progress == True; + Event Player.lastSecondWind > 0; + } + + actions + { + Wait(1, Ignore Condition); + Event Player.lastSecondWind -= 1; + Loop If Condition Is True; + } +} + +rule("Team 1: Change Hero") +{ + event + { + Ongoing - Each Player; + Team 1; + All; + } + + conditions + { + Distance Between(Vector(159, 11, -46.500), Event Player) <= 2; + Is Button Held(Event Player, Button(Interact)) == True; + } + + actions + { + Set Player Allowed Heroes(Event Player, Hero(Pharah)); + Set Player Allowed Heroes(Event Player, Hero(Ana)); + Reset Player Hero Availability(Event Player); + Wait(0.500, Ignore Condition); + Wait Until(Has Spawned(Event Player), 99999); + Teleport(Event Player, Vector(159, 11, -46.500)); + } +} + +rule("Team 1: Player Dealt Healing") +{ + event + { + Player Dealt Healing; + Team 1; + All; + } + + actions + { + If(Hero Of(Event Player) == Hero(Moira) && Event Ability == Button(Ability 2) && Event Player.abilities[12] == True); + Heal(Healee, Event Player, Event Healing * 2); + Play Effect(All Players(Team 1), Good Explosion, Color(Yellow), Healee, 0.100); + Wait(0.250, Ignore Condition); + End; + If(Hero Of(Event Player) == Hero(Zenyatta) && Event Player.abilities[8] == True); + Set Status(Healee, Null, Invincible, 1); + Wait(0.800, Ignore Condition); + End; + Abort If(Healee != Event Player); + If(Event Player.abilities[10] == True); + Set Player Health(Event Player, Health(Event Player) + Event Player.abilities[10] * 0.250 * Event Healing); + End; + If(Hero Of(Event Player) == Hero(Mercy) && Event Player.abilities[8] == True && Normalized Health(Healee) < True); + Set Ultimate Charge(Healee, Ultimate Charge Percent(Healee) + 1); + Wait(0.400, Ignore Condition); + End; + } +} + +rule("Team 1: Player Dealt Damage") +{ + event + { + Player Dealt Damage; + Team 1; + All; + } + + actions + { + If(Event Was Critical Hit == True); + If(Global.upgradeCriticalDamageValue >= Global.upgradeCriticalDamageMaxValue[0]); + Damage(Victim, Event Player, Event Damage * 0.500); + End; + If(Event Player.abilities[1] == True); + Damage(Victim, Event Player, Event Player.abilities[1] * 40 / Event Player.damageDealt * Event Damage); + End; + End; + If(Event Player.abilities[2] == True && Event Ability != Null && (Y Component Of(Position Of(Event Player)) - Y Component Of( + Position Of(Victim)) >= 3 || Absolute Value(Horizontal Angle Towards(Victim, Event Player)) >= 90) == True); + Damage(Victim, Event Player, Event Player.abilities[2] * 30 / Event Player.damageDealt * Event Damage); + End; + If(Global.perk[0] == True && Event Ability != Null && Distance Between(Event Player, Victim) >= 10); + Damage(Victim, Event Player, 50 / Event Player.damageDealt * Event Damage); + End; + If(Event Player.abilities[8] == True); + If(Event Ability == Button(Ability 1)); + If(Hero Of(Event Player) == Hero(Ana)); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(Black), Victim, 1); + Wait(0.250, Ignore Condition); + Set Status(Victim, Null, Knocked Down, 5); + End; + If(Hero Of(Event Player) == Hero(Brigitte)); + Play Effect(All Players(Team 1), Ring Explosion, Color(Orange), Victim, 1.500); + Set Status(Victim, Null, Rooted, 0.500); + Set Environment Credit Player(Victim, Event Player); + End; + If(Hero Of(Event Player) == Hero(Genji)); + Start Heal Over Time(Event Player, Event Player, 3, 25); + Start Damage Over Time(Victim, Event Player, 3, 25); + Damage(Victim, Event Player, 25); + Heal(Event Player, Event Player, 25); + End; + End; + If(Event Ability == Button(Primary Fire)); + If(Hero Of(Event Player) == Hero(Brigitte)); + Play Effect(All Players(Team 1), Ring Explosion, Color(Orange), Victim, 1.500); + Set Status(Victim, Null, Rooted, 0.500); + Set Environment Credit Player(Victim, Event Player); + End; + If(Has Status(Victim, Burning) == True && Hero Of(Event Player) == Hero(Ashe)); + Set Status(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Null, Burning, 10); + Start Damage Over Time(Filtered Array(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Hero Of( + Current Array Element) != Hero(Torbjörn)), Event Player, 10, 15); + Play Effect(All Players(Team 1), Good Explosion, Color(Orange), Victim, 5); + Play Effect(All Players(Team 1), Bad Explosion, Color(Red), Victim, 5); + Wait(0.250, Ignore Condition); + End; + If((Normalized Health(Victim) <= 0.300 || Event Damage >= Normalized Health(Victim) + Event Damage) && Is Firing Secondary( + Event Player) == True && Event Damage >= 40 && Event Was Critical Hit == True); + Kill(Victim, Event Player); + Play Effect(All Players(Team 1), Bad Explosion, Color(Team 2), Victim, 3); + Damage(Players Within Radius(Victim, 3, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Event Damage * 1.500); + End; + End; + If(Event Ability == Button(Ability 2)); + If(Hero Of(Event Player) == Hero(Reinhardt)); + Play Effect(All Players(Team 1), Good Explosion, Color(Orange), Victim, 5); + Start Damage Over Time(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 5, 20); + Set Status(Players Within Radius(Victim, 5, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, Burning, 5); + End; + If(Hero Of(Event Player) == Hero(Cassidy)); + Victim.fearedUntil = Total Time Elapsed + 3.500; + End; + If(Hero Of(Event Player) == Hero(Echo) && Normalized Health(Victim) > 0.500 && Normalized Health(Victim) + <= 0.900 && Is Duplicating(Event Player) == False); + Damage(Victim, Event Player, Event Damage * 3); + Play Effect(All Players(Team 1), Bad Explosion, Color(Violet), Victim, 0.500); + End; + End; + End; + If(Event Player.abilities[12] == True); + If(Event Ability == Button(Ability 2)); + If(Hero Of(Event Player) == Hero(Moira)); + Damage(Victim, Event Player, Event Damage * 2); + Play Effect(All Players(Team 1), Good Explosion, Color(Violet), Victim, 0.100); + Wait(0.250, Ignore Condition); + End; + If(Hero Of(Event Player) == Hero(Hanzo)); + Damage(Victim, Event Player, Event Damage * 0.800); + Apply Impulse(Victim, Facing Direction Of(Event Player), 12, To World, Cancel Contrary Motion); + Apply Impulse(Victim, Up, 5, To World, Cancel Contrary Motion); + Set Environment Credit Player(Victim, Event Player); + Set Status(Victim, Null, Stunned, 1); + End; + If(Hero Of(Event Player) == Hero(Widowmaker)); + Play Effect(All Players(Team 1), Good Explosion, Color(Violet), Victim, 8); + Play Effect(All Players(Team 1), Good Explosion, Color(Purple), Victim, 4); + Play Effect(All Players(Team 1), Ring Explosion, Color(Violet), Victim, 16); + Play Effect(All Players(Team 1), Bad Explosion, Color(White), Victim, 3); + Start Damage Over Time(Players Within Radius(Victim, 8, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, 3, 50); + Start Heal Over Time(Event Player, Event Player, 3, 50); + Wait(0.500, Ignore Condition); + End; + If(Hero Of(Event Player) == Hero(Junkrat)); + Event Player.abilityCountdown = 4; + While(Event Player.abilityCountdown > 0); + Event Player.abilityCountdown -= 1; + Event Player.abilityPosition = Position Of(Victim) + Vector(Random Real(-2, 2), Random Real(-2, 2), Random Real(-2, 2)); + Play Effect(All Players(Team 1), Good Explosion, Color(Sky Blue), Event Player.abilityPosition, 4); + Play Effect(All Players(Team 1), Good Explosion, Color(White), Event Player.abilityPosition, 4); + Damage(Players Within Radius(Event Player.abilityPosition, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + 35); + Set Status(Players Within Radius(Event Player.abilityPosition, 4, Opposite Team Of(Team Of(Event Player)), Surfaces), Event Player, + Stunned, 0.800); + Wait(0.200, Ignore Condition); + End; + End; + End; + If(Event Ability == Button(Ultimate)); + If(Hero Of(Event Player) == Hero(Cassidy)); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(Orange), Victim, 1); + Damage(Victim, Event Player, Event Damage * 1.500); + Set Status(Victim, Null, Knocked Down, 3); + End; + If(Hero Of(Event Player) == Hero(Torbjörn)); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(Orange), Victim, 1); + Set Status(Victim, Null, Rooted, 1); + Wait(1, Ignore Condition); + End; + If(Hero Of(Event Player) == Hero(Tracer) && Event Damage > 20); + Victim.chainReactionOn = True; + End; + End; + If(Event Ability == Button(Secondary Fire)); + If(Hero Of(Event Player) == Hero(Mei) && Is Using Ability 2(Event Player) == True); + Damage(Victim, Event Player, Event Damage * 1.250); + Set Status(Victim, Null, Frozen, 1); + Set Status(Victim, Null, Rooted, 1); + Play Effect(All Players(Team 1), Good Pickup Effect, Color(White), Victim, 1); + End; + End; + End; + } +} \ No newline at end of file