diff --git a/.gitignore b/.gitignore index 57940fd..80ebac8 100644 --- a/.gitignore +++ b/.gitignore @@ -77,3 +77,5 @@ fabric.properties # Android studio 3.1+ serialized cache file .idea/caches/build_file_checksums.ser +/.fleet/ +/.idea/ diff --git a/defendTheCastleExtended/customGameSettings.lobby b/defendTheCastleExtended/customGameSettings.lobby new file mode 100644 index 0000000..47e653b --- /dev/null +++ b/defendTheCastleExtended/customGameSettings.lobby @@ -0,0 +1,33 @@ +{ + "Lobby": { + "Max Spectators": 0, + "Max Team 1 Players": 4, + "Max Team 2 Players": 0, + "Return To Lobby": "Never", + "Swap Teams After Match": false + }, + "Modes": { + "All": { + "Game Mode Start": "Immediately", + "Spawn Health Packs": "Disabled" + }, + "Escort": { + "Enabled Maps": [ + "Havana" + ] + }, + "Team Deathmatch": { + "Enabled Maps": [] + } + }, + "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", + "Extensions": { + "Beam Effects": true, + "Buff Status Effects": true, + "Kinetic Explosion Effects": true, + "Explosion Sounds": true, + "Play More Effects": true, + "Spawn More Dummy Bots": true + } +} \ No newline at end of file diff --git a/defendTheCastleExtended/latest.ostw b/defendTheCastleExtended/latest.ostw new file mode 100644 index 0000000..4c52c1c --- /dev/null +++ b/defendTheCastleExtended/latest.ostw @@ -0,0 +1,5843 @@ +import "customGameSettings.lobby"; + +globalvar define gatePosition; +globalvar define zenSpawnPositions; +globalvar define spawnPositionMaxId; +globalvar define loopIterator; +globalvar define bigBossSpawnPositions; +globalvar define playerSpawnPositions; +globalvar define gateHealthChase; +globalvar define gateHealth; +globalvar define gateMaxHealth; +globalvar define gateProgressBarColorCurrent; +globalvar define gateProgressBarColorComponent; +globalvar define gateHealthEvent; +globalvar define bastionTargetPositions; +globalvar define sniperPositions; +globalvar define ballSpawnPositions; +globalvar define zenRespawnTime; +globalvar define timeSeconds; +globalvar define timeMinutes; +globalvar define defaultCurrentBot; +globalvar define defaultHeroBotsPool; +globalvar define isDebug; +globalvar define botOrisaParent; +globalvar define botOrisaChild; +globalvar define gateRepairPosition; +globalvar define botOrisaTargetPosition; +globalvar define botEchoRespawnPosition; +globalvar define botEchoTeleportPositions; +globalvar define upgradeGateMaxHealthValue; +globalvar define upgradeGateMaxHealthHudId; +globalvar define upgradePlayerMaxHealthValue; +globalvar define upgradePlayerMaxHealthHudId; +globalvar define upgradeCriticalDamageValue; +globalvar define upgradeCriticalDamageHudId; +globalvar define upgradeMaxAmmoValue; +globalvar define upgradeMaxAmmoHudId; +globalvar define upgradeMaxAmmoMaxValue; +globalvar define upgradePlayerMaxHealthMaxValue; +globalvar define upgradeCriticalDamageMaxValue; +globalvar define upgradeGateMaxHealthMaxValue; +globalvar define isDebugAINavigation; +globalvar define gameLogicCountOfUniqueHeroes; +globalvar define isNewWaveGameLogicProcessing; +globalvar define automaticRepair; +globalvar define upgradePerkSharpshooterValue; +globalvar define perk; +globalvar define maxHealthDone; +globalvar define startMoney; +globalvar define time5Minutes; +globalvar define selfNanoWorkshopSetting; +globalvar define shopCamPosition; +globalvar define shopBasePosition; +globalvar define shopPositionAngle; +globalvar define activeBoss; +globalvar define bossRotation; +globalvar define lastBoss; +globalvar define time10Minutes; +globalvar define moneyMultiplier; +globalvar define challengeCount; +globalvar define upgradeBossHealthValue; +globalvar define globalHUDs; +globalvar define extendedGlobalCollection; +globalvar define arrayBuilder; +globalvar define exitButtonProperties; +globalvar define allPositions; +globalvar define allDirections; +globalvar define firstPosition; +globalvar define secondPosition; +globalvar define firstPoint; +globalvar define secondPoint; +globalvar define second; +globalvar define z; +globalvar define wallId; +globalvar define showWalls; +globalvar define isGrounded; +globalvar define beamType; +globalvar define nodePositions; +globalvar define nodeConnections; +globalvar define distanceMatrix; +playervar define botSeePlayer; +playervar define botDoesUniqueBehaviour; +playervar define botEffects; +playervar define botRayCastHitPosition; +playervar define botEventPosition; +playervar define currentHero; +playervar define isDead; +playervar define isRespawning; +playervar define botBastionArtilleryDidShotsCount; +playervar define botCounter; +playervar define hasBadStatus; +playervar define eventHealth; +playervar define healOverTimeId; +playervar define botIsOrisaChild; +playervar define botEchoCapturedPlayer; +playervar define botPlayersInRadius; +playervar define botLoopIterator2; +playervar define botWidowShotTime; +playervar define botWidowTeleportTime; +playervar define isNanoed; +playervar define abilityHUD; +playervar define lucioDashActive; +playervar define lucioDashIcon; +playervar define anaEntityID; +playervar define abilities; +playervar define money; +playervar define heroTalentText; +playervar define damageBoost; +playervar define playerHealth; +playervar define abilityCountdown; +playervar define hpPool; +playervar define effects; +playervar define abilityProjectile; +playervar define abilityEnd; +playervar define abilityAvailable; +playervar define speedBoost; +playervar define damageMod; +playervar define soldierEspionage; +playervar define healBoost; +playervar define baseStats; +playervar define chainReactionOn; +playervar define chainReactionImmune; +playervar define abilityActive; +playervar define p_loopIterator; +playervar define secondWindActive; +playervar define isInMenu; +playervar define playerFacing; +playervar define isBoss; +playervar define deathPosition; +playervar define lastSecondWind; +playervar define vote; +playervar define workshopButtons; +playervar define extendedPlayerCollection; +playervar define getProperties; +playervar define buttonModification; +playervar define currActionID; +playervar define destroyButtonID; +playervar define lastMenuButtonID; +playervar define buttons; +playervar define newButton; +playervar define menuOriginalFacing; +playervar define menuFrame; +playervar define filterPosition; +playervar define lastSavedPosition; +playervar define closestBodyPosition; +playervar define fullBodyPosition; +playervar define previousPositionIntersection; +playervar define activeWall; +playervar define closestWall; +playervar define x; +playervar define intersectionLength; +playervar define thickness; +playervar define botCancelPathFinding; +playervar define botLoopIterator1; +playervar define botTempArray; +playervar define botTargetPlayer; +playervar define botTargetPosition; +playervar define botClosestNodeIdToTarget; +playervar define botClosestNodeIdToBot; +playervar define botPreviousNodeId; +playervar define botNextNodeId; +playervar define botNextNodePosition; +playervar define botCurrentDistanceToTarget; +playervar define botShortestDistanceToTarget; +playervar define botIsPathFinding; + +disabled rule: "=== PATH BUILDER MODE IMPORT ===" +{ +} + +rule: "MAP: HAVANA" +if (CurrentMap() == Map.Havana) +{ + nodePositions = [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.92), Vector(124.572, 10.434, -34.3), 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.03, 7.418, -74.087), Vector(83.72, 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.45, -46.143), Vector(90.086, 7.411, -44.653), Vector(78.752, 7.418, -62.14), Vector(82.124, 7.428, -44.229), Vector(90.675, 7.231, -51.234), Vector(85.717, 4.692, -63.446), Vector(90.83, 4.33, -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.14), Vector(126.979, 12.393, -55.079), Vector(153.72, 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.16, 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)]; + nodeConnections = [[1, 6, 4, 7], [2, 1, 4, 6, 7, 0, 49], [1, 3], [2, 4, 42], [3, 1, 5, 7, 6, 1, 0], [4, 7, 20, 21, 19, 16, 42], [7, 1, 4, 1, 9, 12, 0, 46], [4, 5, 6, 1, 1, 12, 0], [7, 41], [6, 11], [11, 13], [9, 10, 13], [6, 7, 10], [10, 16, 36], [18, 23, 30], [17, 24], [13, 19, 22, 21, 25, 5], [15, 22, 25, 23], [14], [16, 21, 22, 26, 27, 35, 25, 5], [5, 13, 10], [19, 16, 5, 13, 22, 34], [16, 19, 21, 24, 25], [14, 25, 26, 37], [22, 15, 37], [23, 22, 19, 16, 26, 27, 35, 37], [25, 19, 27, 35, 29], [19, 26, 25, 29, 35, 43], [35, 34, 43], [27, 26, 30, 43, 44], [29, 14, 31], [30, 29, 45], [33, 38, 1, 48], [32, 38, 42], [35, 36, 28], [28, 19, 25, 27, 26, 34], [13, 34], [25, 23, 24], [5, 4, 1, 6, 1, 32, 33, 0], [40], [39], [6, 8, 47, 46], [3, 5, 34], [28, 27, 29, 44], [29, 43, 45], [44, 31], [6, 47], [46, 41], [49, 32], [1, 0, 6, 48]]; + distanceMatrix = [[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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [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], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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], [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], [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], [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], [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], [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], [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], [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], [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], [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]]; +} + +void BotResetPathFinding() "SUBROUTINE: BOT - RESET PATH FINDING" +{ + botTargetPlayer = -1; + botTargetPosition = -1; + botPreviousNodeId = -1; + botClosestNodeIdToTarget = -1; + botNextNodeId = -1; + botNextNodePosition = -1; + botIsPathFinding = false; + botCancelPathFinding = false; + StopThrottleInDirection(EventPlayer()); +} + +void BotStartPathFinding() "SUBROUTINE: BOT - START PATH FINDING" +{ + BotGetNextNodeIdAndPosition(); + StartThrottleInDirection(EventPlayer(), DirectionTowards(PositionOf(EventPlayer()), botNextNodePosition), 1, Relative.ToWorld, ThrottleBehavior.ReplaceExistingThrottle, ThrottleRev.DirectionAndMagnitude); + botIsPathFinding = true; +} + +void BotGetNextNodeIdAndPosition() "SUBROUTINE: BOT - GET NEXT NODE ID AND POSITION" +{ + # BOT JUST START FOLLOW PATH OR LOST NEXT NODE + if (botPreviousNodeId == -1) + { + botClosestNodeIdToBot = IndexOfArrayValue(nodePositions, SortedArray(FilteredArray(nodePositions, IsInLineOfSight(PositionOf(EventPlayer()) + Vector(0, 2, 0), ArrayElement(), BarrierLOS.NoBarriersBlock) == true), DistanceBetween(PositionOf(EventPlayer()), ArrayElement()))[0]); + BotGetClosestNodeIdToTarget(); + } + # NEXT NODE IS TARGET (DISTANCE TO TARGET NODE = 1) + if (distanceMatrix[botClosestNodeIdToBot][botClosestNodeIdToTarget] == 1) + { + botNextNodeId = botClosestNodeIdToTarget; + } + else + { + botShortestDistanceToTarget = 999; + botCurrentDistanceToTarget = botShortestDistanceToTarget; + botTempArray = nodeConnections[botClosestNodeIdToBot]; + for (botLoopIterator1 = 0; CountOf(botTempArray); 1) + { + botCurrentDistanceToTarget = distanceMatrix[botTempArray[botLoopIterator1]][botClosestNodeIdToTarget]; + if (botCurrentDistanceToTarget < botShortestDistanceToTarget) + { + botShortestDistanceToTarget = botCurrentDistanceToTarget; + botNextNodeId = botTempArray[botLoopIterator1]; + } + } + } + # NEXT NODE IS HIGHER THAN BOT AND BOT DIDN'T REACH CLOSEST NODE + if (YOf(PositionOf(EventPlayer())) - YOf(nodePositions[botNextNodeId]) < -3 && botPreviousNodeId != botClosestNodeIdToBot) + { + botPreviousNodeId = botClosestNodeIdToBot; + botNextNodeId = botClosestNodeIdToBot; + } + else if (distanceMatrix[botClosestNodeIdToBot][botClosestNodeIdToTarget] == 1 && IsInLineOfSight(PositionOf(EventPlayer()) + Vector(0, 1.6, 0), botTargetPosition + Vector(0, 2, 0), BarrierLOS.NoBarriersBlock)) + { + botNextNodePosition = botTargetPosition; + Abort(); + } + else if (IsInLineOfSight(PositionOf(EventPlayer()) + Vector(0, 1.6, 0), nodePositions[botNextNodeId] + Vector(0, 2, 0), BarrierLOS.NoBarriersBlock) == false && botPreviousNodeId != botClosestNodeIdToBot) + { + botPreviousNodeId = botClosestNodeIdToBot; + botNextNodeId = botClosestNodeIdToBot; + } + botNextNodePosition = nodePositions[botNextNodeId]; +} + +void BotGetClosestNodeIdToTarget() "SUBROUTINE: BOT - GET CLOSEST NODE ID AND POSITION TO TARGET" +{ + botTargetPosition = botTargetPlayer != -1 ? PositionOf(botTargetPlayer) : botTargetPosition; + botClosestNodeIdToTarget = IndexOfArrayValue(nodePositions, SortedArray(FilteredArray(nodePositions, IsInLineOfSight(botTargetPosition + Vector(0, 2, 0), ArrayElement(), BarrierLOS.NoBarriersBlock) == true), DistanceBetween(botTargetPosition, ArrayElement()))[0]); +} + +rule: "BOT: PATH FINDING - START" +Event.OngoingPlayer +Team.Team2 +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if ((botTargetPosition != -1 || botTargetPlayer != -1) == true) +{ + async BotStartPathFinding(); +} + +rule: "BOT: PATH FINDING - CANCEL" +Event.OngoingPlayer +Team.Team2 +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (botIsPathFinding == true) +if (botCancelPathFinding == true) +{ + async BotResetPathFinding(); +} + +rule: "BOT: PATH FINDING - LOST THE NODE" +Event.OngoingPlayer +Team.Team2 +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (botIsPathFinding == true) +if ((IsInLineOfSight(PositionOf(EventPlayer()) + Vector(0, 1.6, 0), botNextNodePosition + Vector(0, 2.5, 0), BarrierLOS.NoBarriersBlock) == false && SpeedOfInDirection(EventPlayer(), ThrottleOf(EventPlayer())) < 2) == true) +{ + Wait(0.5, WaitBehavior.AbortWhenFalse); + # RESET PREV NODE ID TO INFORM BOT THAT IT LOST NEXT NODE + botPreviousNodeId = -1; + # TRY FIND NEW NEXT NODE + BotGetNextNodeIdAndPosition(); + StartFacing(EventPlayer(), DirectionTowards(PositionOf(EventPlayer()), botNextNodeId), 360, Relative.ToWorld, FacingRev.DirectionAndTurnRate); + StartThrottleInDirection(EventPlayer(), DirectionTowards(PositionOf(EventPlayer()), botNextNodePosition), 1, Relative.ToWorld, ThrottleBehavior.ReplaceExistingThrottle, ThrottleRev.DirectionAndMagnitude); +} + +rule: "BOT: PATH FINDING - REACHED THE NODE" +Event.OngoingPlayer +Team.Team2 +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (botIsPathFinding == true) +if (botClosestNodeIdToTarget >= 0) +if (DistanceBetween(Vector(XOf(PositionOf(EventPlayer())), 0, ZOf(PositionOf(EventPlayer()))), Vector(XOf(botNextNodePosition), 0, ZOf(botNextNodePosition))) < 0.85 == true) +{ + botPreviousNodeId = botNextNodeId; + botClosestNodeIdToBot = botNextNodeId; + # BOT'S TARGET IS PLAYER + if (botTargetPlayer != -1) + { + BotGetClosestNodeIdToTarget(); + } + botCurrentDistanceToTarget = DistanceBetween(Vector(XOf(PositionOf(EventPlayer())), 0, ZOf(PositionOf(EventPlayer()))), Vector(XOf(botTargetPosition), 0, ZOf(botTargetPosition))); + # BOT REACHED THE TARGET NODE OR TARGET POSITION + if (botNextNodeId == botClosestNodeIdToTarget || botCurrentDistanceToTarget <= 0.85) + { + # BOT DIDN'T REACH TARGET POSITION + if (botCurrentDistanceToTarget > 0.85) + { + botNextNodePosition = botTargetPosition; + Skip(6); + } + else + { + BotResetPathFinding(); + Abort(); + } + } + # CONTINUE FOLLOW PATH + BotGetNextNodeIdAndPosition(); + StartThrottleInDirection(EventPlayer(), DirectionTowards(PositionOf(EventPlayer()), botNextNodePosition), 1, Relative.ToWorld, ThrottleBehavior.ReplaceExistingThrottle, ThrottleRev.DirectionAndMagnitude); +} + +disabled rule: "=== PATH BUILDER MODE IMPORT ===" +{ +} + +rule: "GLOBAL: GAME MODE INIT - WORKSHOP SETTINGS" +{ + isDebug = false; + isDebugAINavigation = false; + gateMaxHealth[0] = WorkshopSettingInteger("Defend The Castle Extended", "GATE MAX HEALTH", 500, 100, 1000, 0); + moneyMultiplier[0] = WorkshopSettingReal("Defend The Castle Extended", "Money Multiplicator", 1, 0.5, 2, 0); + selfNanoWorkshopSetting = WorkshopSettingToggle("Ana Self Nano", "Ana can nano herself even if there are other players (only if no player targeted)", false, 0); +} + +rule: "GLOBAL: GAME MODE INIT - COMMON PROPERTIES" +{ + CreateInWorldText(AllPlayers(Team.Team1), <"Defend The Castle Extended d143\r\nby ShuriZma#2349\r\nOriginal mode by HUKUTA94#2589\r\nDiscord: dc.shuri.gg\r\n<0>", <"Special Thanks to:\nShingen#21859 for the Abilities,\nLemonAid#11644 for the Hero Talents &\nJosbird for teaching me about Menus<0>", "\nPS: SHINGEN PLS COME BACK">>, Vector(165, 12, -46.5), 1.2, Clipping.ClipAgainstSurfaces, InworldTextRev.VisibleTo, Color.White, Spectators.DefaultVisibility); + gateRepairPosition = Vector(153, 8, -46.5); + gatePosition = Vector(148.8, 6, -46.4); + ballSpawnPositions = [Vector(104, 7, -46), Vector(106, 2, -31)]; + sniperPositions = [Vector(154, 18, -22.6), Vector(86, 12, -46.6), Vector(80.88, 11.3, -71.6), Vector(98, 9, -19)]; + zenSpawnPositions = [Vector(79.5, 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.7, -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.5), Vector(135, 6, -63)]; + playerSpawnPositions = [Vector(160, 11, -53), Vector(158, 11, -53), Vector(160, 11, -39), Vector(158, 11, -39)]; + bigBossSpawnPositions = [Vector(78, 4, -84), Vector(95, 4, -82)]; + bastionTargetPositions = [Vector(131, 12, -62), Vector(115, 7, -46), ObjectivePosition(2), Vector(136, 10, -27)]; + spawnPositionMaxId = 2; + botOrisaTargetPosition = Vector(104, 7, -46); + botEchoRespawnPosition = Vector(130, 23, -44); + botEchoTeleportPositions = [Vector(88, 23, -79), Vector(108, 18, -27)]; + defaultHeroBotsPool = [Hero.Zenyatta, Hero.Widowmaker, null, Hero.Bastion, Hero.Echo, Hero.Bastion]; + zenRespawnTime = 10; + gameLogicCountOfUniqueHeroes = 5; + lastBoss = [null, null, null, null]; + CreateEffect(AllPlayers(Team.Team1), Effect.Ring, Color.SkyBlue, Vector(186, 11, -46.5), 9, EffectRev.VisibleToPositionAndRadius); + CreateEffect(AllPlayers(Team.Team1), Effect.Ring, Color.Yellow, Vector(159, 11, -46.5), 2, EffectRev.VisibleToPositionAndRadius); +} + +disabled rule: "=== TEAM UPGRADES ===" +{ +} + +rule: "GLOBAL: TEAM UPGRADES - INIT" +{ + upgradeMaxAmmoMaxValue[0] = 150; + upgradeMaxAmmoMaxValue[1] = 300; + upgradeMaxAmmoMaxValue[2] = 500; + upgradeCriticalDamageMaxValue[0] = 10; + upgradeCriticalDamageMaxValue[1] = 5; + upgradeCriticalDamageMaxValue[2] = 10; + upgradePlayerMaxHealthMaxValue[0] = 3000; + upgradePlayerMaxHealthMaxValue[1] = 7000; + upgradePlayerMaxHealthMaxValue[2] = 12000; + upgradeGateMaxHealthMaxValue[0] = RoundToInteger(gateMaxHealth[0] + gateMaxHealth[0] * 0.5, Rounding.Up) > 1000 ? 1000 : RoundToInteger(gateMaxHealth[0] + gateMaxHealth[0] * 0.5, Rounding.Up); + upgradeGateMaxHealthMaxValue[1] = RoundToInteger(upgradeGateMaxHealthMaxValue[0] + upgradeGateMaxHealthMaxValue[0] * 0.5, Rounding.Up); + upgradeGateMaxHealthMaxValue[2] = RoundToInteger(upgradeGateMaxHealthMaxValue[1] + upgradeGateMaxHealthMaxValue[1] * 0.5, Rounding.Up); + AbortIf(isDebug == false); + upgradeMaxAmmoMaxValue[0] = 1; + upgradeCriticalDamageMaxValue[0] = 1; + upgradePlayerMaxHealthMaxValue[0] = 1; + upgradeGateMaxHealthMaxValue[0] = 1; + upgradeMaxAmmoMaxValue[1] = 1; + upgradeCriticalDamageMaxValue[1] = 1; + upgradePlayerMaxHealthMaxValue[1] = 1; + upgradeGateMaxHealthMaxValue[1] = 1; + upgradeMaxAmmoMaxValue[2] = 1; + upgradeCriticalDamageMaxValue[2] = 1; + upgradePlayerMaxHealthMaxValue[2] = 1; + upgradeGateMaxHealthMaxValue[2] = 1; +} + +rule: "GLOBAL: UPGRADE - GATE'S MAX HEALTH - DONE" +if (IsGameInProgress() == true) +if (upgradeGateMaxHealthValue >= upgradeGateMaxHealthMaxValue[0] == true) +{ + PlayEffect(AllPlayers(Team.Team1), PlayEffect.GoodExplosion, Color.Green, gatePosition, 5); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.BuffImpactSound, Color.Green, gatePosition, 100); + gateMaxHealth[0] = RoundToInteger(gateMaxHealth[0] + gateMaxHealth[0] * 0.5, Rounding.Up); + gateHealth = gateMaxHealth[0]; + DestroyHudText(upgradeGateMaxHealthHudId[0]); + CreateHudText(AllPlayers(Team.Team1), AbilityIconString(Hero.Reinhardt, Button.SecondaryFire), "2X GATE REPAIR", <"REPAIR GATE <0>/<1> HP", upgradeGateMaxHealthValue, upgradeGateMaxHealthMaxValue[1]>, Location.Left, 12, Color.Blue, Color.Blue, Color.Blue, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + upgradeGateMaxHealthHudId[1] = LastTextID(); + async GateProgressBarColor(); + challengeCount += 1; +} + +rule: "GLOBAL: UPGRADE - GATE'S MAX HEALTH 2 - DONE" +if (IsGameInProgress() == true) +if (upgradeGateMaxHealthValue >= upgradeGateMaxHealthMaxValue[1] == true) +{ + PlayEffect(AllPlayers(Team.Team1), PlayEffect.GoodExplosion, Color.Green, gatePosition, 5); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.BuffImpactSound, Color.Green, gatePosition, 100); + DestroyHudText(upgradeGateMaxHealthHudId[1]); + CreateHudText(AllPlayers(Team.Team1), AbilityIconString(Hero.Reinhardt, Button.SecondaryFire), "2X AUTO-REPAIR", <"REPAIR GATE <0>/<1> HP", upgradeGateMaxHealthValue, upgradeGateMaxHealthMaxValue[2]>, Location.Left, 12, Color.Blue, Color.Blue, Color.Blue, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + upgradeGateMaxHealthHudId[2] = LastTextID(); + gateHealth = gateMaxHealth[0]; + async GateProgressBarColor(); + challengeCount += 1; +} + +rule: "GLOBAL: UPGRADE - GATE'S MAX HEALTH 3 - DONE" +if (IsGameInProgress() == true) +if (upgradeGateMaxHealthValue >= upgradeGateMaxHealthMaxValue[2] == true) +{ + PlayEffect(AllPlayers(Team.Team1), PlayEffect.GoodExplosion, Color.Green, gatePosition, 5); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.BuffImpactSound, Color.Green, gatePosition, 100); + DestroyHudText(upgradeGateMaxHealthHudId[2]); + gateHealth = gateMaxHealth[0]; + async GateProgressBarColor(); + challengeCount += 1; +} + +rule: "PLAYER: UPGRADE - PLAYER'S MAX HEALTH - DEALT HEALING" +Event.OnHealingTaken +Team.Team1 +if (IsGameInProgress() == true) +if (upgradePlayerMaxHealthValue < upgradePlayerMaxHealthMaxValue[2]) +{ + upgradePlayerMaxHealthValue += EventHealing(); +} + +rule: "GLOBAL: UPGRADE - PLAYER'S MAX HEALTH - DONE" +if (IsGameInProgress() == true) +if (upgradePlayerMaxHealthValue >= upgradePlayerMaxHealthMaxValue[0] == true) +{ + DestroyHudText(upgradePlayerMaxHealthHudId[0]); + CreateHudText(AllPlayers(Team.Team1), IconString(Icon.Plus), "Up You Go: You respawn twice as fast", <"HEAL PLAYERS <0>/<1> HP", RoundToInteger(upgradePlayerMaxHealthValue, Rounding.Down), upgradePlayerMaxHealthMaxValue[1]>, Location.Left, 13, Color.Blue, Color.Blue, Color.Blue, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + upgradePlayerMaxHealthHudId[1] = LastTextID(); + for (loopIterator = 0; CountOf(AllPlayers(Team.Team1)); 1) + { + PlayEffect(AllPlayers(Team.Team1), PlayEffect.GoodPickupEffect, Color.Yellow, PositionOf(AllPlayers(Team.Team1)[loopIterator]), 1); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.BuffImpactSound, Color.Yellow, PositionOf(AllPlayers(Team.Team1)[loopIterator]), 100); + } + maxHealthDone = 50; + Heal(AllPlayers(Team.Team1), null, 9999); + challengeCount += 1; +} + +rule: "GLOBAL: UPGRADE - PLAYER'S MAX HEALTH - DONE" +Event.OngoingPlayer +Team.Team1 +if (IsGameInProgress() == true) +if (upgradePlayerMaxHealthValue >= upgradePlayerMaxHealthMaxValue[0] == true) +{ + UpdatePlayerStats(); +} + +rule: "GLOBAL: UPGRADE - PERK UP YOU GO - DONE" +if (IsGameInProgress() == true) +if (upgradePlayerMaxHealthValue >= upgradePlayerMaxHealthMaxValue[1] == true) +{ + DestroyHudText(upgradePlayerMaxHealthHudId[1]); + CreateHudText(AllPlayers(Team.Team1), IconString(Icon.Plus), "PLAYER'S MAX HEALTH +100%", <"HEAL PLAYERS <0>/<1> HP", RoundToInteger(upgradePlayerMaxHealthValue, Rounding.Down), upgradePlayerMaxHealthMaxValue[2]>, Location.Left, 13, Color.Blue, Color.Blue, Color.Blue, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + upgradePlayerMaxHealthHudId[2] = LastTextID(); + SetRespawnMaxTime(AllPlayers(Team.Team1), 5); + Heal(AllPlayers(Team.Team1), null, 9999); + for (loopIterator = 0; CountOf(AllPlayers(Team.Team1)); 1) + { + PlayEffect(AllPlayers(Team.Team1), PlayEffect.GoodPickupEffect, Color.Yellow, PositionOf(AllPlayers(Team.Team1)[loopIterator]), 1); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.BuffImpactSound, Color.Yellow, PositionOf(AllPlayers(Team.Team1)[loopIterator]), 100); + } + perk[2] = 1; + CreateHudText(AllPlayers(Team.Team1), null, "Up You Go", null, Location.Left, 917, Color.White, Color.Green, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + AllPlayers(Team.Team1).abilityHUD[17] = LastTextID(); + challengeCount += 1; +} + +rule: "GLOBAL: UPGRADE - PLAYER'S MAX HEALTH 2 - DONE" +if (IsGameInProgress() == true) +if (upgradePlayerMaxHealthValue >= upgradePlayerMaxHealthMaxValue[2] == true) +{ + DestroyHudText(upgradePlayerMaxHealthHudId[2]); + for (loopIterator = 0; CountOf(AllPlayers(Team.Team1)); 1) + { + PlayEffect(AllPlayers(Team.Team1), PlayEffect.GoodPickupEffect, Color.Yellow, PositionOf(AllPlayers(Team.Team1)[loopIterator]), 1); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.BuffImpactSound, Color.Yellow, PositionOf(AllPlayers(Team.Team1)[loopIterator]), 100); + } + maxHealthDone = 150; + Heal(AllPlayers(Team.Team1), null, 9999); + challengeCount += 1; +} + +rule: "GLOBAL: UPGRADE - PLAYER'S MAX HEALTH 2 - DONE" +Event.OngoingPlayer +Team.Team1 +if (IsGameInProgress() == true) +if (upgradePlayerMaxHealthValue >= upgradePlayerMaxHealthMaxValue[2] == true) +{ + UpdatePlayerStats(); +} + +rule: "PLAYER: UPGRADE - CRITICAL DAMAGE - DEALT KILL" +Event.OnFinalBlow +Team.Team1 +if (IsGameInProgress() == true) +if (EventWasCriticalHit() == true) +if (HeroOf(Victim()) == Hero.Widowmaker) +if (upgradeCriticalDamageValue < upgradeCriticalDamageMaxValue[0]) +{ + upgradeCriticalDamageValue += 1; +} + +rule: "GLOBAL: UPGRADE - CRITICAL DAMAGE - DONE" +if (IsGameInProgress() == true) +if (upgradeCriticalDamageValue >= upgradeCriticalDamageMaxValue[0]) +{ + DestroyHudText(upgradeCriticalDamageHudId[0]); + CreateHudText(AllPlayers(Team.Team1), IconString(Icon.Skull), "Sharpshooter: 40% more damage at >15m", <"KILL ECHO <0>/<1>", upgradePerkSharpshooterValue, upgradeCriticalDamageMaxValue[1]>, Location.Left, 14, Color.Blue, Color.Blue, Color.Blue, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + upgradeCriticalDamageHudId[1] = LastTextID(); + challengeCount += 1; +} + +rule: "PLAYER: UPGRADE - PERK SHARPSHOOTER - DEALT KILL" +Event.OnFinalBlow +Team.Team1 +if (IsGameInProgress() == true) +if (HeroOf(Victim()) == Hero.Echo) +if (upgradePerkSharpshooterValue < upgradeCriticalDamageMaxValue[1]) +if (upgradeCriticalDamageValue >= upgradeCriticalDamageMaxValue[0]) +{ + upgradePerkSharpshooterValue += 1; +} + +rule: "GLOBAL: UPGRADE - PERK SHARPSHOOTER - DONE" +if (IsGameInProgress() == true) +if (upgradePerkSharpshooterValue >= upgradeCriticalDamageMaxValue[1]) +{ + DestroyHudText(upgradeCriticalDamageHudId[1]); + CreateHudText(AllPlayers(Team.Team1), IconString(Icon.Skull), "-10% BOSS HEALTH", <"KILL Bosses <0>/<1>", upgradeBossHealthValue, upgradeCriticalDamageMaxValue[2]>, Location.Left, 14, Color.Blue, Color.Blue, Color.Blue, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + upgradeCriticalDamageHudId[2] = LastTextID(); + perk[0] = 1; + CreateHudText(AllPlayers(Team.Team1), null, "Sharpshooter", null, Location.Left, 918, Color.White, Color.Green, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + AllPlayers(Team.Team1).abilityHUD[18] = LastTextID(); + challengeCount += 1; +} + +rule: "GLOBAL: UPGRADE - -10% BOSS HEALTH - DONE" +if (IsGameInProgress() == true) +if (upgradeBossHealthValue >= upgradeCriticalDamageMaxValue[2]) +{ + DestroyHudText(upgradeCriticalDamageHudId[2]); + challengeCount += 1; +} + +rule: "GLOBAL: UPGRADE - MAX AMMO - DONE" +if (IsGameInProgress() == true) +if (upgradeMaxAmmoValue >= upgradeMaxAmmoMaxValue[0] == true) +{ + DestroyHudText(upgradeMaxAmmoHudId[0]); + CreateHudText(AllPlayers(Team.Team1), IconString(Icon.Asterisk), "+50% DAMAGE", <"KILL ENEMIES: <0>/<1>", upgradeMaxAmmoValue, upgradeMaxAmmoMaxValue[1]>, Location.Left, 15, Color.Blue, Color.Blue, Color.Blue, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + upgradeMaxAmmoHudId[1] = LastTextID(); + for (loopIterator = 0; CountOf(AllPlayers(Team.Team1)); 1) + { + SetMaxAmmo(AllPlayers(Team.Team1)[loopIterator], 0, MaxAmmo(AllPlayers(Team.Team1)[loopIterator], 0) * 2); + SetMaxAmmo(AllPlayers(Team.Team1)[loopIterator], 1, MaxAmmo(AllPlayers(Team.Team1)[loopIterator], 1) * 2); + SetAmmo(AllPlayers(Team.Team1)[loopIterator], 0, MaxAmmo(AllPlayers(Team.Team1)[loopIterator], 0)); + SetAmmo(AllPlayers(Team.Team1)[loopIterator], 1, MaxAmmo(AllPlayers(Team.Team1)[loopIterator], 1)); + } + challengeCount += 1; +} + +rule: "GLOBAL: UPGRADE - +50% DAMAGE - DONE" +if (IsGameInProgress() == true) +if (upgradeMaxAmmoValue >= upgradeMaxAmmoMaxValue[1] == true) +{ + DestroyHudText(upgradeMaxAmmoHudId[1]); + CreateHudText(AllPlayers(Team.Team1), IconString(Icon.Asterisk), "Bulletstorm: Your weapon can hold unlimited ammo", <"KILL ENEMIES: <0>/<1>", upgradeMaxAmmoValue, upgradeMaxAmmoMaxValue[2]>, Location.Left, 15, Color.Blue, Color.Blue, Color.Blue, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + upgradeMaxAmmoHudId[2] = LastTextID(); + challengeCount += 1; +} + +rule: "GLOBAL: UPGRADE - +50% DAMAGE - DONE" +Event.OngoingPlayer +Team.Team1 +if (IsGameInProgress() == true) +if (upgradeMaxAmmoValue >= upgradeMaxAmmoMaxValue[1] == true) +{ + UpdatePlayerStats(); +} + +rule: "GLOBAL: UPGRADE - PERK BULLETSTORM - DONE" +if (IsGameInProgress() == true) +if (upgradeMaxAmmoValue >= upgradeMaxAmmoMaxValue[2] == true) +{ + DestroyHudText(upgradeMaxAmmoHudId[2]); + perk[1] = 1; + CreateHudText(AllPlayers(Team.Team1), null, "Bulletstorm", null, Location.Left, 919, Color.White, Color.Green, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + AllPlayers(Team.Team1).abilityHUD[19] = LastTextID(); + challengeCount += 1; +} + +disabled rule: "=== GAME PHASES ===" +{ +} + +rule: "GLOBAL: ASSEMBLING PHASE - MAKE CHALLENGE HUDS" +if (IsAssemblingHeroes() == true) +{ + if (isDebug) + { + SetMatchTime(1); + } + else + { + DisableInspectorRecording(); + SetMatchTime(10); + } + CreateInWorldText(AllPlayers(Team.Team1), <"<0><1>\nREPAIR\n <2>", <"<0><1><2>", HeroIconString(Hero.Torbjorn), HeroIconString(Hero.Brigitte), HeroIconString(Hero.Reinhardt)>, HeroIconString(Hero.Symmetra), AbilityIconString(Hero.Reinhardt, Button.PrimaryFire)>, gatePosition + Vector(0, 1.4, 0), 1.2, Clipping.DoNotClip, InworldTextRev.VisibleTo, Color.White, Spectators.DefaultVisibility); + CreateHudText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[1] == 0), null, <"HOLD <0> - Reload to open the shop", InputBindingString(Button.Reload)>, null, Location.Top, 1000, Color.White, Color.Yellow, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + WaitUntil(IsGameInProgress() == true, 9999); + CreateHudText(AllPlayers(Team.Team1), null, <"TEAM CHALLENGES <0>/12", challengeCount>, null, Location.Left, 11, Color.White, Color.Red, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + # UPGRADE - GATE'S MAX HEALTH + CreateHudText(AllPlayers(Team.Team1), AbilityIconString(Hero.Reinhardt, Button.SecondaryFire), <"GATE'S MAX HEALTH: <0> HP", RoundToInteger(gateMaxHealth[0] + gateMaxHealth[0] * 0.75, Rounding.Up)>, <"REPAIR GATE <0>/<1> HP", upgradeGateMaxHealthValue, upgradeGateMaxHealthMaxValue[0]>, Location.Left, 12, Color.Blue, Color.Blue, Color.Blue, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + upgradeGateMaxHealthHudId[0] = LastTextID(); + # UPGRADE - PLAYER'S MAX HEALTH + CreateHudText(AllPlayers(Team.Team1), IconString(Icon.Plus), "PLAYER'S MAX HEALTH +50%", <"HEAL PLAYERS <0>/<1> HP", RoundToInteger(upgradePlayerMaxHealthValue, Rounding.Down), upgradePlayerMaxHealthMaxValue[0]>, Location.Left, 13, Color.Blue, Color.Blue, Color.Blue, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + upgradePlayerMaxHealthHudId[0] = LastTextID(); + # UPGRADE - CRITICAL DAMAGE + CreateHudText(AllPlayers(Team.Team1), IconString(Icon.Skull), "CRITICAL DAMAGE 150%", <"KILL WIDOW WITH HEADSHOT: <0>/<1>", upgradeCriticalDamageValue, upgradeCriticalDamageMaxValue[0]>, Location.Left, 14, Color.Blue, Color.Blue, Color.Blue, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + upgradeCriticalDamageHudId[0] = LastTextID(); + # UPGRADE - MAX AMMO + CreateHudText(AllPlayers(Team.Team1), IconString(Icon.Asterisk), "MAX AMMO 200%", <"KILL ENEMIES: <0>/<1>", upgradeMaxAmmoValue, upgradeMaxAmmoMaxValue[0]>, Location.Left, 15, Color.Blue, Color.Blue, Color.Blue, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + upgradeMaxAmmoHudId[0] = LastTextID(); +} + +rule: "GLOBAL: SETUP PHASE" +if (IsInSetup() == true) +{ + if (isDebug) + { + SetMatchTime(1); + } + else + { + PauseMatchTime(); + CreateHudText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[1] == 0), null, <"PRESS <0> - INTERACT TO VOTE FOR START | <1>/<2>", InputBindingString(Button.Interact), CountOf(FilteredArray(AllPlayers(Team.Team1), ArrayElement().vote[0] == 1)), CountOf(AllPlayers(Team.Team1))>, null, Location.Top, 50, Color.White, Color.Red, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + globalHUDs[0] = LastTextID(); + SetMatchTime(10); + while (CountOf(FilteredArray(AllPlayers(Team.Team1), ArrayElement().vote[0] == 1)) <= CountOf(AllPlayers(Team.Team1)) / 2) + { + FilteredArray(AllPlayers(Team.Team1), IsButtonHeld(ArrayElement(), Button.Interact)).vote[0] = 1; + Wait(0.1, WaitBehavior.IgnoreCondition); + } + DestroyHudText(globalHUDs[0]); + UnpauseMatchTime(); + } + SetObjectiveDescription(AllPlayers(Team.All), "DEFEND GATE", HudTextRev.VisibleToAndString); +} + +rule: "GLOBAL: GAME IN PROGRESS" +if (IsGameInProgress() == true) +{ + SetMatchTime(3599); + PauseMatchTime(); + DisableScoring(); + DisableAnnouncer(); + DisableCompletion(); + DisableGameModeHud(AllPlayers(Team.All)); + DisableGameModeInworldUI(AllPlayers(Team.All)); + gateHealth = gateMaxHealth[0]; + gateHealthChase = gateHealth; + gateProgressBarColorComponent = 255; + gateProgressBarColorCurrent = Color.White; + CreateProgressBarHudText(AllPlayers(Team.Team1), gateHealthChase * 100 / gateMaxHealth[0], <"GATE <0>/<1>", gateHealth, gateMaxHealth[0]>, Location.Top, 1, gateProgressBarColorCurrent, Color.White, ProgressBarHudEvaluation.VisibleToValuesAndColor, Spectators.DefaultVisibility); + CreateHudText(AllPlayers(Team.Team1), null, <"SURVIVED TIME: <0>:<1>", timeMinutes, timeSeconds < 10 ? <"0<0>", timeSeconds> : timeSeconds>, null, Location.Top, 2, Color.White, Color.White, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); +} + +disabled rule: "=== GAME - MAIN LOGIC ===" +{ +} + +rule: "GLOBAL: DEFEAT" +if (IsGameInProgress() == true) +if (isDebug == false) +if (gateHealth <= 0) +{ + DeclareTeamVictory(Team.Team2); +} + +rule: "GLOBAL: TIMER - MAIN GAME LOOP" +if (IsGameInProgress() == true) +{ + Wait(1, WaitBehavior.IgnoreCondition); + timeSeconds += 1; + if (timeSeconds == 60) + { + timeSeconds = 0; + timeMinutes += 1; + time5Minutes = RoundToInteger(timeMinutes / 5, Rounding.Down); + time10Minutes = RoundToInteger(timeMinutes / 10, Rounding.Down); + spawnPositionMaxId += 1; + } + else if (timeSeconds == 30) + { + spawnPositionMaxId += 1; + } + LoopIfConditionIsTrue(); +} + +void GameLogicSetBotProperties() "SUBROUTINE: GAME LOGIC - SET BOT PROPERTIES" +{ + AbortIf(botIsOrisaChild == true); + if (timeMinutes >= 10) + { + if (FilteredArray(lastBoss, ArrayElement() == HeroOf(EventPlayer())) == false) + { + if (activeBoss == false) + { + activeBoss = EventPlayer(); + isBoss[0] = 1; + } + } + } + End(); + # PROPERTIES BY DEFAULT + SetGravity(EventPlayer(), 100); + SetDamageDealt(EventPlayer(), 100); + SetRespawnMaxTime(EventPlayer(), 10); + StartScalingPlayer(EventPlayer(), 1, false); + # INDIVIDUAL HERO'S PROPERTIES + if (HeroOf(EventPlayer()) == Hero.Zenyatta) + { + if (isBoss[0] == 1) + { + SetMoveSpeed(EventPlayer(), 30); + SetMaxHealth(EventPlayer(), 10 * (100 + 10 * timeMinutes + 25 * time5Minutes + 50 * time10Minutes) * (upgradeBossHealthValue >= upgradeCriticalDamageMaxValue[2] ? 0.9 : 1)); + StartScalingPlayer(EventPlayer(), 1.5, false); + } + else + { + if (20 + 3 * NumberOfPlayers(Team.Team1) + 3 * timeMinutes > 75) + { + SetMoveSpeed(EventPlayer(), 75); + } + else + { + SetMoveSpeed(EventPlayer(), 20 + 3 * CountOf(AllPlayers(Team.Team1)) + 3 * timeMinutes); + } + SetMaxHealth(EventPlayer(), 100 + 10 * timeMinutes + 25 * time5Minutes + 50 * time10Minutes); + } + } + else if (HeroOf(EventPlayer()) == Hero.WreckingBall) + { + if (isBoss[0] == 1) + { + SetMoveSpeed(EventPlayer(), 20); + SetMaxHealth(EventPlayer(), 5 * (70 + 10 * CountOf(AllPlayers(Team.Team1)) + 10 * timeMinutes + 25 * time5Minutes + 30 * time10Minutes) * (upgradeBossHealthValue >= upgradeCriticalDamageMaxValue[2] ? 0.9 : 1)); + StartScalingPlayer(EventPlayer(), 2, false); + } + else if (isBoss[1] == 1) + { + SetMoveSpeed(EventPlayer(), 50); + SetMaxHealth(EventPlayer(), 40 + 7 * CountOf(AllPlayers(Team.Team1)) + 5 * timeMinutes + 20 * time5Minutes + 15 * time10Minutes); + StartScalingPlayer(EventPlayer(), 0.5, false); + } + else + { + if (30 + timeMinutes + 2.5 * time5Minutes > 40) + { + SetMoveSpeed(EventPlayer(), 40); + } + else + { + SetMoveSpeed(EventPlayer(), 30 + timeMinutes + 2.5 * time5Minutes); + } + SetUltimateCharge(EventPlayer(), 0); + SetMaxHealth(EventPlayer(), 70 + 10 * CountOf(AllPlayers(Team.Team1)) + 10 * timeMinutes + 25 * time5Minutes + 30 * time10Minutes); + } + } + else if (HeroOf(EventPlayer()) == Hero.Widowmaker) + { + if (isBoss[0] == 1) + { + SetDamageDealt(EventPlayer(), 2 * (55 + 15 * CountOf(AllPlayers(Team.Team1)) + 25 * time5Minutes + 30 * time10Minutes)); + SetMoveSpeed(EventPlayer(), 100); + SetMaxHealth(EventPlayer(), 5 * (50 + 25 * CountOf(AllPlayers(Team.Team1)) + 5 * timeMinutes + 15 * time5Minutes + 25 * time10Minutes) * (upgradeBossHealthValue >= upgradeCriticalDamageMaxValue[2] ? 0.9 : 1)); + StartScalingPlayer(EventPlayer(), 2, false); + } + else + { + botCounter = 0; + SetDamageDealt(EventPlayer(), 55 + 15 * CountOf(AllPlayers(Team.Team1)) + 25 * time5Minutes + 30 * time10Minutes); + SetMoveSpeed(EventPlayer(), 100); + SetMaxHealth(EventPlayer(), 50 + 25 * CountOf(AllPlayers(Team.Team1)) + 5 * timeMinutes + 15 * time5Minutes + 25 * time10Minutes); + } + } + else if (HeroOf(EventPlayer()) == Hero.Bastion) + { + if (isBoss[0] == 1) + { + SetMoveSpeed(EventPlayer(), 50); + SetDamageDealt(EventPlayer(), 55 + 5 * CountOf(AllPlayers(Team.Team1)) + 5 * time5Minutes + 5 * time10Minutes); + StartScalingPlayer(EventPlayer(), 3, false); + SetMaxHealth(EventPlayer(), 5 * (125 + 150 * CountOf(AllPlayers(Team.Team1)) + 20 * timeMinutes + 35 * time5Minutes + 45 * time10Minutes) * (upgradeBossHealthValue >= upgradeCriticalDamageMaxValue[2] ? 0.9 : 1)); + } + else if (isBoss[1] == 1) + { + SetMoveSpeed(EventPlayer(), 100); + SetDamageDealt(EventPlayer(), 20 + 2 * CountOf(AllPlayers(Team.Team1)) + 2 * time5Minutes + 5 * time10Minutes); + SetMaxHealth(EventPlayer(), 60 + 60 * CountOf(AllPlayers(Team.Team1)) + 10 * timeMinutes + 20 * time5Minutes + 20 * time10Minutes); + } + else + { + SetMoveSpeed(EventPlayer(), 80); + SetDamageDealt(EventPlayer(), 55 + 5 * CountOf(AllPlayers(Team.Team1)) + 5 * time5Minutes + 5 * time10Minutes); + StartScalingPlayer(EventPlayer(), 2, false); + SetMaxHealth(EventPlayer(), 125 + 150 * CountOf(AllPlayers(Team.Team1)) + 20 * timeMinutes + 35 * time5Minutes + 45 * time10Minutes); + } + } + else if (HeroOf(EventPlayer()) == Hero.Orisa) + { + if (isBoss[0] == 1) + { + StartScalingPlayer(EventPlayer(), 1.8, false); + SetMaxHealth(EventPlayer(), 5 * (200 + CountOf(AllPlayers(Team.Team1)) * 70 + 50 * time5Minutes + 75 * time10Minutes) * (upgradeBossHealthValue >= upgradeCriticalDamageMaxValue[2] ? 0.9 : 1)); + SetMoveSpeed(EventPlayer(), 20 + 5 * time5Minutes); + } + else + { + StartScalingPlayer(EventPlayer(), 1.8, false); + SetMaxHealth(EventPlayer(), 200 + CountOf(AllPlayers(Team.Team1)) * 70 + 50 * time5Minutes + 75 * time10Minutes); + SetMoveSpeed(EventPlayer(), 80 + 5 * time5Minutes); + } + } + else if (HeroOf(EventPlayer()) == Hero.Echo) + { + if (isBoss[0] == 1) + { + SetGravity(EventPlayer(), 40); + SetMoveSpeed(EventPlayer(), 50 + 5 * time5Minutes); + SetRespawnMaxTime(EventPlayer(), 18); + SetMaxHealth(EventPlayer(), 5 * (70 + 25 * CountOf(AllPlayers(Team.Team1)) + 15 * timeMinutes + 25 * time5Minutes + 40 * time10Minutes) * (upgradeBossHealthValue >= upgradeCriticalDamageMaxValue[2] ? 0.9 : 1)); + StartScalingPlayer(EventPlayer(), 2, false); + } + else + { + SetGravity(EventPlayer(), 40); + SetMoveSpeed(EventPlayer(), 110 + 5 * time5Minutes); + SetRespawnMaxTime(EventPlayer(), 18); + SetMaxHealth(EventPlayer(), 70 + 25 * CountOf(AllPlayers(Team.Team1)) + 15 * timeMinutes + 25 * time5Minutes + 40 * time10Minutes); + } + } + else if (HeroOf(EventPlayer()) == Hero.Reinhardt) + { + if (isBoss[0] == 1) + { + StartScalingPlayer(EventPlayer(), 1.5, false); + SetMoveSpeed(EventPlayer(), 50); + SetDamageDealt(EventPlayer(), 80 + 5 * CountOf(AllPlayers(Team.Team1)) + 5 * time5Minutes + 8 * time10Minutes); + SetRespawnMaxTime(EventPlayer(), 15); + SetMaxHealth(EventPlayer(), 5 * (45 + 25 * CountOf(AllPlayers(Team.Team1)) + 15 * timeMinutes + 25 * time5Minutes + 40 * time10Minutes) * (upgradeBossHealthValue >= upgradeCriticalDamageMaxValue[2] ? 0.9 : 1)); + } + else if (isBoss[1] == 1) + { + StartScalingPlayer(EventPlayer(), 0.5, false); + SetMoveSpeed(EventPlayer(), 100); + SetDamageDealt(EventPlayer(), 30 + 2 * CountOf(AllPlayers(Team.Team1)) + 2 * time5Minutes + 5 * time10Minutes); + SetMaxHealth(EventPlayer(), 20 + 10 * CountOf(AllPlayers(Team.Team1)) + 10 * timeMinutes + 10 * time5Minutes + 20 * time10Minutes); + } + else + { + SetMoveSpeed(EventPlayer(), 90); + SetDamageDealt(EventPlayer(), 80 + 5 * CountOf(AllPlayers(Team.Team1)) + 5 * time5Minutes + 8 * time10Minutes); + SetRespawnMaxTime(EventPlayer(), 15); + SetMaxHealth(EventPlayer(), 45 + 25 * CountOf(AllPlayers(Team.Team1)) + 15 * timeMinutes + 25 * time5Minutes + 40 * time10Minutes); + } + } + Wait(0.25, WaitBehavior.IgnoreCondition); + # FILL HEALTH + Heal(EventPlayer(), null, 100000); +} + +disabled rule: "=== GATE ===" +{ +} + +void UpdatePlayerStats() "Subroutine: UPDATE PLAYER STATS" +{ + damageBoost[0] = (upgradeMaxAmmoValue >= upgradeMaxAmmoMaxValue[1] ? 50 : 0) + abilities[13] * 5 + damageBoost[1]; + SetDamageDealt(EventPlayer(), baseStats[0] + damageBoost); + playerHealth = maxHealthDone + abilities[14] * 5; + SetMaxHealth(EventPlayer(), baseStats[1] + playerHealth); + healBoost[0] = healBoost[1] + abilities[15] * 5; + SetHealingDealt(EventPlayer(), baseStats[2] + healBoost[0]); + SetMoveSpeed(EventPlayer(), baseStats[3] + speedBoost); +} + +void GateRepair() "Subroutine: GATE REPAIR" +{ + # UPGRADE - GATE'S MAX HEALTH + if (upgradeGateMaxHealthValue < upgradeGateMaxHealthMaxValue[2]) + { + if (gateMaxHealth[0] - gateHealth > (HeroOf(EventPlayer()) == Hero.Symmetra ? 2 : 10) * (upgradeGateMaxHealthValue >= upgradeGateMaxHealthMaxValue[1] ? 2 : 1) * (isNanoed == 1 ? 2 : 1)) + { + upgradeGateMaxHealthValue += (HeroOf(EventPlayer()) == Hero.Symmetra ? 2 : 10) * (upgradeGateMaxHealthValue >= upgradeGateMaxHealthMaxValue[1] ? 2 : 1) * (isNanoed == 1 ? 2 : 1); + } + else + { + upgradeGateMaxHealthValue += gateMaxHealth[0] - gateHealth; + } + } + # HEAL GATE + if (gateMaxHealth[0] - gateHealth > (HeroOf(EventPlayer()) == Hero.Symmetra ? 2 : 10) * (upgradeGateMaxHealthValue >= upgradeGateMaxHealthMaxValue[1] ? 2 : 1) * (isNanoed == 1 ? 2 : 1)) + { + gateHealth += (HeroOf(EventPlayer()) == Hero.Symmetra ? 2 : 10) * (upgradeGateMaxHealthValue >= upgradeGateMaxHealthMaxValue[1] ? 2 : 1) * (isNanoed == 1 ? 2 : 1); + } + else + { + gateHealth += gateMaxHealth[0] - gateHealth; + } + # CHARGE ULTIMATE + SetUltimateCharge(EventPlayer(), UltimateChargePercent(EventPlayer()) + 2); + # UPDATE GATE'S HEALTH BAR + async GateProgressBarColor(); +} + +rule: "GATE REPAIR" +Event.OngoingPlayer +Team.Team1 +if (IsGameInProgress() == true) +if ((HeroOf(EventPlayer()) == Hero.Torbjorn && Weapon(EventPlayer()) == 2 || HeroOf(EventPlayer()) == Hero.Reinhardt || HeroOf(EventPlayer()) == Hero.Brigitte || HeroBeingDuplicated(EventPlayer()) == Hero.Reinhardt || HeroOf(EventPlayer()) == Hero.Symmetra) == true) +if (IsFiringPrimary(EventPlayer()) == true) +if (gateHealth < gateMaxHealth[0]) +if (IsInViewAngle(EventPlayer(), gateRepairPosition, 30) == true) +if (DistanceBetween(PositionOf(EventPlayer()), gatePosition) < (HeroOf(EventPlayer()) == Hero.Brigitte ? 5 : HeroOf(EventPlayer()) == Hero.Symmetra ? 12 : 3.5)) +{ + if (HeroOf(EventPlayer()) == Hero.Reinhardt) + { + Wait(0.1, WaitBehavior.IgnoreCondition); + } + GateRepair(); + if (HeroOf(EventPlayer()) == Hero.Torbjorn) + { + Wait(IsUsingAbility2(EventPlayer()) == true ? 0.35 : 0.7, WaitBehavior.IgnoreCondition); + } + else if (HeroOf(EventPlayer()) == Hero.Reinhardt) + { + Wait(0.85, WaitBehavior.IgnoreCondition); + } + else if (HeroOf(EventPlayer()) == Hero.Symmetra) + { + Wait(0.1, WaitBehavior.IgnoreCondition); + } + else + { + Wait(0.5, WaitBehavior.IgnoreCondition); + } + LoopIfConditionIsTrue(); +} + +void GateProgressBarColor() "SUBROUTINE: GATE PROGRESS BAR COLOR" +{ + StopChasingVariable(gateHealthChase); + ChaseVariableOverTime(gateHealthChase, gateHealth, 0.1, TimeChaseReevaluation.DestinationAndDuration); + # GATE WAS DAMAGED + if (gateHealth < gateHealthEvent) + { + for (loopIterator = 0; 3; 1) + { + gateProgressBarColorCurrent = Color.Red; + Wait(0.1, WaitBehavior.IgnoreCondition); + gateProgressBarColorCurrent = Color.White; + Wait(0.1, WaitBehavior.IgnoreCondition); + } + } + else + { + gateProgressBarColorCurrent = Color.Green; + Wait(0.1, WaitBehavior.IgnoreCondition); + gateProgressBarColorCurrent = Color.Yellow; + Wait(0.1, WaitBehavior.IgnoreCondition); + } + gateHealthEvent = gateHealth; + gateProgressBarColorComponent = gateHealth * 255 / gateMaxHealth[0]; + gateProgressBarColorCurrent = CustomColor(255, gateProgressBarColorComponent, gateProgressBarColorComponent, 255); +} + +disabled rule: "=== COMMON MECHANICS ===" +{ +} + +rule: "ALL: INIT" +Event.OnPlayerJoin +{ + # ALL (COMMON) INIT + isDead = true; + DisableKillFeed(EventPlayer()); + DisableGameModeInworldUI(EventPlayer()); + DisableSpectateHUD(EventPlayer()); + # BOT INIT + if (IsDummyBot(EventPlayer())) + { + BotInit(); + } + else + { + PlayerInit(); + } +} + +void BotInit() "SUBROUTINE: BOT - INIT" +{ + # INIT VARS + hasBadStatus = false; + isRespawning = false; + botDoesUniqueBehaviour = false; + botEventPosition = Vector(9999, 999, 9999); + # DISABLE ALL FOR BOT + DisableHeroHud(EventPlayer()); + DisableMessages(EventPlayer()); + DisableTextChat(EventPlayer()); + DisableScoreboard(EventPlayer()); + DisableGameModeHud(EventPlayer()); + DisableSpectate(EventPlayer()); + DisableVoiceChat(EventPlayer(), true, true, true); + # INIT AI NAVIGATION VARS + BotResetPathFinding(); +} + +void PlayerInit() "SUBROUTINE: PLAYER - INIT" +{ + UpdatePlayerStats(); + if (IsGameInProgress()) + { + DisableGameModeHud(EventPlayer()); + } +} + +rule: "ALL: RESPAWN" +Event.OngoingPlayer +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if ((HeroOf(EventPlayer()) != currentHero || isDead == true) == true) +{ + isDead = false; + # BOT RESPAWN + if (IsDummyBot(EventPlayer())) + { + BotRespawn(); + if (isDebugAINavigation) + { + CreateBeamEffect(AllPlayers(Team.All), BeamType.GoodBeam, EyePosition(EventPlayer()), botNextNodePosition, Color.Green, EffectRev.VisibleToPositionAndRadius); + } + } + else + { + PlayerRespawn(); + } + # MUST BE AFTER ALL RESPAWN SUBROUTINES! + currentHero = HeroOf(EventPlayer()); +} + +void BotRespawn() "SUBROUTINE: BOT - RESPAWN" +{ + # RESET COMMON PROPERTIES + isRespawning = true; + EnableNameplates(EventPlayer(), AllPlayers(Team.Team1)); + BotResetPathFinding(); + GameLogicSetBotProperties(); + # INDIVIDUAL HERO'S RESPAWN SCRIPTS + if (HeroOf(EventPlayer()) == Hero.Bastion) + { + BotBastionRespawn(); + } + else if (HeroOf(EventPlayer()) == Hero.Zenyatta) + { + BotZenyattaRespawn(); + } + else if (HeroOf(EventPlayer()) == Hero.Widowmaker) + { + BotWidowRespawn(); + } + else if (HeroOf(EventPlayer()) == Hero.WreckingBall) + { + BotBallRespawn(); + } + else if (HeroOf(EventPlayer()) == Hero.Orisa) + { + BotOrisaRespawn(); + } + else if (HeroOf(EventPlayer()) == Hero.Echo) + { + BotEchoRespawn(); + } + else if (HeroOf(EventPlayer()) == Hero.Reinhardt) + { + BotReinRespawn(); + } + isRespawning = false; +} + +void PlayerRespawn() "SUBROUTINE: PLAYER - RESPAWN" +{ + # TEAM CHALLENGE - MAX AMMO + if (HeroOf(EventPlayer()) != currentHero && upgradeMaxAmmoValue >= upgradeMaxAmmoMaxValue[0]) + { + SetMaxAmmo(EventPlayer(), 0, Ammo(EventPlayer(), 0) * 2); + SetMaxAmmo(EventPlayer(), 1, Ammo(EventPlayer(), 1) * 2); + SetAmmo(EventPlayer(), 0, MaxAmmo(EventPlayer(), 0)); + SetAmmo(EventPlayer(), 1, MaxAmmo(EventPlayer(), 1)); + } + # PLAYER RESPAWN + SetStatus(EventPlayer(), null, Status.PhasedOut, 3); + SetFacing(EventPlayer(), Vector(-1, 0, 0), Relative.ToWorld); + if (AbilityCooldown(PlayersOnHero(Hero.Mercy, Team.Team1), Button.Ability2) >= 30 * (PlayersOnHero(Hero.Mercy, Team.Team1).abilities[6] ? PlayersOnHero(Hero.Mercy, Team.Team1).abilities[6] * 0.25 : 1) - 1) + { + Wait(0.25, WaitBehavior.IgnoreCondition); + Teleport(EventPlayer(), deathPosition); + } + else + { + Teleport(EventPlayer(), playerSpawnPositions[SlotOf(EventPlayer()) == CountOf(playerSpawnPositions) ? RandomInteger(0, CountOf(playerSpawnPositions) - 1) : SlotOf(EventPlayer())]); + } + UpdatePlayerStats(); +} + +rule: "PLAYER: DEATH" +Event.OnDeath +Team.Team1 +{ + if (HeroOf(EventPlayer()) == Hero.Roadhog) + { + abilities[8] -= 1; + Wait(perk[2] ? 5 : 10, WaitBehavior.IgnoreCondition); + abilities[8] += 1; + } + deathPosition = PositionOf(EventPlayer()); + isDead = true; +} + +rule: "BOT: DEATH" +Event.OnDeath +Team.Team2 +{ + deathPosition = PositionOf(EventPlayer()); + if (isBoss[0] == 1) + { + if (upgradePerkSharpshooterValue >= upgradeCriticalDamageMaxValue[1] && upgradeBossHealthValue < upgradeCriticalDamageMaxValue[2]) + { + upgradeBossHealthValue += 1; + } + isBoss[0] = 0; + activeBoss = null; + } + else if (isBoss[1] == 1) + { + if (HeroOf(EventPlayer()) == Hero.WreckingBall) + { + DestroyEffect(botEffects[0]); + } + Wait(1, WaitBehavior.IgnoreCondition); + ForcePlayerHero(EventPlayer(), RandomInteger(1, 100) > 50 ? Hero.Reinhardt : RandomInteger(1, 100) > 33 ? Hero.WreckingBall : CountOf(FilteredArray(AllPlayers(Team.Team2), HeroOf(ArrayElement()) == Hero.Zenyatta)) > 0 ? Hero.WreckingBall : Hero.Bastion); + } + isDead = true; + hasBadStatus = false; + botDoesUniqueBehaviour = false; + DisableNameplates(EventPlayer(), AllPlayers(Team.Team1)); + # BOT HAS 1 EFFECT IN VAR (NOT ARRAY) + SkipIf(!EntityExists(botEffects), 1); + DestroyEffect(botEffects); + # BOT HAS MORE THEN 1 EFFECT IN VAR (ARRAY) + SkipIf(CountOf(botEffects) == 0, 3); + for (botLoopIterator1 = 0; CountOf(botEffects); 1) + { + DestroyEffect(botEffects[botLoopIterator1]); + } +} + +disabled rule: "=== BOT COMMON MECHANICS ===" +{ +} + +rule: "BOT: BAD STATUS" +Event.OngoingPlayer +Team.Team2 +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (hasBadStatus == false) +if ((HasStatus(EventPlayer(), Status.Hacked) || HasStatus(EventPlayer(), Status.Frozen) || HasStatus(EventPlayer(), Status.KnockedDown) || HasStatus(EventPlayer(), Status.Asleep) || HasStatus(EventPlayer(), Status.Stunned)) == true) +{ + hasBadStatus = true; + # PROCESS BAD STATUS + if (HeroOf(EventPlayer()) == Hero.Widowmaker) + { + async! BotWidowBadStatus(); + } + WaitUntil(!HasStatus(EventPlayer(), Status.KnockedDown) && !HasStatus(EventPlayer(), Status.Asleep) && !HasStatus(EventPlayer(), Status.Frozen) && !HasStatus(EventPlayer(), Status.Stunned), 15); + hasBadStatus = false; +} + +void BotLandingFromSky() "SUBROUTINE: BOT - LANDING FROM SKY" +{ + StopThrottleInDirection(EventPlayer()); + # SET RESPAWN POSITION + botEventPosition = RandomValueInArray(bigBossSpawnPositions); + # CREATE EFFECTS + CreateEffect(AllPlayers(Team.Team1), Effect.LightShaft, Color.Red, botEventPosition, 3, EffectRev.VisibleTo); + botEffects[0] = LastCreatedEntity(); + # RESPAWN IN LIGHT SHAFT EFFECT + Teleport(EventPlayer(), botEventPosition + Vector(0, 25, 0)); + Wait(0.1, WaitBehavior.IgnoreCondition); + # SLOW LANDING + SetGravity(EventPlayer(), 50); + while (IsInAir(EventPlayer()) == true) + { + PlayEffect(AllPlayers(Team.Team1), PlayEffect.GoodPickupEffect, Color.Orange, PositionOf(EventPlayer()) + Vector(0, -2.7, 0), 2); + Wait(0.25, WaitBehavior.IgnoreCondition); + } + SetGravity(EventPlayer(), 100); + DestroyEffect(botEffects[0]); + # LANDING EFFECTS + PlayEffect(AllPlayers(Team.Team1), PlayEffect.WreckingBallPiledriverImpactEffect, CustomColor(105, 87, 46, 255), PositionOf(EventPlayer()), 8); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.DoomfistMeteorStrikeImpactSound, Color.White, PositionOf(EventPlayer()), 150); +} + +void BotAppearFromUnderground() "SUBROUTINE: BOT - APPEAR FROM UNDERGROUND" +{ + SetStatus(EventPlayer(), null, Status.KnockedDown, 1); + Wait(0.2, WaitBehavior.IgnoreCondition); + SetGravity(EventPlayer(), 20); + DisableMovementCollisionWithEnvironment(EventPlayer(), true); + Teleport(EventPlayer(), zenSpawnPositions[RandomInteger(Min(timeMinutes, CountOf(zenSpawnPositions) - 10), Min(spawnPositionMaxId, CountOf(zenSpawnPositions) - 4))] + Vector(0, -1.5, 0)); + Wait(0.1, WaitBehavior.IgnoreCondition); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.SigmaAccretionImpactEffect, CustomColor(220, 175, 100, 255), EyePosition(EventPlayer()), 3); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.SigmaAccretionImpactSound, Color.Gray, EyePosition(EventPlayer()), 50); + ApplyImpulse(EventPlayer(), Up(), 3.5, Relative.ToWorld, ContraryMotion.Cancel); + Wait(0.4, WaitBehavior.IgnoreCondition); + ClearStatus(EventPlayer(), Status.KnockedDown); + SetGravity(EventPlayer(), 100); + EnableMovementCollisionWithEnvironment(EventPlayer()); +} + +disabled rule: "=== PLAYER MECHANICS ===" +{ +} + +rule: "PLAYER: HEALTH REGEN" +Event.OnDamageTaken +Team.Team1 +{ + StopHealOverTime(healOverTimeId); + eventHealth = Health(EventPlayer()); + Wait(4, WaitBehavior.IgnoreCondition); + # TOOK DAMAGE, RESET REGENERATION TIMER + LoopIf(IsAlive(EventPlayer()) && eventHealth > Health(EventPlayer())); + StartHealOverTime(EventPlayer(), null, 3, MaxHealth(EventPlayer()) / 3); + healOverTimeId = LastHealOverTime(); +} + +disabled rule: "=== ZENYATTA ===" +{ +} + +rule: "BOT: ZEN - REACHED THE GATE" +Event.OngoingPlayer +Team.Team2 +Player.Zenyatta +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (isRespawning == false) +if (botIsPathFinding == false) +{ + SetAmmo(EventPlayer(), 0, 0); + Communicate(EventPlayer(), Communication.Hello); + Wait(1.5, WaitBehavior.IgnoreCondition); + AbortIf(IsDead(EventPlayer()) == true); + Kill(EventPlayer(), null); +} + +rule: "BOT: ZEN - DEATH" +Event.OnDeath +Team.Team2 +Player.Zenyatta +{ + # EFFECT + PlayEffect(AllPlayers(Team.Team1), PlayEffect.JunkratFragLauncherExplosionEffect, Color.Red, EyePosition(EventPlayer()), 2.5); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.AsheDynamiteExplosionSound, Color.Red, EyePosition(EventPlayer()), 70); + # DAMAGE AND APPLY IMPULSE TO PLAYERS + botPlayersInRadius = PlayersWithinRadius(PositionOf(EventPlayer()), 2.5, Team.All, RadiusLOS.SurfacesAndEnemyBarriers); + for (botLoopIterator1 = 0; CountOf(botPlayersInRadius); 1) + { + ApplyImpulse(botPlayersInRadius[botLoopIterator1], DirectionTowards(PositionOf(EventPlayer()), EyePosition(botPlayersInRadius[botLoopIterator1])), 5, Relative.ToWorld, ContraryMotion.Incorporate); + if (TeamOf(botPlayersInRadius[botLoopIterator1]) == Team.Team1) + { + Damage(botPlayersInRadius[botLoopIterator1], EventPlayer(), 50); + } + } + # DAMAGE GATE + if (DistanceBetween(PositionOf(EventPlayer()), gatePosition) < 3 && IsInLineOfSight(EyePosition(EventPlayer()), gatePosition, BarrierLOS.EnemyBarriersBlock)) + { + if (isBoss[0] == 1) + { + gateHealth -= 125; + } + else + { + gateHealth -= 25 + 5 * time5Minutes; + } + async GateProgressBarColor(); + Respawn(EventPlayer()); + Abort(); + } + # KILLED BY PLAYER + Teleport(EventPlayer(), Vector(0, -999, 0)); + Wait(2, WaitBehavior.IgnoreCondition); + Respawn(EventPlayer()); + Wait(2, WaitBehavior.IgnoreCondition); +} + +void BotZenyattaRespawn() "SUBROUTINE: ZEN - RESPAWN" +{ + BotAppearFromUnderground(); + botTargetPosition = gatePosition; + botIsPathFinding = true; + async! BotStartPathFinding(); + StartFacing(EventPlayer(), DirectionTowards(PositionOf(EventPlayer()), botNextNodePosition), 360, Relative.ToWorld, FacingRev.DirectionAndTurnRate); +} + +disabled rule: "=== WRECKING BALL ===" +{ +} + +rule: "BOT: BALL - REACHED THE GATE" +Event.OngoingPlayer +Team.Team2 +Player.WreckingBall +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (isRespawning == false) +if (botIsPathFinding == false) +{ + StartHoldingButton(EventPlayer(), Button.Ability1); + SetAmmo(EventPlayer(), 0, 0); + Wait(1, WaitBehavior.IgnoreCondition); + SetUltimateCharge(EventPlayer(), 100); + StartHoldingButton(EventPlayer(), Button.Ultimate); + WaitUntil(IsUsingUltimate(EventPlayer()), 0.6); + AbortIf(IsDead(EventPlayer())); + Kill(EventPlayer(), null); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.JunkratRipTireExplosionEffect, Color.Orange, EyePosition(EventPlayer()), 6); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.DvaSelfDestructExplosionSound, Color.White, EyePosition(EventPlayer()), 250); + if (DistanceBetween(PositionOf(EventPlayer()), gatePosition) < 3.5 && IsInLineOfSight(EyePosition(EventPlayer()), gatePosition, BarrierLOS.EnemyBarriersBlock)) + { + if (isBoss[0] == 1) + { + gateHealth -= 300; + } + else if (isBoss[1] == 1) + { + gateHealth -= 50; + } + else + { + gateHealth -= 150 + 10 * time5Minutes; + } + async GateProgressBarColor(); + } + Damage(PlayersWithinRadius(EyePosition(EventPlayer()), 5, Team.Team1, RadiusLOS.SurfacesAndAllBarriers), EventPlayer(), 100); +} + +rule: "BOT: BALL - ALTERNATIVE FORM" +Event.OngoingPlayer +Team.Team2 +Player.WreckingBall +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsInAlternateForm(EventPlayer()) == false) +{ + StartHoldingButton(EventPlayer(), Button.Ability1); + WaitUntil(IsInAlternateForm(EventPlayer()), 10); + StopHoldingButton(EventPlayer(), Button.Ability1); +} + +rule: "BOT: BALL - DEATH" +Event.OnDeath +Team.Team2 +Player.WreckingBall +{ + StopHoldingButton(EventPlayer(), Button.Ability1); + StopHoldingButton(EventPlayer(), Button.Ultimate); +} + +void BotBallRespawn() "SUBROUTINE: BALL - RESPAWN" +{ + # RESPAWN IN AIR + Teleport(EventPlayer(), RandomValueInArray(ballSpawnPositions) + Vector(0, 20, 0)); + StopHoldingButton(EventPlayer(), Button.Ultimate); + Wait(0.25, WaitBehavior.IgnoreCondition); + # LANDING + StartHoldingButton(EventPlayer(), Button.Crouch); + WaitUntil(IsOnGround(EventPlayer()), 9999); + StopHoldingButton(EventPlayer(), Button.Crouch); + # LANDING IMPACT EFFECT + PlayEffect(AllPlayers(Team.Team1), PlayEffect.SigmaAccretionImpactSound, Color.White, EventPlayer(), 150); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.DoomfistMeteorStrikeImpactEffect, Color.Gray, PositionOf(EventPlayer()), 10); + CreateEffect(AllPlayers(Team.Team1), Effect.BadAura, Color.Orange, EyePosition(EventPlayer()), 1.5, EffectRev.VisibleToPositionAndRadius); + botEffects[0] = LastCreatedEntity(); + # PATH FINDING TO GATE + botTargetPosition = gatePosition; + botIsPathFinding = true; + async! BotStartPathFinding(); +} + +disabled rule: "=== ECHO ===" +{ +} + +rule: "BOT: ECHO - FLY ABILITY" +Event.OngoingPlayer +Team.Team2 +Player.Echo +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (isRespawning == false) +if (botIsPathFinding == false) +if (IsUsingAbility1(EventPlayer()) == false) +{ + SetAbilityCooldown(EventPlayer(), Button.Ability1, 0); + PressButton(EventPlayer(), Button.Ability1); + Wait(0.3, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); +} + +rule: "BOT: ECHO - BEAM ABILITY" +Event.OngoingPlayer +Team.Team2 +Player.Echo +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (isRespawning == false) +if (IsUsingAbility1(EventPlayer()) == false) +if (botDoesUniqueBehaviour == true) +{ + SetAbilityCooldown(EventPlayer(), Button.Ability2, 0); + PressButton(EventPlayer(), Button.Ability2); +} + +rule: "BOT: ECHO - BAD STATUS - RESET BEAM" +Event.OngoingPlayer +Team.Team2 +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (isRespawning == false) +if (hasBadStatus == true) +{ + if (botDoesUniqueBehaviour) + { + BotEchoDetachPlayer(); + } + WaitUntil(hasBadStatus, 7); +} + +rule: "BOT: ECHO - CAN'T SEE PORTAL - APPLY IMPULSE" +Event.OngoingPlayer +Team.Team2 +Player.Echo +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (isRespawning == false) +if (botDoesUniqueBehaviour == true) +if (IsInLineOfSight(PositionOf(EventPlayer()), botEchoRespawnPosition, BarrierLOS.NoBarriersBlock) == false) +{ + Wait(0.3, WaitBehavior.AbortWhenFalse); + ApplyImpulse(EventPlayer(), Vector(RandomInteger(-1, 1), 1, RandomInteger(-1, 1)), 20, Relative.ToWorld, ContraryMotion.Incorporate); + Wait(1, WaitBehavior.IgnoreCondition); + if (!IsInLineOfSight(PositionOf(EventPlayer()), botEchoRespawnPosition, BarrierLOS.NoBarriersBlock)) + { + botTargetPosition = botEchoRespawnPosition; + async BotStartPathFinding(); + } + else + { + BotResetPathFinding(); + } + LoopIfConditionIsTrue(); +} + +rule: "BOT: ECHO - MAIN LOGIC - LOOP" +Event.OngoingPlayer +Team.Team2 +Player.Echo +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (isRespawning == false) +{ + if (botDoesUniqueBehaviour == false) + { + botSeePlayer = SortedArray(FilteredArray(AllLivingPlayers(Team.Team1), HasSpawned(ArrayElement()) == true && ArrayElement().isInMenu[0] == false && (HeroOf(ArrayElement()) == Hero.Sombra && IsUsingAbility1(ArrayElement())) == false && IsInLineOfSight(EyePosition(EventPlayer()), EyePosition(ArrayElement()), BarrierLOS.NoBarriersBlock) == true), DistanceBetween(PositionOf(EventPlayer()), PositionOf(ArrayElement())))[0]; + } + # TELEPORT PLAYER SO FAR + if (botDoesUniqueBehaviour && DistanceBetween(PositionOf(botEchoCapturedPlayer), botEchoRespawnPosition) < 4) + { + PlayEffect(AllPlayers(Team.Team1), PlayEffect.BadPickupEffect, Color.White, botEchoRespawnPosition, 1); + Teleport(botEchoCapturedPlayer, RandomValueInArray(botEchoTeleportPositions)); + SetStatus(botEchoCapturedPlayer, EventPlayer(), Status.KnockedDown, 1); + BotEchoDetachPlayer(); + } + # BEGIN TO FLY TO THE PORTAL WITH A PLAYER + if (botDoesUniqueBehaviour) + { + StartFacing(EventPlayer(), DirectionTowards(EyePosition(EventPlayer()), botEchoRespawnPosition), 100, Relative.ToWorld, FacingRev.DirectionAndTurnRate); + # BOT SEES THE PORTAL + if (IsInLineOfSight(PositionOf(EventPlayer()), botEchoRespawnPosition, BarrierLOS.NoBarriersBlock)) + { + # RESET PATH FINDING + if (botIsPathFinding) + { + BotResetPathFinding(); + } + StartThrottleInDirection(EventPlayer(), DirectionTowards(EyePosition(EventPlayer()), botEchoRespawnPosition), 1, Relative.ToWorld, ThrottleBehavior.ReplaceExistingThrottle, ThrottleRev.DirectionAndMagnitude); + } + else if (!botIsPathFinding) + { + botTargetPlayer = botEchoCapturedPlayer; + StopHoldingButton(EventPlayer(), Button.Jump); + async BotStartPathFinding(); + } + } + Wait(0.5, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); +} + +rule: "BOT: ECHO - DEFEND PORTAL" +Event.OngoingPlayer +Team.Team2 +Player.Echo +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (botSeePlayer == null) +if (isRespawning == false) +if (botIsPathFinding == false) +if (botDoesUniqueBehaviour == false) +{ + BotEchoFlyToPortal(); +} + +rule: "BOT: ECHO - CAN SEE PLAYER" +Event.OngoingPlayer +Team.Team2 +Player.Echo +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (botSeePlayer != null) +if (isRespawning == false) +if (botDoesUniqueBehaviour == false) +if (IsInLineOfSight(EyePosition(EventPlayer()), EyePosition(botSeePlayer), BarrierLOS.NoBarriersBlock) == true) +if (botSeePlayer.isInMenu[0] == false) +{ + if (botIsPathFinding) + { + BotResetPathFinding(); + } + BotEchoFlyToPlayer(); +} + +rule: "BOT: ECHO - PATH FINDING TO PLAYER" +Event.OngoingPlayer +Team.Team2 +Player.Echo +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (botSeePlayer != null) +if (isRespawning == false) +if (botIsPathFinding == false) +if (botDoesUniqueBehaviour == false) +if (IsInLineOfSight(EyePosition(EventPlayer()), EyePosition(botSeePlayer), BarrierLOS.NoBarriersBlock) == false) +{ + botTargetPlayer = botSeePlayer; + StopHoldingButton(EventPlayer(), Button.Jump); + BotStartPathFinding(); +} + +rule: "BOT: ECHO - ATTACH PLAYER BY BEAM" +Event.OngoingPlayer +Team.Team2 +Player.Echo +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (hasBadStatus == false) +if (botSeePlayer != null) +if (isRespawning == false) +if (botEchoCapturedPlayer == null) +if (botDoesUniqueBehaviour == false) +if (IsInLineOfSight(EyePosition(EventPlayer()), EyePosition(botSeePlayer), BarrierLOS.NoBarriersBlock) == true) +if (DistanceBetween(PositionOf(EventPlayer()), PositionOf(botSeePlayer)) < 3) +{ + botDoesUniqueBehaviour = true; + botEchoCapturedPlayer = botSeePlayer; + SetStatus(botEchoCapturedPlayer, EventPlayer(), Status.Stunned, 0.7); + SetStatus(botEchoCapturedPlayer, EventPlayer(), Status.Hacked, 10); + AttachPlayers(botEchoCapturedPlayer, EventPlayer(), Vector(0, 0, 2)); + PressButton(EventPlayer(), Button.Ability2); +} + +rule: "BOT: ECHO - PLAYER DEAD" +Event.OngoingPlayer +Team.Team2 +Player.Echo +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (isRespawning == false) +if (IsDead(botEchoCapturedPlayer) != null) +{ + if (botDoesUniqueBehaviour) + { + BotEchoDetachPlayer(); + } + if (botIsPathFinding) + { + BotResetPathFinding(); + } + BotEchoFlyToPortal(); +} + +rule: "BOT: ECHO - DEATH" +Event.OnDeath +Team.Team2 +Player.Echo +{ + BotEchoDetachPlayer(); + StopHoldingButton(EventPlayer(), Button.Jump); + Wait(5, WaitBehavior.IgnoreCondition); + Teleport(EventPlayer(), Vector(0, 999, 0)); + ForcePlayerHero(EventPlayer(), Hero.Orisa); +} + +void BotEchoRespawn() "SUBROUTINE: ECHO - RESPAWN" +{ + botCounter = 0; + botEffects = []; + CreateEffect(AllPlayers(Team.Team1), Effect.GoodAura, Color.SkyBlue, botEchoRespawnPosition, botCounter, EffectRev.VisibleToPositionAndRadius); + ModifyVariable(botEffects, Operation.AppendToArray, LastCreatedEntity()); + CreateEffect(AllPlayers(Team.Team1), Effect.BadAura, Color.SkyBlue, botEchoRespawnPosition, botCounter, EffectRev.VisibleToPositionAndRadius); + ModifyVariable(botEffects, Operation.AppendToArray, LastCreatedEntity()); + CreateEffect(AllPlayers(Team.Team1), Effect.EnergySound, Color.White, botEchoRespawnPosition, 200, EffectRev.VisibleTo); + ModifyVariable(botEffects, Operation.AppendToArray, LastCreatedEntity()); + ChaseVariableOverTime(botCounter, 3, 0.8, TimeChaseReevaluation.DestinationAndDuration); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.JunkratRipTireExplosionEffect, Color.SkyBlue, botEchoRespawnPosition, 12); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.SombraEmpExplosionSound, null, botEchoRespawnPosition, 100); + Wait(3, WaitBehavior.IgnoreCondition); + Teleport(EventPlayer(), botEchoRespawnPosition); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.GoodExplosion, Color.White, botEchoRespawnPosition, 2.5); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.DebuffImpactSound, null, botEchoRespawnPosition, 100); +} + +void BotEchoFlyToPlayer() "SUBROUTINE: ECHO - FLY TO PLAYER" +{ + StartFacing(EventPlayer(), DirectionTowards(EyePosition(EventPlayer()), EyePosition(botSeePlayer)), 300, Relative.ToWorld, FacingRev.DirectionAndTurnRate); + StartThrottleInDirection(EventPlayer(), DirectionTowards(EyePosition(EventPlayer()), EyePosition(botSeePlayer)), 1, Relative.ToWorld, ThrottleBehavior.ReplaceExistingThrottle, ThrottleRev.DirectionAndMagnitude); + StopHoldingButton(EventPlayer(), Button.Jump); +} + +void BotEchoFlyToPortal() "SUBROUTINE: ECHO - FLY TO PORTAL" +{ + StartFacing(EventPlayer(), DirectionTowards(EyePosition(EventPlayer()), botEchoRespawnPosition), 100, Relative.ToWorld, FacingRev.DirectionAndTurnRate); + StartThrottleInDirection(EventPlayer(), DirectionTowards(EyePosition(EventPlayer()), botEchoRespawnPosition), 1, Relative.ToWorld, ThrottleBehavior.ReplaceExistingThrottle, ThrottleRev.DirectionAndMagnitude); + StartHoldingButton(EventPlayer(), Button.Jump); +} + +void BotEchoDetachPlayer() "SUBROUTINE: ECHO - DETACH PLAYER" +{ + DetachPlayers(botEchoCapturedPlayer); + ClearStatus(botEchoCapturedPlayer, Status.Hacked); + # IF PLAYER INSIDE THE WALL + if (IsInLineOfSight(EyePosition(EventPlayer()), EyePosition(botEchoCapturedPlayer), BarrierLOS.NoBarriersBlock)) + { + Teleport(botEchoCapturedPlayer, PositionOf(EventPlayer())); + } + botDoesUniqueBehaviour = false; + botEchoCapturedPlayer = null; +} + +disabled rule: "=== REINHARDT ===" +{ +} + +rule: "BOT: REIN - SET PLAYER AS TARGET" +Event.OngoingPlayer +Team.Team2 +Player.Reinhardt +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (isRespawning == false) +# CAN SEE PLAYER +if (IsTrueForAny(FilteredArray(AllLivingPlayers(Team.Team1), HasSpawned(ArrayElement()) && ArrayElement().isInMenu[0] == false && (HeroOf(ArrayElement()) == Hero.Sombra && IsUsingAbility1(ArrayElement())) == false), IsInLineOfSight(EyePosition(EventPlayer()), EyePosition(ArrayElement()), BarrierLOS.NoBarriersBlock)) == true) +{ + BotResetPathFinding(); + # SET CLOSEST PLAYER TO BOT AS TARGET AND FOLLOW HIM + botTargetPlayer = SortedArray(FilteredArray(AllLivingPlayers(Team.Team1), HasSpawned(ArrayElement()) == true && ArrayElement().isInMenu[0] == false && (HeroOf(ArrayElement()) == Hero.Sombra && IsUsingAbility1(ArrayElement())) == false && IsInLineOfSight(EyePosition(EventPlayer()), EyePosition(ArrayElement()), BarrierLOS.NoBarriersBlock) == true), DistanceBetween(PositionOf(EventPlayer()), PositionOf(ArrayElement())))[0]; + StartFacing(EventPlayer(), DirectionTowards(PositionOf(EventPlayer()), PositionOf(botTargetPlayer)), 360, Relative.ToWorld, FacingRev.DirectionAndTurnRate); + async BotStartPathFinding(); +} + +rule: "BOT: REIN - SET GATE AS TARGET" +Event.OngoingPlayer +Team.Team2 +Player.Reinhardt +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (isRespawning == false) +# BOT DOESN'T FOLLOW PLAYER +if (botTargetPlayer == -1) +{ + BotResetPathFinding(); + # SET GATE AS TARGET + botTargetPosition = gatePosition; + StartFacing(EventPlayer(), DirectionTowards(PositionOf(EventPlayer()), botNextNodePosition), 360, Relative.ToWorld, FacingRev.DirectionAndTurnRate); + async BotStartPathFinding(); +} + +rule: "BOT: REIN - TARGET DEAD" +Event.OngoingPlayer +Team.Team2 +Player.Reinhardt +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (isRespawning == false) +if (botTargetPlayer != -1) +if ((IsDead(botTargetPlayer) || botTargetPlayer.isInMenu[0] || HeroOf(botTargetPlayer) == Hero.Sombra && IsUsingAbility1(botTargetPlayer)) == true) +{ + BotResetPathFinding(); +} + +rule: "BOT: REIN - ATTACK TARGET" +Event.OngoingPlayer +Team.Team2 +Player.Reinhardt +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (isRespawning == false) +# CAN ATTACK TARGET +if (DistanceBetween(PositionOf(EventPlayer()), botTargetPlayer != -1 ? PositionOf(botTargetPlayer) : gatePosition) < 4) +{ + StartHoldingButton(EventPlayer(), Button.PrimaryFire); + StopHoldingButton(EventPlayer(), Button.SecondaryFire); + # TARGET IS PLAYER + AbortIf(botTargetPlayer != -1); + if (isBoss[0] == 1) + { + # TARGET IS GATE + gateHealth -= 25 + 10 * time10Minutes; + } + else if (isBoss[1] == 1) + { + gateHealth -= 5; + } + else + { + gateHealth -= 5 + 5 * time5Minutes; + } + async GateProgressBarColor(); + Wait(0.9, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); +} + +rule: "BOT: REIN - STOP ATTACK TARGET" +Event.OngoingPlayer +Team.Team2 +Player.Reinhardt +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (isRespawning == false) +# CAN ATTACK TARGET +if (DistanceBetween(PositionOf(EventPlayer()), botTargetPlayer != -1 ? PositionOf(botTargetPlayer) : gatePosition) > 4) +{ + StopHoldingButton(EventPlayer(), Button.PrimaryFire); +} + +rule: "BOT: REIN - USE SHIELD" +Event.OnDamageTaken +Team.Team2 +Player.Reinhardt +if (isBoss[1] == false) +if (DistanceBetween(PositionOf(EventPlayer()), PositionOf(botTargetPlayer)) > 3) +{ + StartFacing(EventPlayer(), DirectionTowards(EyePosition(EventPlayer()), EyePosition(Attacker())), 200, Relative.ToWorld, FacingRev.DirectionAndTurnRate); + StartHoldingButton(EventPlayer(), Button.SecondaryFire); + WaitUntil(DistanceBetween(PositionOf(EventPlayer()), PositionOf(botTargetPlayer)) < 3, 3); + StopHoldingButton(EventPlayer(), Button.SecondaryFire); +} + +rule: "BOT: REIN - CHARGE IN GATE" +Event.OngoingPlayer +Team.Team2 +Player.Reinhardt +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (isRespawning == false) +if (botTargetPlayer == -1) +if (IsUsingAbility1(EventPlayer()) == false) +if (IsInLineOfSight(EyePosition(EventPlayer()), gatePosition, BarrierLOS.NoBarriersBlock) == true) +if (IsInViewAngle(EventPlayer(), gatePosition, 7.5) == true) +{ + StartHoldingButton(EventPlayer(), Button.Ability1); + WaitUntil(IsUsingAbility1(EventPlayer()), 1); + StopHoldingButton(EventPlayer(), Button.Ability1); +} + +rule: "BOT: REIN - DEATH" +Event.OngoingPlayer +Team.Team2 +Player.Reinhardt +{ + StopHoldingButton(EventPlayer(), Button.PrimaryFire); + StopHoldingButton(EventPlayer(), Button.SecondaryFire); +} + +void BotReinRespawn() "SUBROUTINE: REIN - RESPAWN" +{ + BotAppearFromUnderground(); + StartFacing(EventPlayer(), DirectionTowards(PositionOf(EventPlayer()), botNextNodePosition), 360, Relative.ToWorld, FacingRev.DirectionAndTurnRate); +} + +disabled rule: "=== WIDOW ===" +{ +} + +rule: "BOT: WIDOW - SEE PLAYER" +Event.OngoingPlayer +Team.Team2 +Player.Widowmaker +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (IsReloading(EventPlayer()) == false) +if (botSeePlayer == null) +if (hasBadStatus == false) +# CAN SEE PLAYER +if (IsTrueForAny(FilteredArray(AllLivingPlayers(Team.Team1), HasSpawned(ArrayElement()) && ArrayElement().isInMenu[0] == false && (HeroOf(ArrayElement()) == Hero.Sombra && IsUsingAbility1(ArrayElement())) == false), IsInLineOfSight(EyePosition(EventPlayer()), EyePosition(ArrayElement()), BarrierLOS.NoBarriersBlock)) == true) +{ + botSeePlayer = SortedArray(FilteredArray(AllLivingPlayers(Team.Team1), HasSpawned(ArrayElement()) == true && ArrayElement().isInMenu[0] == false && (HeroOf(ArrayElement()) == Hero.Sombra && IsUsingAbility1(ArrayElement())) == false && IsInLineOfSight(EyePosition(EventPlayer()), EyePosition(ArrayElement()), BarrierLOS.NoBarriersBlock) == true), DistanceBetween(PositionOf(EventPlayer()), PositionOf(ArrayElement())))[0]; + botWidowShotTime = TotalTimeElapsed() + (timeMinutes >= 9 ? RandomReal(2, 5) : RandomReal(5, 10)); + StartFacing(EventPlayer(), DirectionTowards(EyePosition(EventPlayer()), EyePosition(botSeePlayer)), 9999, Relative.ToWorld, FacingRev.DirectionAndTurnRate); +} + +rule: "BOT: WIDOW - SHOOT" +Event.OngoingPlayer +Team.Team2 +Player.Widowmaker +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (IsReloading(EventPlayer()) == false) +if (botSeePlayer != null) +if (hasBadStatus == false) +if (TotalTimeElapsed() >= botWidowShotTime) +{ + PressButton(EventPlayer(), Button.PrimaryFire); + StopFacing(EventPlayer()); + botSeePlayer = null; +} + +rule: "BOT: WIDOW - Aim Sound" +Event.OngoingPlayer +Team.Team1 +if (IsAlive(EventPlayer()) == true) +if (IsInLineOfSight(EyePosition(PlayersOnHero(Hero.Widowmaker, Team.Team2)), EyePosition(EventPlayer()), BarrierLOS.NoBarriersBlock) == true) +if (IsAlive(PlayersOnHero(Hero.Widowmaker, Team.Team2)) == true) +if (PlayersOnHero(Hero.Widowmaker, Team.Team2).botSeePlayer == true) +{ + PlayEffect(EventPlayer(), PlayEffect.ExplosionSound, Color.White, EventPlayer(), 100); + Wait(1, WaitBehavior.AbortWhenFalse); + LoopIfConditionIsTrue(); +} + +rule: "BOT: WIDOW - TELEPORT TO NEW POSITION" +Event.OngoingPlayer +Team.Team2 +Player.Widowmaker +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (hasBadStatus == false) +if (TotalTimeElapsed() >= botWidowTeleportTime) +{ + botWidowTeleportTime = TotalTimeElapsed() + 28; + botWidowShotTime = TotalTimeElapsed() + (timeMinutes >= 9 ? RandomReal(1, 3) : RandomReal(3, 6)); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.BadPickupEffect, Color.White, EventPlayer(), 1); + Wait(0.1, WaitBehavior.IgnoreCondition); + Teleport(EventPlayer(), FilteredArray(sniperPositions, DistanceBetween(botEventPosition, ArrayElement()) > 5)[RandomInteger(0, CountOf(sniperPositions) - 2)]); + Wait(0.1, WaitBehavior.IgnoreCondition); + botEventPosition = PositionOf(EventPlayer()); + SetFacing(EventPlayer(), DirectionTowards(EyePosition(EventPlayer()), ObjectivePosition(2)), Relative.ToWorld); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.GoodPickupEffect, Color.White, EventPlayer(), 2); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.DebuffImpactSound, Color.White, EventPlayer(), 100); +} + +rule: "BOT: WIDOW - DEATH" +Event.OnDeath +Team.Team2 +Player.Widowmaker +{ + StopHoldingButton(EventPlayer(), Button.SecondaryFire); + Wait(0.25, WaitBehavior.IgnoreCondition); + DestroyEffect(botEffects[0]); +} + +void BotWidowRespawn() "SUBROUTINE: WIDOW - RESPAWN" +{ + # RESPAWN ON RANDOM SNIPER POSITION + Teleport(EventPlayer(), FilteredArray(sniperPositions, DistanceBetween(botEventPosition, ArrayElement()) > 5)[RandomInteger(0, CountOf(sniperPositions) - 2)]); + Wait(0.1, WaitBehavior.IgnoreCondition); + botEventPosition = PositionOf(EventPlayer()); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.GoodPickupEffect, Color.White, EventPlayer(), 2); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.DebuffImpactSound, Color.White, EventPlayer(), 100); + SetFacing(EventPlayer(), DirectionTowards(EyePosition(EventPlayer()), ObjectivePosition(2)), Relative.ToWorld); + Wait(0.7, WaitBehavior.IgnoreCondition); + StartHoldingButton(EventPlayer(), Button.SecondaryFire); + CreateBeamEffect(AllPlayers(Team.All), BeamType.TorbjornTurretSightBeam, EyePosition(EventPlayer()), UpdateEveryFrame(RayCastHitPosition(EyePosition(EventPlayer()), EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 999, null, EventPlayer(), false)), Color.Red, EffectRev.VisibleToPositionAndRadius); + botEffects[0] = LastCreatedEntity(); + WaitUntil(IsDead(EventPlayer()), 99999); + DestroyEffect(botEffects[0]); +} + +void BotWidowBadStatus() "SUBROUTINE: WIDOW - BAD STATUS" +{ + StopFacing(EventPlayer()); + DestroyEffect(botEffects[0]); + WaitUntil(!hasBadStatus, 15); + CreateBeamEffect(AllPlayers(Team.All), BeamType.TorbjornTurretSightBeam, EyePosition(EventPlayer()), UpdateEveryFrame(RayCastHitPosition(EyePosition(EventPlayer()), EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 999, null, EventPlayer(), false)), Color.Red, EffectRev.VisibleToPositionAndRadius); + botEffects[0] = LastCreatedEntity(); +} + +disabled rule: "=== BASTION ===" +{ +} + +rule: "BOT: BASTION - MAIN LOGIC - LOOP" +Event.OngoingPlayer +Team.Team2 +Player.Bastion +if (IsDummyBot(EventPlayer()) == true) +if (botIsOrisaChild == false) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (isRespawning == false) +if (botDoesUniqueBehaviour == false) +{ + botSeePlayer = SortedArray(FilteredArray(AllLivingPlayers(Team.Team1), HasSpawned(ArrayElement()) == true && ArrayElement().isInMenu[0] == false && (HeroOf(ArrayElement()) == Hero.Sombra && IsUsingAbility1(ArrayElement())) == false && IsInLineOfSight(EyePosition(EventPlayer()), EyePosition(ArrayElement()), BarrierLOS.NoBarriersBlock) == true), DistanceBetween(PositionOf(EventPlayer()), PositionOf(ArrayElement())))[0]; + # SEE THE PLAYER + if (botSeePlayer != null) + { + StopHoldingButton(EventPlayer(), Button.SecondaryFire); + StartFacing(EventPlayer(), DirectionTowards(EyePosition(EventPlayer()), EyePosition(botSeePlayer) - Vector(0, 0.5, 0)), 100, Relative.ToWorld, FacingRev.DirectionAndTurnRate); + } + else if (!IsFiringSecondary(EventPlayer()) && Health(EventPlayer()) < MaxHealth(EventPlayer())) + { + StartHoldingButton(EventPlayer(), Button.SecondaryFire); + } + Wait(1, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); +} + +rule: "BOT: BASTION - ARTILLERY" +Event.OngoingPlayer +Team.Team2 +Player.Bastion +if (IsDummyBot(EventPlayer()) == true) +if (botIsOrisaChild == false) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (botSeePlayer == true) +if (IsReloading(EventPlayer()) == false) +if (botDoesUniqueBehaviour == false) +if (IsInViewAngle(EventPlayer(), PositionOf(botSeePlayer), 30) == true) +if (DistanceBetween(PositionOf(EventPlayer()), PositionOf(botSeePlayer)) > 18) +if (DistanceBetween(EyePosition(EventPlayer()), RayCastHitPosition(EyePosition(EventPlayer()), EyePosition(EventPlayer()) + Up() * 99, null, EventPlayer(), false)) >= 35) +{ + # TRYING TO CAPTURE TARGET + Wait(0.8, WaitBehavior.AbortWhenFalse); + # CAPTURE TARGET + botDoesUniqueBehaviour = true; + StopThrottleInDirection(EventPlayer()); + CreateBeamEffect(AllPlayers(Team.All), BeamType.TorbjornTurretSightBeam, UpdateEveryFrame(EyePosition(EventPlayer())), UpdateEveryFrame(RayCastHitPosition(EyePosition(EventPlayer()), EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 1000, AllLivingPlayers(Team.Team1), EventPlayer(), true)), Color.SkyBlue, EffectRev.VisibleToPositionAndRadius); + botEffects[1] = LastCreatedEntity(); + Wait(1.4, WaitBehavior.IgnoreCondition); + DestroyEffect(botEffects[1]); + AbortIf(IsDead(EventPlayer())); + botEventPosition = PositionOf(botSeePlayer); + # SHOOT FROM ARTILLERY + botBastionArtilleryDidShotsCount = 0; + for (botLoopIterator1 = 0; 4; 1) + { + botBastionArtilleryDidShotsCount += 1; + PlayEffect(AllPlayers(Team.Team1), PlayEffect.WreckingBallMinefieldExplosionSound, Color.White, EyePosition(EventPlayer()), 250); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.PharahBarrageExplosionEffect, Color.Orange, EyePosition(EventPlayer()) + WorldVectorOf(Vector(0, 1.4, -0.7), EventPlayer(), LocalVector.Rotation), 2); + CreateBeamEffect(AllPlayers(Team.All), BeamType.ZaryaParticleBeam, EyePosition(EventPlayer()) + WorldVectorOf(Vector(0, 1.4, -0.7), EventPlayer(), LocalVector.Rotation), EyePosition(EventPlayer()) + WorldVectorOf(Vector(RandomReal(-1, 1), RandomInteger(40, 80), RandomReal(0.5, 1.5)), EventPlayer(), LocalVector.Rotation), Color.Orange, EffectRev.VisibleTo); + botEffects[2] = LastCreatedEntity(); + Wait(0.1, WaitBehavior.IgnoreCondition); + DestroyEffect(botEffects[2]); + Wait(0.4, WaitBehavior.IgnoreCondition); + if (IsDead(EventPlayer())) + { + break; + } + } + StartThrottleInDirection(EventPlayer(), DirectionTowards(PositionOf(EventPlayer()), botNextNodePosition), 1, Relative.ToWorld, ThrottleBehavior.ReplaceExistingThrottle, ThrottleRev.DirectionAndMagnitude); + Wait(1.5, WaitBehavior.IgnoreCondition); + async! BotBastionArtilleryDamage(); + Wait(4, WaitBehavior.IgnoreCondition); +} + +rule: "BOT: BASTION - PRIMARY FIRE" +Event.OngoingPlayer +Team.Team2 +Player.Bastion +if (IsDummyBot(EventPlayer()) == true) +if (botIsOrisaChild == false) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (botSeePlayer != null) +if (botDoesUniqueBehaviour == false) +if (IsInViewAngle(EventPlayer(), PositionOf(botSeePlayer), 40) == true) +{ + StartHoldingButton(EventPlayer(), Button.PrimaryFire); + Wait(1, WaitBehavior.IgnoreCondition); + StopHoldingButton(EventPlayer(), Button.PrimaryFire); + Wait(1, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); +} + +rule: "BOT: BASTION - DEATH" +Event.OnDeath +Team.Team2 +Player.Bastion +{ + StopHoldingButton(EventPlayer(), Button.SecondaryFire); + for (botLoopIterator1 = 0; 3; 1) + { + PlayEffect(AllPlayers(Team.Team1), PlayEffect.BastionTankCannonExplosionEffect, Color.White, EventPlayer(), 1); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.BastionTankCannonExplosionSound, Color.White, EventPlayer(), 100); + Wait(0.25, WaitBehavior.IgnoreCondition); + } +} + +void BotBastionRespawn() "SUBROUTINE: BASTION - RESPAWN" +{ + AbortIf(botIsOrisaChild == true); + BotLandingFromSky(); + SetAmmo(EventPlayer(), 0, 0); + WaitUntil(!IsReloading(EventPlayer()), 99999); + botTargetPosition = ObjectivePosition(2); +} + +void BotBastionArtilleryDamage() "SUBROUTINE: BASTION - ARTILLERY DAMAGE" +{ + botDoesUniqueBehaviour = false; + # EXPLOSIONS OF ARTILLERY + for (botLoopIterator2 = 0; botBastionArtilleryDidShotsCount; 1) + { + botEventPosition = RayCastHitPosition(botEventPosition + Vector(0, 50, 0), botEventPosition + Vector(RandomInteger(-4, 4), -15, RandomInteger(-4, 4)), null, EventPlayer(), true); + Damage(PlayersWithinRadius(botEventPosition, 8, Team.Team1, RadiusLOS.SurfacesAndEnemyBarriers), EventPlayer(), 50); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.BastionTankCannonExplosionSound, Color.White, botEventPosition, 150); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.PharahRocketLauncherExplosionEffect, Color.Orange, botEventPosition, 5); + CreateBeamEffect(AllPlayers(Team.All), BeamType.ZaryaParticleBeam, botEventPosition, botEventPosition + Vector(0, 60, 0), Color.Orange, EffectRev.VisibleTo); + botEffects[1] = LastCreatedEntity(); + Wait(0.1, WaitBehavior.IgnoreCondition); + DestroyEffect(botEffects[1]); + Wait(0.4, WaitBehavior.IgnoreCondition); + } +} + +disabled rule: "=== ORISA + BASTION ===" +{ +} + +rule: "BOT: ORISA-BASTION - REACHED TARGET POSITION" +Event.OngoingPlayer +Team.Team2 +Player.Orisa +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (botIsPathFinding == true) +if (DistanceBetween(PositionOf(EventPlayer()), botOrisaTargetPosition) < 1.5) +{ + BotResetPathFinding(); + StartFacing(EventPlayer(), DirectionTowards(EyePosition(EventPlayer()), Vector(XOf(gatePosition), -999, ZOf(gatePosition))), 80, Relative.ToWorld, FacingRev.DirectionAndTurnRate); + StartFacing(botOrisaChild, DirectionTowards(EyePosition(EventPlayer()), IsInLineOfSight(EyePosition(EventPlayer()), gatePosition, BarrierLOS.NoBarriersBlock) ? gatePosition : SortedArray(FilteredArray(AllPlayers(Team.Team1), IsAlive(ArrayElement())), DistanceBetween(EyePosition(EventPlayer()), PositionOf(ArrayElement())))[0]), 200, Relative.ToWorld, FacingRev.DirectionAndTurnRate); + PressButton(EventPlayer(), Button.Ability1); + WaitUntil(YOf(FacingDirectionOf(EventPlayer())) < -0.3, 99999); + PressButton(EventPlayer(), Button.Ability2); + Wait(0.8, WaitBehavior.IgnoreCondition); + botOrisaChild.botDoesUniqueBehaviour = false; + DisallowButton(EventPlayer(), Button.Ability2); +} + +rule: "BOT: ORISA-BASTION - SHOOT" +Event.OngoingPlayer +Team.Team2 +Player.Bastion +if (IsDummyBot(EventPlayer()) == true) +if (botIsOrisaChild == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (isRespawning == false) +if (botDoesUniqueBehaviour == false) +{ + botDoesUniqueBehaviour = true; + while (IsAlive(EventPlayer())) + { + CreateEffect(AllPlayers(Team.Team1), Effect.BadAura, Color.Purple, EyePosition(EventPlayer()) - Vector(0, 0.7, 0) + FacingDirectionOf(EventPlayer()) * 3.2, 1, EffectRev.VisibleToPositionAndRadius); + botEffects[3] = LastCreatedEntity(); + Wait(1.5, WaitBehavior.IgnoreCondition); + DestroyEffect(botEffects[3]); + AbortIf(IsDead(EventPlayer())); + PressButton(EventPlayer(), Button.PrimaryFire); + PressButton(EventPlayer(), Button.Reload); + botRayCastHitPosition = RayCastHitPosition(EyePosition(EventPlayer()), EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 999, AllPlayers(Team.Team1), AllPlayers(Team.Team2), true); + # ANTI-SHIELD BUG + botRayCastHitPosition = botRayCastHitPosition + DirectionTowards(botRayCastHitPosition, EyePosition(EventPlayer())) * 0.2; + CreateBeamEffect(AllPlayers(Team.All), BeamType.ZaryaParticleBeam, EyePosition(EventPlayer()) - Vector(0, 0.7, 0) + FacingDirectionOf(EventPlayer()) * 3, botRayCastHitPosition, Color.Purple, EffectRev.VisibleToPositionAndRadius); + botEffects[4] = LastCreatedEntity(); + Damage(PlayersWithinRadius(botRayCastHitPosition, 4, Team.Team1, RadiusLOS.SurfacesAndAllBarriers), EventPlayer(), 0.04); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.PharahConcussiveBlastEffect, Color.Purple, botRayCastHitPosition, 4); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.PharahConcussiveBlastSound, Color.Purple, botRayCastHitPosition, 250); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.BadExplosion, Color.Purple, EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 3.3, 2); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.SombraEmpExplosionSound, Color.Purple, EyePosition(EventPlayer()), 170); + if (DistanceBetween(botRayCastHitPosition, gatePosition) < 4 && IsInLineOfSight(botRayCastHitPosition, gatePosition, BarrierLOS.EnemyBarriersBlock)) + { + gateHealth -= 80 + 10 * time5Minutes; + async GateProgressBarColor(); + } + Wait(0.15, WaitBehavior.IgnoreCondition); + DestroyEffect(botEffects[4]); + Wait(0.1, WaitBehavior.IgnoreCondition); + WaitUntil(!IsReloading(EventPlayer()), 2.5); + } +} + +rule: "BOT: ORISA-BASTION - CAN'T SEE THE TARGET" +Event.OngoingPlayer +Team.Team2 +Player.Orisa +if (IsDummyBot(EventPlayer()) == true) +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +if (isRespawning == false) +if (botIsPathFinding == false) +if (IsInLineOfSight(EyePosition(EventPlayer()), gatePosition, BarrierLOS.NoBarriersBlock) == false) +{ + botTargetPosition = botOrisaTargetPosition; + async BotStartPathFinding(); +} + +rule: "BOT: ORISA-BASTION - DEATH" +Event.OnDeath +Team.Team2 +Player.Orisa +{ + AllowButton(EventPlayer(), Button.Ability2); + Kill(botOrisaChild, null); + DetachPlayers(botOrisaChild); + ClearStatus(botOrisaChild, Status.PhasedOut); + SetDamageDealt(botOrisaChild, 100); + botOrisaChild.botIsOrisaChild = false; + botOrisaChild = null; + botOrisaParent = null; + ForcePlayerHero(EventPlayer(), Hero.Widowmaker); +} + +void BotOrisaRespawn() "SUBROUTINE: ORISA - RESPAWN" +{ + botOrisaParent = EventPlayer(); + # WAITING FOR ANY BASTION TO DIE + WaitUntil(IsTrueForAny(AllPlayers(Team.Team2), IsDead(ArrayElement()) && HeroOf(ArrayElement()) == Hero.Bastion && ArrayElement().isBoss[0] == false && ArrayElement().isBoss[1] == false), 99999); + # SETUP BASTION AS CHILD + botOrisaChild = FilteredArray(AllPlayers(Team.Team2), IsDead(ArrayElement()) && HeroOf(ArrayElement()) == Hero.Bastion && ArrayElement().isBoss[0] == false && ArrayElement().isBoss[1] == false)[0]; + botOrisaChild.botIsOrisaChild = true; + botOrisaChild.botDoesUniqueBehaviour = true; + Wait(2, WaitBehavior.IgnoreCondition); + Respawn(botOrisaChild); + StartScalingPlayer(botOrisaChild, 1.8, false); + SetDamageDealt(botOrisaChild, 2000); + SetStatus(botOrisaChild, null, Status.PhasedOut, 9999); + DisableNameplates(botOrisaChild, AllPlayers(Team.All)); + SetFacing(botOrisaChild, Vector(XOf(FacingDirectionOf(EventPlayer())), 9999, ZOf(FacingDirectionOf(EventPlayer()))), Relative.ToWorld); + StartHoldingButton(botOrisaChild, Button.Ability1); + WaitUntil(IsInAlternateForm(botOrisaChild), 5); + StopHoldingButton(botOrisaChild, Button.Ability1); + Teleport(botOrisaChild, PositionOf(EventPlayer())); + AttachPlayers(botOrisaChild, botOrisaParent, Vector(0, 1.8, 0.23)); + BotLandingFromSky(); + StartFacing(EventPlayer(), DirectionTowards(PositionOf(EventPlayer()), botNextNodePosition), 360, Relative.ToWorld, FacingRev.DirectionAndTurnRate); + botTargetPosition = botOrisaTargetPosition; + async! BotStartPathFinding(); +} + +rule: "GLOBAL: GAME LOGIC - MIN 0 - ZENS, REINS, BALL" +if (IsGameInProgress() == true) +if (timeMinutes == 0) +{ + # CREATE BOTS - ZEN + while (CountOf(AllPlayers(Team.Team2)) < 13) + { + CreateDummyBot(Hero.Zenyatta, Team.Team2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, WaitBehavior.IgnoreCondition); + } + # BALL + while (CountOf(FilteredArray(AllPlayers(Team.Team2), HeroOf(ArrayElement()) == Hero.WreckingBall)) == 0) + { + CreateDummyBot(Hero.WreckingBall, Team.Team2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + Wait(1, WaitBehavior.IgnoreCondition); + } + # REPLACE DEAD ZEN TO REIN + while (CountOf(FilteredArray(AllPlayers(Team.Team2), HeroOf(ArrayElement()) == Hero.Reinhardt)) != 3) + { + # WAITING FOR ANY ZEN TO DIE + WaitUntil(IsTrueForAny(AllPlayers(Team.Team2), IsDead(ArrayElement()) && HeroOf(ArrayElement()) == Hero.Zenyatta), 99999); + # REPLACE HIM TO A NEW HERO + defaultCurrentBot = FilteredArray(AllPlayers(Team.Team2), IsDead(ArrayElement()) && HeroOf(ArrayElement()) == Hero.Zenyatta)[0]; + Wait(0.2, WaitBehavior.IgnoreCondition); + DestroyDummyBot(Team.Team2, SlotOf(defaultCurrentBot)); + Wait(0.2, WaitBehavior.IgnoreCondition); + CreateDummyBot(Hero.Reinhardt, Team.Team2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } +} + +rule: "GLOBAL: GAME LOGIC - MIN 1 - WIDOW" +if (IsGameInProgress() == true) +if (timeMinutes == 1) +{ + isNewWaveGameLogicProcessing = true; + while (CountOf(FilteredArray(AllPlayers(Team.Team2), HeroOf(ArrayElement()) == Hero.Widowmaker)) == 0) + { + # WAITING FOR ANY ZEN TO DIE + WaitUntil(IsTrueForAny(AllPlayers(Team.Team2), IsDead(ArrayElement()) && HeroOf(ArrayElement()) == Hero.Zenyatta), 99999); + # REPLACE HIM TO A NEW HERO + defaultCurrentBot = FilteredArray(AllPlayers(Team.Team2), IsDead(ArrayElement()) && HeroOf(ArrayElement()) == Hero.Zenyatta)[0]; + Wait(0.2, WaitBehavior.IgnoreCondition); + DestroyDummyBot(Team.Team2, SlotOf(defaultCurrentBot)); + Wait(0.2, WaitBehavior.IgnoreCondition); + CreateDummyBot(Hero.Widowmaker, Team.Team2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + } + isNewWaveGameLogicProcessing = false; +} + +rule: "GLOBAL: GAME LOGIC - MIN 3 - BALL" +if (IsGameInProgress() == true) +if (timeMinutes == 3) +{ + # WAITING FOR ANY ZEN TO DIE + WaitUntil(IsTrueForAny(AllPlayers(Team.Team2), IsDead(ArrayElement()) && HeroOf(ArrayElement()) == Hero.Zenyatta), 99999); + # REPLACE HIM TO A NEW HERO + defaultCurrentBot = FilteredArray(AllPlayers(Team.Team2), IsDead(ArrayElement()) && HeroOf(ArrayElement()) == Hero.Zenyatta)[0]; + Wait(0.2, WaitBehavior.IgnoreCondition); + DestroyDummyBot(Team.Team2, SlotOf(defaultCurrentBot)); + Wait(1, WaitBehavior.IgnoreCondition); + CreateDummyBot(Hero.WreckingBall, Team.Team2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); +} + +rule: "GLOBAL: GAME LOGIC - MIN 6 - BASTION" +if (IsGameInProgress() == true) +if (timeMinutes == 6) +{ + while (CountOf(FilteredArray(AllPlayers(Team.Team2), HeroOf(ArrayElement()) == Hero.Zenyatta)) > 0) + { + # WAITING FOR ANY ZEN TO DIE + WaitUntil(IsTrueForAny(AllPlayers(Team.Team2), IsDead(ArrayElement()) && HeroOf(ArrayElement()) == Hero.Zenyatta), 99999); + # REPLACE HIM TO A NEW HERO + defaultCurrentBot = FilteredArray(AllPlayers(Team.Team2), IsDead(ArrayElement()) && HeroOf(ArrayElement()) == Hero.Zenyatta)[0]; + Wait(0.2, WaitBehavior.IgnoreCondition); + DestroyDummyBot(Team.Team2, SlotOf(defaultCurrentBot)); + Wait(1, WaitBehavior.IgnoreCondition); + if (CountOf(AllPlayers(Team.Team2)) < 11) + { + CreateDummyBot(Hero.Reinhardt, Team.Team2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); + LastCreatedEntity().isBoss[1] = true; + } + } + CreateDummyBot(Hero.Bastion, Team.Team2, -1, Vector(0, 999, 0), Vector(0, 0, 0)); +} + +rule: "GLOBAL: GAME LOGIC - MIN 9 - ECHO, +1 BASTION" +if (IsGameInProgress() == true) +if (timeMinutes == 9) +{ + while (CountOf(FilteredArray(AllPlayers(Team.Team2), HeroOf(ArrayElement()) == Hero.Widowmaker)) > 0) + { + WaitUntil(IsTrueForAny(AllPlayers(Team.Team2), IsDead(ArrayElement()) && HeroOf(ArrayElement()) == Hero.Widowmaker), 99999); + defaultCurrentBot = FilteredArray(AllPlayers(Team.Team2), IsDead(ArrayElement()) && HeroOf(ArrayElement()) == Hero.Widowmaker)[0]; + Wait(0.2, WaitBehavior.IgnoreCondition); + DestroyDummyBot(Team.Team2, SlotOf(defaultCurrentBot)); + } + while (CountOf(FilteredArray(AllPlayers(Team.Team2), HeroOf(ArrayElement()) == Hero.Echo)) == 0) + { + Wait(1, WaitBehavior.IgnoreCondition); + CreateDummyBot(Hero.Echo, Team.Team2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); + } + WaitUntil(CountOf(FilteredArray(AllPlayers(Team.Team2), HeroOf(ArrayElement()) == Hero.Zenyatta)) == 0, 99999); + CreateDummyBot(Hero.Bastion, Team.Team2, -1, Vector(0, 9999, 0), Vector(0, 0, 0)); +} + +rule: "Ana Nano Variable" +Event.OngoingPlayer +Team.Team1 +Player.Ana +if (IsUsingUltimate(EventPlayer()) == true) +{ + PlayerClosestToReticle(EventPlayer(), Team.Team1).isNanoed = 1; +} + +rule: "isNanoed" +Event.OngoingPlayer +Team.Team1 +if (isNanoed == true) +{ + if (IsDead(EventPlayer())) + { + isNanoed = 0; + } + Wait(8, WaitBehavior.IgnoreCondition); + isNanoed = 0; +} + +rule: "money on kill" +Event.OnFinalBlow +Team.Team1 +{ + if (upgradeMaxAmmoValue < upgradeMaxAmmoMaxValue[2]) + { + upgradeMaxAmmoValue += Victim().isBoss[0] == 1 ? 10 : 1; + } + if (HeroOf(Victim()) == Hero.Zenyatta) + { + AllPlayers(Team.Team1).money[0] += 10 * (Victim().isBoss[0] ? 3 : 1) * moneyMultiplier[0]; + startMoney += 10 * (Victim().isBoss[0] ? 3 : 1) * moneyMultiplier[0]; + } + else if (HeroOf(Victim()) == Hero.Reinhardt) + { + AllPlayers(Team.Team1).money[0] += 20 * (Victim().isBoss[0] ? 3 : 1) * moneyMultiplier[0]; + startMoney += 20 * (Victim().isBoss[0] ? 3 : 1) * moneyMultiplier[0]; + } + else if (HeroOf(Victim()) == Hero.WreckingBall) + { + AllPlayers(Team.Team1).money[0] += 30 * (Victim().isBoss[0] ? 3 : 1) * moneyMultiplier[0]; + startMoney += 30 * (Victim().isBoss[0] ? 3 : 1) * moneyMultiplier[0]; + } + else if (HeroOf(Victim()) == Hero.Widowmaker) + { + AllPlayers(Team.Team1).money[0] += 50 * (Victim().isBoss[0] ? 3 : 1) * moneyMultiplier[0]; + startMoney += 50 * (Victim().isBoss[0] ? 3 : 1) * moneyMultiplier[0]; + } + else if (HeroOf(Victim()) == Hero.Bastion) + { + AllPlayers(Team.Team1).money[0] += 70 * (Victim().isBoss[0] ? 3 : 1) * moneyMultiplier[0]; + startMoney += 70 * (Victim().isBoss[0] ? 3 : 1) * moneyMultiplier[0]; + } + else if (HeroOf(Victim()) == Hero.Echo) + { + AllPlayers(Team.Team1).money[0] += 90 * (Victim().isBoss[0] ? 3 : 1) * moneyMultiplier[0]; + startMoney += 90 * (Victim().isBoss[0] ? 3 : 1) * moneyMultiplier[0]; + } + else if (HeroOf(Victim()) == Hero.Orisa) + { + AllPlayers(Team.Team1).money[0] += 120 * (Victim().isBoss[0] ? 3 : 1) * moneyMultiplier[0]; + startMoney += 120 * (Victim().isBoss[0] ? 3 : 1) * moneyMultiplier[0]; + } +} + +rule: "Abilities and Hero Talents by Shingen and LemonAid" +Event.OngoingPlayer +Team.Team1 +{ + baseStats[0] = 100; + baseStats[1] = 100; + baseStats[2] = 100; + baseStats[3] = 100; + damageBoost[0] = 0; + damageBoost[1] = 0; + playerHealth = 0; + healBoost = 0; + speedBoost = 0; + money[0] = 2400 + startMoney; + if (<"<0>", EventPlayer()> == "ShuriZma") + { + CreateHudText(EventPlayer(), null, <"Serverload: <0>, AVG <1>, Peak <2>", ServerLoad(), ServerLoadAverage(), ServerLoadPeak()>, null, Location.Right, -10000, Color.White, Color.Red, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(EventPlayer(), null, <"<0><1><2>", <"damage: <0>\nhealth: <1>\nhealing: <2>\n", baseStats[0], baseStats[1], baseStats[2]>, <"speed: <0>\ndamageBoost[0]: <1>\ndamageBoost[1]: <2>\n", baseStats[3], damageBoost[0], damageBoost[1]>, <"playerHealth: <0>\nhealBoost: <1>\n<2>", playerHealth, healBoost, <"speedBoost: <0>\nkills: <1>", speedBoost, baseStats[4]>>>, null, Location.Right, -10000, Color.White, Color.Red, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + } +} + +rule: "Team 1 (Ability): Quick Fix" +Event.OnElimination +Team.Team1 +if (abilities[3] == true) +{ + if (baseStats[5] != abilities[3] * 20 && baseStats[4] == true) + { + speedBoost -= baseStats[5]; + } + Heal(EventPlayer(), null, abilities[3] * 50); + if (baseStats[4] != true || baseStats[5] != abilities[3] * 20) + { + baseStats[5] = abilities[3] * 20; + baseStats[4] = true; + speedBoost += baseStats[5]; + UpdatePlayerStats(); + } + Wait(5, WaitBehavior.RestartWhenTrue); + speedBoost -= baseStats[5]; + baseStats[4] = false; + UpdatePlayerStats(); +} + +rule: "Team 1 (Ability): Heavyweight" +Event.PlayerDealtKnockback +Team.Team1 +if (abilities[4] == true) +{ + Damage(Victim(), EventPlayer(), EventDamage() / (100 / abilities[4] * 25)); +} + +rule: "Team 1 (Ability): Charged" +Event.OngoingPlayer +Team.Team1 +if (abilities[5] == true) +if (UltimateChargePercent(EventPlayer()) < abilities[5] * 20) +{ + SetUltimateCharge(EventPlayer(), abilities[5] * 20); + if (IsDuplicating(EventPlayer())) + { + Wait(0.1, WaitBehavior.IgnoreCondition); + SetUltimateCharge(EventPlayer(), abilities[5] * 20); + } + Wait(0.25, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); +} + +rule: "Team 1 (Ability): Haste Primary Fire" +Event.OngoingPlayer +Team.Team1 +if (abilities[6] == true) +if (AbilityCooldown(EventPlayer(), Button.PrimaryFire) > 0.1) +{ + SetAbilityCooldown(EventPlayer(), Button.PrimaryFire, (1 - 0.25 * abilities[6]) * AbilityCooldown(EventPlayer(), Button.PrimaryFire)); +} + +rule: "Team 1 (Ability): Haste Secondary Fire" +Event.OngoingPlayer +Team.Team1 +if (abilities[6] == true) +if (AbilityCooldown(EventPlayer(), Button.SecondaryFire) > 0.1) +{ + SetAbilityCooldown(EventPlayer(), Button.SecondaryFire, (1 - 0.25 * abilities[6]) * AbilityCooldown(EventPlayer(), Button.SecondaryFire)); +} + +rule: "Team 1 (Ability): Haste Ability 1" +Event.OngoingPlayer +Team.Team1 +if (abilities[6] == true) +if (AbilityCooldown(EventPlayer(), Button.Ability1) > 0.1) +{ + SetAbilityCooldown(EventPlayer(), Button.Ability1, (1 - 0.25 * abilities[6]) * AbilityCooldown(EventPlayer(), Button.Ability1)); +} + +rule: "Team 1 (Ability): Haste Ability 2" +Event.OngoingPlayer +Team.Team1 +if (abilities[6] == true) +if (AbilityCooldown(EventPlayer(), Button.Ability2) > 0.1) +{ + SetAbilityCooldown(EventPlayer(), Button.Ability2, (1 - 0.25 * abilities[6]) * AbilityCooldown(EventPlayer(), Button.Ability2)); +} + +rule: "Team 1 (Ability): Haste Jump" +Event.OngoingPlayer +Team.Team1 +if (abilities[6] == true) +if (AbilityCooldown(EventPlayer(), Button.Jump) > 0.1) +{ + SetAbilityCooldown(EventPlayer(), Button.Jump, (1 - 0.25 * abilities[6]) * AbilityCooldown(EventPlayer(), Button.Jump)); +} + +rule: "Team 1 (Ability): Haste Crouch" +Event.OngoingPlayer +Team.Team1 +if (abilities[6] == true) +if (AbilityCooldown(EventPlayer(), Button.Crouch) > 0.1) +{ + SetAbilityCooldown(EventPlayer(), Button.Crouch, (1 - 0.25 * abilities[6]) * AbilityCooldown(EventPlayer(), Button.Crouch)); +} + +rule: "Team 1 (Ability): Heavy Impact" +Event.OnDamageTaken +Team.Team2 +if (Attacker().abilities[7] == true) +{ + AbortIf(RandomReal(-0.02, 1) > EventDamage() / MaxHealth(EventPlayer())); + SetStatus(EventPlayer(), Attacker(), Status.Stunned, 1 * Attacker().abilities[7]); + Wait(5, WaitBehavior.IgnoreCondition); +} + +rule: "Team 1 (Ability): Resilience" +Event.OngoingPlayer +Team.Team1 +if (abilities[11] == true) +if (NormalizedHealth(EventPlayer()) < abilities[11] * 0.3) +{ + SetDamageReceived(EventPlayer(), 70); + WaitUntil(!(abilities[11] && NormalizedHealth(EventPlayer()) < abilities[11] * 0.3), 99999); + SetDamageReceived(EventPlayer(), 100); +} + +rule: "Auto Repair" +if (IsGameInProgress() == true) +if (automaticRepair == true) +if (gateHealth < gateMaxHealth[0]) +{ + if (gateMaxHealth[0] - gateHealth > 5 * automaticRepair * (upgradeGateMaxHealthValue >= upgradeGateMaxHealthMaxValue[2] ? 2 : 1)) + { + gateHealth += 5 * automaticRepair * (upgradeGateMaxHealthValue >= upgradeGateMaxHealthMaxValue[2] ? 2 : 1); + upgradeGateMaxHealthValue += 5 * automaticRepair; + } + else + { + gateHealth += gateMaxHealth[0] - gateHealth; + upgradeGateMaxHealthValue += gateMaxHealth[0] - gateHealth; + } + # UPDATE GATE'S HEALTH BAR + async GateProgressBarColor(); + Wait(5, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); +} + +rule: "Hero Talent Text" +Event.OngoingPlayer +Team.Team1 +if (HasSpawned(EventPlayer()) == true) +if (IsAlive(EventPlayer()) == true) +{ + if (HeroOf(EventPlayer()) == Hero.Ana) + { + heroTalentText[1] = [AbilityIconString(Hero.Ana, Button.Ability1), "Sleep Paralysis: Slept enemies will take a lot of damage when they wake up"]; + heroTalentText[2] = [AbilityIconString(Hero.Ana, Button.Ability2), "Multinade: Ana throws multiple Biotic Grenades"]; + } + else if (HeroOf(EventPlayer()) == Hero.Ashe) + { + heroTalentText[1] = [AbilityIconString(Hero.Ashe, Button.Ability2), "Black Gunpowder: Coach gun stuns and sets enemies on fire"]; + heroTalentText[2] = [IconString(Icon.Fire), "Dancing Flames: Eliminated enemies exlpode and burn others nearby"]; + } + else if (HeroOf(EventPlayer()) == Hero.Baptiste) + { + heroTalentText[1] = [IconString(Icon.Poison), "Corrode: Regenerative Burst will damage and poison enemies"]; + heroTalentText[2] = [AbilityIconString(Hero.Baptiste, Button.Ability2), "Aerial Ace: Exo-boots allow for gliding and deal bonus damage while gliding"]; + } + else if (HeroOf(EventPlayer()) == Hero.Bastion) + { + heroTalentText[1] = [AbilityIconString(Hero.Echo, Button.SecondaryFire), "Fusillade: Automatically fire a tactical grenade every so often in sentry form"]; + heroTalentText[2] = [AbilityIconString(Hero.Symmetra, Button.Ability1), "Trickshot: Landing tactical grenade on an enemy deals more damage and heals"]; + } + else if (HeroOf(EventPlayer()) == Hero.Brigitte) + { + heroTalentText[1] = [AbilityIconString(Hero.Brigitte, Button.Ability1), "Endeavor: Gain a boost in damage, armour and speed when your barrier breaks"]; + heroTalentText[2] = [AbilityIconString(Hero.Brigitte, Button.Ultimate), "Whiplash: Endpoint of whip shot generates a stunning shockwave"]; + } + else if (HeroOf(EventPlayer()) == Hero.Cassidy) + { + heroTalentText[1] = [AbilityIconString(Hero.Cassidy, Button.Ability2), "Standoff: Enemies cannot move once their skull is locked during deadeye"]; + heroTalentText[2] = [AbilityIconString(Hero.Cassidy, Button.Ultimate), "Flashpoint: Magnetic Grenade will heavily stun enemies if it sticks"]; + } + else if (HeroOf(EventPlayer()) == Hero.Dva) + { + heroTalentText[1] = [AbilityIconString(Hero.Dva, Button.SecondaryFire), "Voltage Grid: Defense matrix damages and roots enemies"]; + heroTalentText[2] = [AbilityIconString(Hero.Dva, Button.Ability1), "Shooting Star: Boosters set enemies on fire"]; + } + else if (HeroOf(EventPlayer()) == Hero.Doomfist) + { + heroTalentText[1] = [AbilityIconString(Hero.Pharah, Button.Jump), "Punch Card: Rocket Punch deals triple damage at full charge"]; + heroTalentText[2] = [AbilityIconString(Hero.Doomfist, Button.Ultimate), "Fissure: Seismic Slam leaves a large fire pool behind"]; + } + else if (HeroOf(EventPlayer()) == Hero.Echo) + { + heroTalentText[1] = [AbilityIconString(Hero.Echo, Button.Ability2), "Glass Bombs: Sticky Bombs deal double damage to enemies under half health"]; + heroTalentText[2] = [AbilityIconString(Hero.Echo, Button.SecondaryFire), "Focusing Optics: Focusing Beam boost starts at 90% hp instead of 50%"]; + } + else if (HeroOf(EventPlayer()) == Hero.Genji) + { + heroTalentText[1] = [AbilityIconString(Hero.Genji, Button.Ability1), "Venomous Strike: Swift Strike deals bleed damage; heal for bleed damage"]; + heroTalentText[2] = [AbilityIconString(Hero.Genji, Button.Ultimate), "Dragon's Breath: Dragonblade fires explosive spirit charges with every swing"]; + } + else if (HeroOf(EventPlayer()) == Hero.Hanzo) + { + heroTalentText[1] = [IconString(Icon.Bolt), "Firebolt: Charging an arrow for more than 2s turns it into an explosive bolt"]; + heroTalentText[2] = [AbilityIconString(Hero.Hanzo, Button.Ability2), "Stormbreak: Storm arrows have no cooldown for a short duration when earning a kill"]; + } + else if (HeroOf(EventPlayer()) == Hero.Junkrat) + { + heroTalentText[1] = [IconString(Icon.Fire), "Pyromania: All explosive attacks deal fire damage"]; + heroTalentText[2] = [AbilityIconString(Hero.Junkrat, Button.Ability2), "Trigger Happy: Gain +1 Concussion Mine every 4s, up to 5 max"]; + } + else if (HeroOf(EventPlayer()) == Hero.JunkerQueen) + { + heroTalentText[1] = [IconString(Icon.Fire), "Shout Louder: Commanding Shout wounds enemies in the area"]; + heroTalentText[2] = [AbilityIconString(Hero.Junkrat, Button.Ability2), "Grace Period: Gracie deals extra damage upon pulling an enemy back"]; + } + else if (HeroOf(EventPlayer()) == Hero.Kiriko) + { + heroTalentText[1] = [IconString(Icon.Fire), "Shinobi Tactics: Healing with abilities creates energy explosions around the target"]; + heroTalentText[2] = [AbilityIconString(Hero.Junkrat, Button.Ability2), "Recession: Protection Suzu damages for 20% of health and freezes enemies"]; + } + else if (HeroOf(EventPlayer()) == Hero.Lucio) + { + heroTalentText[1] = [AbilityIconString(Hero.Lucio, Button.SecondaryFire), "Power Skating: Soundwave deals more damage and knockback based on movement speed"]; + heroTalentText[2] = [AbilityIconString(Hero.Lucio, Button.Ability1), "Reverse Amp: Amp It Up inflicts the opposite song effect to enemies"]; + } + else if (HeroOf(EventPlayer()) == Hero.Mei) + { + heroTalentText[1] = [AbilityIconString(Hero.Mei, Button.Ultimate), "Cold Snap: Instantly freeze nearby enemies once Cryo-Freeze breaks"]; + heroTalentText[2] = [AbilityIconString(Hero.Mei, Button.Ability2), "Polar Vortex: Mei throws 3 blizzard drones instead of 1 at increased damage"]; + } + else if (HeroOf(EventPlayer()) == Hero.Mercy) + { + heroTalentText[1] = [AbilityIconString(Hero.Mercy, Button.Ability2), "Wings of Grand: Guardian Angel damages and knocks enemies down in its path"]; + heroTalentText[2] = [AbilityIconString(Hero.Mercy, Button.Ultimate), "Holy light missiles: Unleash blasts of holy light missiles during valkyrie"]; + } + else if (HeroOf(EventPlayer()) == Hero.Moira) + { + heroTalentText[1] = [AbilityIconString(Hero.Moira, Button.SecondaryFire), "Flourish: Fading through allies heals and through enemies damages them"]; + heroTalentText[2] = [AbilityIconString(Hero.Moira, Button.Ability2), "Catalyst: Holding primary during coalescence costs energy and speed, but boosts effectiveness"]; + } + else if (HeroOf(EventPlayer()) == Hero.Orisa) + { + heroTalentText[1] = [AbilityIconString(Hero.Orisa, Button.Ability1), "Steel Pinwheel: Javelin spin deals a large sweep attack when it ends"]; + heroTalentText[2] = [AbilityIconString(Hero.Orisa, Button.SecondaryFire), "Flaming Harpoon: Energy Javelin stuns for longer and burns enemies"]; + } + else if (HeroOf(EventPlayer()) == Hero.Pharah) + { + heroTalentText[1] = [AbilityIconString(Hero.Pharah, Button.Ability2), "Head Trauma: Concussive Blast deals damage and tazes enemies below half health"]; + heroTalentText[2] = [AbilityIconString(Hero.Pharah, Button.Ability1), "Weaponized Storm: Every 6th rocket flies faster and detonates several clusters"]; + } + else if (HeroOf(EventPlayer()) == Hero.Ramattra) + { + heroTalentText[1] = [AbilityIconString(Hero.Ramattra, Button.Ability1), "Vile Dominance: Move faster and root enemies with every punch in nemesis form"]; + heroTalentText[2] = [AbilityIconString(Hero.Ramattra, Button.Ultimate), "Nether Sector: Heal and gain bonus ultimate charge for every enemy grounded with vortex"]; + } + else if (HeroOf(EventPlayer()) == Hero.Reaper) + { + heroTalentText[1] = [AbilityIconString(Hero.Reaper, Button.Ability1), "Wraith Wrath: Shooting is enabled during wraith form with increased damage"]; + heroTalentText[2] = [AbilityIconString(Hero.Reaper, Button.Ultimate), "Gloom: Wraith form instantly tazes all enemies in sight"]; + } + else if (HeroOf(EventPlayer()) == Hero.Reinhardt) + { + heroTalentText[1] = [AbilityIconString(Hero.Reinhardt, Button.Ability2), "Fire Blast: Fire Strike explodes as it deals damage, igniting enemies"]; + heroTalentText[2] = [AbilityIconString(Hero.Reinhardt, Button.Ultimate), "Epicenter: Earth shatter travels in all directions"]; + } + else if (HeroOf(EventPlayer()) == Hero.Roadhog) + { + heroTalentText[1] = [IconString(Icon.Poison), "Stench: Constantly inflict toxic damage to nearby enemeis"]; + heroTalentText[2] = [AbilityIconString(Hero.Roadhog, Button.Ability1), "Chainsnap: Chain Hook deals 4x more damage; resets upon eliminations"]; + } + else if (HeroOf(EventPlayer()) == Hero.Sigma) + { + heroTalentText[1] = [AbilityIconString(Hero.Sigma, Button.Ability1), "Accretion Disk: Accretion flies straight and has increased damage and stun"]; + heroTalentText[2] = [AbilityIconString(Hero.Sigma, Button.Ultimate), "String Theory: When kinetic grasp ends, fire a blast that scales based on the amount of damage collected"]; + } + else if (HeroOf(EventPlayer()) == Hero.Sojourn) + { + heroTalentText[1] = [AbilityIconString(Hero.Sigma, Button.Ability1), "Thunderous kicks: Kickslide Jump initiates a powerful energy blast"]; + heroTalentText[2] = [AbilityIconString(Hero.Sigma, Button.Ultimate), "Matter Splatter: Critical railgun hits are explosive"]; + } + else if (HeroOf(EventPlayer()) == Hero.Soldier76) + { + heroTalentText[1] = [AbilityIconString(Hero.Pharah, Button.Ultimate), "Triple Threat: Helix Rockets fires two adjacent mini rockets"]; + heroTalentText[2] = [AbilityIconString(Hero.Soldier76, Button.Ability1), "Espionage: Allies in biotic field revive faster and become harder to hit"]; + } + else if (HeroOf(EventPlayer()) == Hero.Sombra) + { + heroTalentText[1] = [AbilityIconString(Hero.Sombra, Button.SecondaryFire), "Going Viral: Cancelling stealth will trigger a small hack explosion"]; + heroTalentText[2] = [AbilityIconString(Hero.Sombra, Button.Ultimate), "Cyberattack: Using translocator will damage and hack nearby enemies"]; + } + else if (HeroOf(EventPlayer()) == Hero.Symmetra) + { + heroTalentText[1] = [IconString(Icon.Bolt), "Sentry Paragon: Each sentry turret deals 50% more damage"]; + heroTalentText[2] = [AbilityIconString(Hero.Symmetra, Button.Ultimate), "Shield Generator: Gain increased damage and speed, and grant all players shields with kills"]; + } + else if (HeroOf(EventPlayer()) == Hero.Torbjorn) + { + heroTalentText[1] = [AbilityIconString(Hero.Torbjorn, Button.Ability2), "Heatwaves: Unleash waves of fire when overload or molten core is active"]; + heroTalentText[2] = [AbilityIconString(Hero.Torbjorn, Button.Ultimate), "melting point: Every turret kill boosts its damage to 200% for a short duration"]; + } + else if (HeroOf(EventPlayer()) == Hero.Tracer) + { + heroTalentText[1] = [AbilityIconString(Hero.Tracer, Button.Ability2), "Vortex: Recall drags and roots nearby enemies to its activation point"]; + heroTalentText[2] = [AbilityIconString(Hero.Tracer, Button.Ultimate), "Chain Reaction: Pulse Bomb explosions can chain onto other enemies"]; + } + else if (HeroOf(EventPlayer()) == Hero.Widowmaker) + { + heroTalentText[1] = [AbilityIconString(Hero.Widowmaker, Button.Ultimate), "Baiser de Soie: Scoped critical hits instantly kill enemies below 30% hp"]; + heroTalentText[2] = [AbilityIconString(Hero.Widowmaker, Button.Ability2), "Felt More Alive: Gain low gravity and deal 40% more damage when scoping airbourne"]; + } + else if (HeroOf(EventPlayer()) == Hero.Winston) + { + heroTalentText[1] = [AbilityIconString(Hero.Winston, Button.Ability2), "Lightning Strikes Twice: Direct zap hits will trigger twice"]; + heroTalentText[2] = [AbilityIconString(Hero.Winston, Button.Ultimate), "Quake: Jump Pack landing force is much more powerful and stuns enemies"]; + } + else if (HeroOf(EventPlayer()) == Hero.WreckingBall) + { + heroTalentText[1] = [AbilityIconString(Hero.WreckingBall, Button.Ultimate), "Mirror Ball: Reflect 100% of received damage to nearby enemies"]; + heroTalentText[2] = [AbilityIconString(Hero.WreckingBall, Button.Ability2), "Distortion: Adaptive shields triggers explosions and tazes nearby enemies"]; + } + else if (HeroOf(EventPlayer()) == Hero.Zarya) + { + heroTalentText[1] = [AbilityIconString(Hero.Zarya, Button.Ability1), "Combusta-Bubble: Barriers explode when they expire"]; + heroTalentText[2] = [AbilityIconString(Hero.Echo, Button.Ability2), "Power Surge: Personal barrier grants energy upon activation"]; + } + else if (HeroOf(EventPlayer()) == Hero.Zenyatta) + { + heroTalentText[1] = [AbilityIconString(Hero.Baptiste, Button.Ability2), "Stress Relief: Fully charged orb volleys deal 50% more damage"]; + heroTalentText[2] = [AbilityIconString(Hero.Zenyatta, Button.Ultimate), "Perfect Balance: Transcendence damages enemies in the area of effect"]; + } +} + +void CancelMomentum() "Subroutine: Cancel player momentum" +{ + ApplyImpulse(EventPlayer(), -1 * DirectionFromAngles(HorizontalAngleFromDirection(VelocityOf(EventPlayer())), 0), 0.001, Relative.ToWorld, ContraryMotion.CancelXYZ); +} + +rule: "Ana: Sleep Paralysis" +Event.OnDamageDealt +Team.Team1 +Player.Ana +{ + AbortIf(!abilities[8]); + AbortIf(EventAbility() != Button.Ability1); + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.Black, Victim(), 2); + Wait(0.5, WaitBehavior.IgnoreCondition); + WaitUntil(!HasStatus(Victim(), Status.Asleep), 5); + PlayEffect(AllPlayers(Team.All), PlayEffect.ExplosionSound, Color.Black, EyePosition(Victim()), 150); + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.Black, Victim(), 6); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Black, Victim(), 12); + Damage(PlayersWithinRadius(Victim(), 6, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 150); + SetStatus(PlayersWithinRadius(EyePosition(Victim()), 6, Team.Team2, RadiusLOS.Surfaces), null, Status.Hacked, 1.5); +} + +rule: "Ana: Multinade" +Event.OngoingPlayer +Team.Team1 +Player.Ana +if (abilities[12] == true) +if (IsUsingAbility2(EventPlayer()) == true) +{ + for (p_loopIterator = 0; 4; 1) + { + Wait(0.03, WaitBehavior.IgnoreCondition); + SetAbilityCooldown(EventPlayer(), Button.Ability2, false); + CancelPrimaryAction(EventPlayer()); + Wait(0.05, WaitBehavior.IgnoreCondition); + PressButton(EventPlayer(), Button.Ability2); + } + Wait(2, WaitBehavior.IgnoreCondition); +} + +rule: "Ashe: Taunt" +Event.PlayerDealtKnockback +Team.Team1 +Player.Ashe +if (abilities[8] == true) +if (EventAbility() == Button.Ability1) +if (Victim() != EventPlayer()) +{ + StartDamageOverTime(Victim(), EventPlayer(), 3, EventDamage() * 2.5); + SetStatus(Victim(), null, Status.Burning, 3); + SetStatus(Victim(), null, Status.Stunned, 3); +} + +rule: "Ashe: Dancing Flames" +Event.OnElimination +Team.Team1 +Player.Ashe +if (abilities[12] == true) +{ + PlayEffect(AllPlayers(Team.All), PlayEffect.ExplosionSound, Color.Orange, Victim().deathPosition, 120); + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.Orange, Victim().deathPosition, 5); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadPickupEffect, Color.Yellow, Victim().deathPosition, 5); + StartDamageOverTime(PlayersWithinRadius(Victim().deathPosition, 5, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 3, 15); + SetStatus(PlayersWithinRadius(Victim().deathPosition, 5, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), Status.Burning, 3); + Damage(PlayersWithinRadius(Victim().deathPosition, 5, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 30); +} + +rule: "Baptiste: Corrode" +Event.OngoingPlayer +Team.Team1 +Player.Baptiste +if (IsUsingAbility1(EventPlayer()) == true) +if (abilities[8] == true) +{ + for (p_loopIterator = 0; 3; 1) + { + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Purple, PositionOf(EventPlayer()), 20); + Damage(PlayersWithinRadius(EventPlayer(), 10, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 25); + StartDamageOverTime(PlayersWithinRadius(EventPlayer(), 10, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 5, 30); + Wait(0.2, WaitBehavior.IgnoreCondition); + } +} + +rule: "Baptiste: Aerial Ace - Jump" +Event.OngoingPlayer +Player.Baptiste +if (abilities[12] == true) +if (IsCrouching(EventPlayer()) == true) +if (HasStatus(EventPlayer(), Status.Hacked) == false) +{ + WaitUntil(!IsCrouching(EventPlayer()), 9999); + WaitUntil(IsJumping(EventPlayer()), 1); + abilityAvailable = true; + Wait(0.25, WaitBehavior.IgnoreCondition); + damageBoost[1] += 30; + UpdatePlayerStats(); + WaitUntil(IsOnGround(EventPlayer()), 99999); + abilityAvailable = false; + damageBoost[1] -= 30; + UpdatePlayerStats(); +} + +rule: "Baptiste: Aerial Ace - Slower fall" +Event.OngoingPlayer +Player.Baptiste +if (abilities[12] == true) +if (abilityAvailable == true) +if (IsAlive(EventPlayer()) == true) +if (IsButtonHeld(EventPlayer(), Button.Jump) == true) +if ((HasStatus(EventPlayer(), Status.Stunned) && HasStatus(EventPlayer(), Status.Hacked)) == false) +if (AltitudeOf(EventPlayer()) >= 1) +if (VerticalSpeedOf(EventPlayer()) < 0) +{ + SetGravity(EventPlayer(), 7.5); + Wait(0.333, WaitBehavior.IgnoreCondition); + PlayEffect(AllPlayers(TeamOf(EventPlayer())), PlayEffect.RingExplosion, Color.Orange, PositionOf(EventPlayer()), 2); + LoopIfConditionIsTrue(); + SetGravity(EventPlayer(), 100); +} + +rule: "Bastion: Fusillade" +Event.OngoingPlayer +Player.Bastion +if (abilities[8] == true) +if (IsFiringPrimary(EventPlayer()) == true) +if (IsInAlternateForm(EventPlayer()) == true) +{ + Wait(1.5, WaitBehavior.AbortWhenFalse); + CancelPrimaryAction(EventPlayer()); + SetAbilityCooldown(EventPlayer(), Button.SecondaryFire, 0); + Wait(0.1, WaitBehavior.IgnoreCondition); + PressButton(EventPlayer(), Button.SecondaryFire); + LoopIfConditionIsTrue(); +} + +rule: "Bastion: Trickshot" +Event.OnDamageDealt +Player.Bastion +{ + AbortIf(!abilities[12]); + AbortIf(EventAbility() != Button.SecondaryFire); + AbortIf(EventDamage() > 30); + Wait(0.5, WaitBehavior.IgnoreCondition); + SetAbilityCooldown(EventPlayer(), Button.SecondaryFire, AbilityCooldown(EventPlayer(), Button.SecondaryFire) - 3); + Damage(PlayersWithinRadius(Victim(), 5, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 30); + Heal(EventPlayer(), EventPlayer(), 50); +} + +rule: "Brigitte: Endeavor" +Event.OngoingPlayer +Team.Team1 +Player.Brigitte +if (abilities[8] == true) +if (AbilityCooldown(EventPlayer(), Button.SecondaryFire) >= 0.1) +{ + CreateEffect(AllPlayers(Team.All), Effect.EchoCloningEffect, Team.Team1, EventPlayer(), 0.4, EffectRev.VisibleToPositionAndRadius); + effects[1] = LastCreatedEntity(); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Orange, EyePosition(EventPlayer()), 15); + Heal(PlayersWithinRadius(EventPlayer(), 15, Team.Team1, RadiusLOS.Off), EventPlayer(), 200); + damageBoost[1] += 150; + speedBoost += 75; + UpdatePlayerStats(); + AddHealthPoolToPlayer(EventPlayer(), HealthType.Armor, MaxHealth(EventPlayer()) / 3, false, true); + hpPool[1] = LastCreatedHealthPool(); + WaitUntil(!abilities[8] || IsDead(EventPlayer()), 6); + damageBoost[1] -= 150; + speedBoost -= 75; + UpdatePlayerStats(); + RemoveHealthPoolFromPlayer(hpPool[1]); + DestroyEffect(effects[1]); +} + +rule: "Brigitte: Whiplash" +Event.PlayerDealtKnockback +Team.Team1 +Player.Brigitte +if (abilities[12] == true) +if (IsUsingAbility1(EventPlayer()) == true) +{ + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosionSound, Color.Green, Victim(), 100); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadExplosion, Color.Orange, Victim(), 2.5); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadPickupEffect, Color.Orange, Victim(), 2.5); + Damage(PlayersWithinRadius(Victim(), 2.5, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 100); + SetStatus(PlayersWithinRadius(Victim(), 2.5, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), Status.Stunned, 1.5); +} + +rule: "Cassidy: Standoff" +Event.OngoingPlayer +Team.Team1 +Player.Cassidy +if (IsUsingUltimate(EventPlayer()) == true) +if (abilities[8] == true) +{ + Wait(0.2, WaitBehavior.IgnoreCondition); + abilityCountdown = false; + ChaseVariableAtRate(abilityCountdown, 9999, 100, RateChaseReevaluation.DestinationAndRate); + Wait(0.5, WaitBehavior.IgnoreCondition); + ChaseVariableAtRate(abilityCountdown, 9999, 275, RateChaseReevaluation.DestinationAndRate); + Wait(0.5, WaitBehavior.IgnoreCondition); + ChaseVariableAtRate(abilityCountdown, 9999, 550, RateChaseReevaluation.DestinationAndRate); +} + +rule: "Cassidy: Standoff - Set root" +Event.OngoingPlayer +Team.Team1 +Player.Cassidy +if (IsUsingUltimate(EventPlayer()) == true) +if (abilities[8] == true) +{ + Wait(0.2, WaitBehavior.IgnoreCondition); + for (p_loopIterator = 0; 5; 1) + { + Wait(1, WaitBehavior.AbortWhenFalse); + PlayEffect(EventPlayer(), PlayEffect.ExplosionSound, Color.White, EventPlayer(), 15); + SetStatus(FilteredArray(PlayersInViewAngle(EventPlayer(), Team.Team2, 103), Health(ArrayElement()) <= abilityCountdown && IsInLineOfSight(EventPlayer(), ArrayElement(), BarrierLOS.NoBarriersBlock)), EventPlayer(), Status.Rooted, 2); + } + StopChasingVariable(abilityCountdown); +} + +rule: "Cassidy: Flashpoint" +Event.OnDamageDealt +Team.Team1 +Player.Cassidy +{ + AbortIf(!abilities[12]); + AbortIf(EventAbility() != Button.Ability2); + if (EventDamage() <= 5) + { + Wait(1.25, WaitBehavior.IgnoreCondition); + Damage(PlayersWithinRadius(Victim(), 6, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 35); + SetStatus(PlayersWithinRadius(Victim(), 6, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), Status.Stunned, 1); + } +} + +rule: "D.Va: Voltage Grid" +Event.OngoingPlayer +Team.Team1 +Player.Dva +if (IsFiringSecondary(EventPlayer()) == true) +if (abilities[8] == true) +{ + PlayEffect(AllPlayers(Team.All), PlayEffect.BadExplosion, Color.Turquoise, EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 2, 0.15); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadExplosion, Color.Turquoise, EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 5, 0.15); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadExplosion, Color.Turquoise, EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 8, 0.15); + Wait(0.3, WaitBehavior.IgnoreCondition); + Damage(PlayersWithinRadius(EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 2, 2.5, Team.Team2, RadiusLOS.Off), EventPlayer(), 20); + Damage(PlayersWithinRadius(EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 5, 2.5, Team.Team2, RadiusLOS.Off), EventPlayer(), 20); + Damage(PlayersWithinRadius(EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 8, 2.5, Team.Team2, RadiusLOS.Off), EventPlayer(), 20); + SetStatus(PlayersWithinRadius(EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 2, 2.5, Team.Team2, RadiusLOS.Off), EventPlayer(), Status.Rooted, 0.4); + SetStatus(PlayersWithinRadius(EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 5, 2.5, Team.Team2, RadiusLOS.Off), EventPlayer(), Status.Rooted, 0.4); + SetStatus(PlayersWithinRadius(EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 8, 2.5, Team.Team2, RadiusLOS.Off), EventPlayer(), Status.Rooted, 0.4); + LoopIfConditionIsTrue(); +} + +rule: "D.Va: Shooting Star" +Event.PlayerDealtKnockback +Team.Team1 +Player.Dva +if (EventAbility() == Button.Ability1) +if (abilities[12] == true) +{ + Damage(Victim(), EventPlayer(), 30); + SetStatus(Victim(), null, Status.Burning, 3); + StartDamageOverTime(Victim(), EventPlayer(), 3, 35); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadExplosion, Color.Red, Victim(), 1); +} + +rule: "Doomfist: Punch Card" +Event.OngoingPlayer +Team.Team1 +Player.Doomfist +if (abilities[8] == true) +if (IsFiringSecondary(EventPlayer()) == true) +{ + Wait(1, WaitBehavior.AbortWhenFalse); + damageBoost[1] += 200; + UpdatePlayerStats(); + WaitUntil(AbilityCooldown(EventPlayer(), Button.SecondaryFire) > 0.1, 1); + damageBoost[1] -= 200; + UpdatePlayerStats(); +} + +rule: "Doomfist: Fissure" +Event.OngoingPlayer +Team.Team1 +Player.Doomfist +if (IsUsingAbility1(EventPlayer()) == true) +if (abilities[12] == true) +{ + Wait(1.25, WaitBehavior.AbortWhenFalse); + WaitUntil(IsOnGround(EventPlayer()), 10); + AbortIf(!IsOnGround(EventPlayer())); + abilityProjectile = PositionOf(EventPlayer()); + abilityActive = true; + WaitUntil(IsDead(EventPlayer()), 5); + abilityActive = false; +} + +rule: "Doomfist: Fissure" +Event.OngoingPlayer +Team.Team1 +Player.Doomfist +if (abilityActive == true) +if (abilities[12] == true) +{ + CreateEffect(AllPlayers(Team.All), Effect.Ring, Color.Orange, abilityProjectile, 8, EffectRev.VisibleToPositionAndRadius); + effects[1] = LastCreatedEntity(); + CreateEffect(AllPlayers(Team.All), Effect.Cloud, Color.Orange, abilityProjectile, 8, EffectRev.VisibleToPositionAndRadius); + effects[2] = LastCreatedEntity(); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Orange, abilityProjectile, 16); + while (abilityActive && abilities[12]) + { + Damage(PlayersWithinRadius(abilityProjectile, 8, Team.Team2, RadiusLOS.Off), EventPlayer(), 20); + Wait(0.235, WaitBehavior.IgnoreCondition); + } + DestroyEffect(effects[1]); + DestroyEffect(effects[2]); +} + +rule: "Echo: Silver Lining" +Event.OnDamageDealt +Team.Team1 +Player.Echo +{ + AbortIf(!abilities[8]); + AbortIf(EventAbility() != Button.SecondaryFire); + AbortIf(IsDuplicating(EventPlayer())); + AbortIf(NormalizedHealth(Victim()) > 0.5); + Damage(Victim(), EventPlayer(), EventDamage()); +} + +rule: "Echo: Focusing Optics" +Event.OnDamageDealt +Team.Team1 +Player.Echo +{ + AbortIf(!abilities[12]); + AbortIf(EventAbility() != Button.Ability2); + AbortIf(IsDuplicating(EventPlayer())); + AbortIf(NormalizedHealth(Victim()) <= 0.5); + AbortIf(NormalizedHealth(Victim()) > 0.9); + Damage(Victim(), EventPlayer(), EventDamage() * 3); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadExplosion, Color.Violet, Victim(), 0.5); +} + +rule: "Genji: Venomous Strike" +Event.OnDamageDealt +Team.Team1 +Player.Genji +{ + AbortIf(!abilities[8]); + AbortIf(EventAbility() != Button.Ability1); + StartHealOverTime(EventPlayer(), EventPlayer(), 3, 15); + StartDamageOverTime(Victim(), EventPlayer(), 3, 15); + Heal(EventPlayer(), EventPlayer(), 5); + Wait(0.25, WaitBehavior.RestartWhenTrue); + Wait(2, WaitBehavior.IgnoreCondition); +} + +rule: "Genji: Dragon's Breath" +Event.OngoingPlayer +Team.Team1 +Player.Genji +if (abilities[12] == true) +if (IsUsingUltimate(EventPlayer()) == true) +if (IsFiringPrimary(EventPlayer()) == true) +{ + CreateEffect(AllPlayers(Team.All), Effect.GoodAura, Color.LimeGreen, abilityProjectile, 1, EffectRev.VisibleToPositionAndRadius); + effects[1] = LastCreatedEntity(); + abilityProjectile = EyePosition(EventPlayer()); + ChaseVariableAtRate(abilityProjectile, abilityEnd, 80, RateChaseReevaluation.DestinationAndRate); + abilityEnd = RayCastHitPosition(EyePosition(EventPlayer()), EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 60, AllLivingPlayers(Team.Team2), AllPlayers(Team.Team1), true); + WaitUntil(!abilities[12] || abilityEnd == abilityProjectile, 1); + DestroyEffect(effects[1]); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosionSound, Color.Green, abilityProjectile, 100); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadExplosion, Color.LimeGreen, abilityProjectile, 5); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadExplosion, Color.Green, abilityProjectile, 5); + Damage(PlayersWithinRadius(abilityProjectile, 5, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 150); + StopChasingVariable(abilityCountdown); +} + +rule: "Hanzo: Firebolt" +Event.OngoingPlayer +Team.Team1 +Player.Hanzo +if (abilities[8] == true) +if (IsFiringPrimary(EventPlayer()) == true) +{ + for (p_loopIterator = 0; 1; 1) + { + Wait(1, WaitBehavior.AbortWhenFalse); + PlayEffect(EventPlayer(), PlayEffect.ExplosionSound, Color.White, EventPlayer(), 100); + } + PlayEffect(AllPlayers(Team.All), PlayEffect.BadExplosion, Color.SkyBlue, EyePosition(EventPlayer()) + Vector(0, -0.25, false) + FacingDirectionOf(EventPlayer()), 1); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosionSound, Color.Team1, EventPlayer(), 100); + while (IsFiringPrimary(EventPlayer())) + { + Wait(0.1, WaitBehavior.IgnoreCondition); + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.Orange, EyePosition(EventPlayer()) + Vector(0, -0.25, false) + FacingDirectionOf(EventPlayer()) * 0.7, 0.001); + } + AbortIf(HasStatus(EventPlayer(), Status.Stunned) || IsDead(EventPlayer()) || IsButtonHeld(EventPlayer(), Button.SecondaryFire) || HasStatus(EventPlayer(), Status.Asleep)); + abilityProjectile = EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * Vector(false, false, 2); + abilityEnd = RayCastHitPosition(EyePosition(EventPlayer()), EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 200, AllLivingPlayers(Team.All), EventPlayer(), false); + SetProjectileSpeed(EventPlayer(), 150); + ChaseVariableAtRate(abilityProjectile, abilityEnd, 165, RateChaseReevaluation.DestinationAndRate); + while (abilityProjectile != abilityEnd) + { + PlayEffect(AllPlayers(Team.All), PlayEffect.BadPickupEffect, Color.Orange, abilityProjectile, 3.5); + PlayEffect(AllPlayers(Team.All), PlayEffect.ExplosionSound, Color.Team1, abilityProjectile, 35); + Wait(0.072, WaitBehavior.IgnoreCondition); + } + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.Orange, abilityProjectile, 4); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosionSound, Color.Team1, abilityProjectile, 150); + Damage(PlayersWithinRadius(abilityProjectile, 4, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 175); + SetProjectileSpeed(EventPlayer(), 100); + StopChasingVariable(abilityProjectile); +} + +rule: "Hanzo: Stormbreak" +Event.OnFinalBlow +Team.Team1 +Player.Hanzo +if (abilities[12] == true) +{ + abilityCountdown = 4; + ChaseVariableAtRate(abilityCountdown, 0, 1, RateChaseReevaluation.DestinationAndRate); +} + +rule: "Hanzo: Stormbreak - Boost" +Event.OngoingPlayer +Team.Team1 +Player.Hanzo +if (abilities[12] == true) +if (abilityCountdown > 0) +{ + CreateEffect(AllPlayers(Team.All), Effect.WinstonPrimalRageEffect, Color.Team1, EventPlayer(), 1, EffectRev.VisibleToPositionAndRadius); + effects[1] = LastCreatedEntity(); + WaitUntil(IsDead(EventPlayer()) || !abilityCountdown || !abilities[12], 99999); + abilityCountdown = false; + DestroyEffect(effects[1]); + StopChasingVariable(abilityCountdown); +} + +rule: "Hanzo: Stormbreak - Reset Cooldowns For Storm Arrows" +Event.OngoingPlayer +Team.Team1 +Player.Hanzo +if (abilityCountdown > 0) +if (AbilityCooldown(EventPlayer(), Button.Ability2) > 0) +{ + SetAbilityCooldown(EventPlayer(), Button.Ability2, false); +} + +rule: "Junker Queen: Shout Very Loudly" +Event.OngoingPlayer +Team.Team1 +Player.JunkerQueen +if (abilities[8] == true) +if (IsUsingAbility1(EventPlayer()) == true) +{ + StartDamageOverTime(RemoveFromArray(PlayersWithinRadius(EventPlayer(), 15, Team.Team2, RadiusLOS.Surfaces), EventPlayer()), EventPlayer(), 5, 8); + StartHealOverTime(EventPlayer(), EventPlayer(), 5, 8 * CountOf(PlayersWithinRadius(EventPlayer(), 15, Team.Team2, RadiusLOS.Surfaces))); +} + +rule: "Junker Queen: Grace Period" +Event.PlayerDealtKnockback +Team.Team1 +Player.JunkerQueen +if (abilities[12] == true) +if (EventAbility() == Button.SecondaryFire) +if (IsMeleeing(EventPlayer()) == false) +{ + StartDamageOverTime(Victim(), EventPlayer(), 2.5, 20); + StartHealOverTime(EventPlayer(), EventPlayer(), 2.5, 20); + Heal(EventPlayer(), EventPlayer(), 60); + Damage(Victim(), EventPlayer(), 40); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadExplosion, Color.Red, Victim(), 0.25); +} + +rule: "Junkrat: Pyromania" +Event.PlayerDealtKnockback +Team.Team1 +Player.Junkrat +{ + AbortIf(!abilities[8]); + AbortIf(EventAbility() == Button.Melee); + AbortIf(Victim() == EventPlayer()); + StartDamageOverTime(Victim(), EventPlayer(), 2, 20); + SetStatus(Victim(), null, Status.Burning, 2); +} + +rule: "Junkrat: Trigger Happy" +Event.OngoingPlayer +Team.Team1 +Player.Junkrat +if (abilities[12] == true) +if (AbilityCharge(EventPlayer(), Button.Ability1) < 5) +{ + Wait(4, WaitBehavior.AbortWhenFalse); + SetAbilityCharge(EventPlayer(), Button.Ability1, AbilityCharge(EventPlayer(), Button.Ability1) + 1); + LoopIfConditionIsTrue(); +} + +rule: "Kiriko: Shinobi Tactics" +Event.OnHealingDealt +Team.Team1 +Player.Kiriko +{ + AbortIf(!abilities[8]); + AbortIf(EventAbility() == null); + Damage(PlayersWithinRadius(Healee(), 6, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), EventHealing() * 2); +} + +rule: "Kiriko: Recession" +Event.PlayerDealtKnockback +Team.Team1 +Player.Kiriko +if (abilities[12] == true) +if (EventAbility() == Button.Ability2) +{ + Damage(Victim(), EventPlayer(), 75); + SetStatus(Victim(), EventPlayer(), Status.Frozen, 1.5); + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.Gray, Victim(), 1); +} + +rule: "Lucio: Power Skating - Damage" +Event.PlayerDealtKnockback +Team.Team1 +Player.Lucio +if (abilities[8] == true) +if (EventAbility() == Button.SecondaryFire) +{ + Damage(Victim(), EventPlayer(), SpeedOf(EventPlayer()) * 5); + ApplyImpulse(Victim(), FacingDirectionOf(EventPlayer()), SpeedOf(EventPlayer()) * 1.5, Relative.ToWorld, ContraryMotion.Cancel); + ApplyImpulse(Victim(), Up(), 4, Relative.ToWorld, ContraryMotion.Incorporate); + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.Green, Victim(), 0.01); +} + +rule: "Lucio: Reverse Amp" +Event.OngoingPlayer +Team.Team1 +Player.Lucio +if (IsUsingAbility2(EventPlayer()) == true) +if (abilities[12] == true) +{ + if (IsUsingAbility1(EventPlayer())) + { + SetStatus(PlayersWithinRadius(EventPlayer(), 12, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), Status.Rooted, 0.75); + } + else + { + Damage(PlayersWithinRadius(EventPlayer(), 12, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 30); + Wait(0.5, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); + } +} + +rule: "Mei: Cold Snap" +Event.OngoingPlayer +Team.Team1 +Player.Mei +if (abilities[8] == true) +if (IsUsingAbility1(EventPlayer()) == true) +{ + Wait(0.5, WaitBehavior.AbortWhenFalse); + WaitUntil(!IsUsingAbility1(EventPlayer()), 99999); + Damage(PlayersWithinRadius(EyePosition(EventPlayer()), 10, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 35); + SetStatus(PlayersWithinRadius(EyePosition(EventPlayer()), 10, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), Status.Frozen, 2); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.SkyBlue, PositionOf(EventPlayer()), 20); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Aqua, PositionOf(EventPlayer()) + Vector(0, 1, false), 20); +} + +rule: "Mei: Polar Vortex" +Event.OngoingPlayer +Player.Mei +if (abilities[12] == true) +if (IsUsingUltimate(EventPlayer()) == true) +{ + damageBoost[1] += 75; + UpdatePlayerStats(); + for (p_loopIterator = 0; 3; 1) + { + MinWait(); + SetUltimateCharge(EventPlayer(), 100); + PressButton(EventPlayer(), Button.Ultimate); + Wait(0.51, WaitBehavior.IgnoreCondition); + } + damageBoost[1] -= 75; + UpdatePlayerStats(); + SetUltimateCharge(EventPlayer(), 0); + Wait(1, WaitBehavior.IgnoreCondition); +} + +rule: "Mercy: Wings of Grand" +Event.OngoingPlayer +Team.Team1 +Player.Mercy +if (abilities[8] == true) +if (IsAlive(EventPlayer()) == true) +if (IsUsingAbility1(EventPlayer()) == true) +{ + if (SpeedOf(EventPlayer()) > 10) + { + Damage(FilteredArray(PlayersWithinRadius(EventPlayer(), 4, Team.Team2, RadiusLOS.Surfaces), !HasStatus(ArrayElement(), Status.KnockedDown)), EventPlayer(), 35); + SetStatus(PlayersWithinRadius(EventPlayer(), 4, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), Status.KnockedDown, 0.8); + ApplyImpulse(PlayersWithinRadius(EventPlayer(), 4, Team.Team2, RadiusLOS.Surfaces), Normalize(VelocityOf(EventPlayer())) + DirectionTowards(EventPlayer(), ThrottleOf(EventPlayer())) + Up() * 1.1, 7.5, Relative.ToWorld, ContraryMotion.Cancel); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadExplosion, Color.Yellow, PositionOf(EventPlayer()), 0.15); + } + Wait(0.25, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); +} + +rule: "Mercy: Holy Light Missiles" +Event.OngoingPlayer +Team.Team1 +Player.Mercy +if (abilities[12] == true) +if (IsUsingUltimate(EventPlayer()) == true) +{ + CreateEffect(AllPlayers(Team.All), Effect.Orb, Color.Yellow, abilityProjectile, 1, EffectRev.VisibleToPositionAndRadius); + effects[1] = LastCreatedEntity(); + abilityProjectile = EyePosition(EventPlayer()); + ChaseVariableAtRate(abilityProjectile, abilityEnd, 100, RateChaseReevaluation.DestinationAndRate); + abilityEnd = RayCastHitPosition(EyePosition(EventPlayer()), EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 60, AllLivingPlayers(Team.Team2), AllPlayers(Team.Team1), true); + WaitUntil(!abilities[12] || abilityEnd == abilityProjectile, 1); + DestroyEffect(effects[1]); + StopChasingVariable(abilityCountdown); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosionSound, Color.Green, abilityProjectile, 100); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadExplosion, Color.Yellow, abilityProjectile, 6); + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodPickupEffect, Color.White, abilityProjectile, 6); + Damage(PlayersWithinRadius(abilityProjectile, 6, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 150); + Heal(PlayersWithinRadius(abilityProjectile, 6, Team.Team1, RadiusLOS.Surfaces), EventPlayer(), 150); + Wait(1.5, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); +} + +rule: "Moira: Flourish" +Event.OngoingPlayer +Team.Team1 +Player.Moira +if (IsUsingAbility1(EventPlayer()) == true) +if (abilities[8] == true) +{ + StartDamageOverTime(PlayersWithinRadius(EventPlayer(), 3, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 2, 25); + StartHealOverTime(PlayersWithinRadius(EventPlayer(), 3, Team.Team1, RadiusLOS.Surfaces), EventPlayer(), 2, 40); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Black, PositionOf(EventPlayer()), 6); + Wait(0.2, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); +} + +rule: "Moira: Catalyst" +Event.OngoingPlayer +Player.Moira +if (abilities[12] == true) +if (IsUsingUltimate(EventPlayer()) == true) +if (IsButtonHeld(EventPlayer(), Button.PrimaryFire) == true) +if (AbilityResource(EventPlayer(), Button.PrimaryFire) > 8) +{ + damageBoost[1] += 300; + healBoost[1] += 300; + speedBoost -= 40; + UpdatePlayerStats(); + WaitUntil(!IsButtonHeld(EventPlayer(), Button.PrimaryFire) || !abilities[12] || !IsUsingUltimate(EventPlayer()), 8); + damageBoost[1] -= 300; + speedBoost += 40; + healBoost[1] -= 300; + UpdatePlayerStats(); + Wait(0.25, WaitBehavior.IgnoreCondition); +} + +rule: "Moira: Catalyst" +Event.OngoingPlayer +Player.Moira +if (abilities[12] == true) +if (IsUsingUltimate(EventPlayer()) == true) +if (IsButtonHeld(EventPlayer(), Button.PrimaryFire) == true) +if (AbilityResource(EventPlayer(), Button.PrimaryFire) > 8) +{ + SetAbilityResource(EventPlayer(), Button.PrimaryFire, AbilityResource(EventPlayer(), Button.PrimaryFire) - 15); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Purple, EyePosition(EventPlayer()), 10); + Damage(PlayersWithinRadius(EyePosition(EventPlayer()), 5, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 35); + Wait(0.5, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); +} + +rule: "Orisa: Melting Point" +Event.OngoingPlayer +Team.Team1 +Player.Orisa +if (abilities[8] == true) +if (IsUsingAbility2(EventPlayer()) == true) +{ + WaitUntil(!IsUsingAbility2(EventPlayer()), 99999); + Damage(PlayersWithinRadius(EventPlayer(), 12, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 70); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.LimeGreen, PositionOf(EventPlayer()), 24); + ApplyImpulse(PlayersWithinRadius(EventPlayer(), 12, Team.Team2, RadiusLOS.Surfaces), Up(), 8, Relative.ToWorld, ContraryMotion.Cancel); + SetStatus(PlayersWithinRadius(EventPlayer(), 12, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), Status.Rooted, 1.5); +} + +rule: "Orisa: Flaming Harpoon" +Event.PlayerDealtKnockback +Team.Team1 +Player.Orisa +if (EventAbility() == Button.SecondaryFire) +if (abilities[12] == true) +{ + StartDamageOverTime(Victim(), EventPlayer(), 3, 20); + SetStatus(Victim(), null, Status.Burning, 3); + SetStatus(Victim(), EventPlayer(), Status.Stunned, 1); +} + +rule: "Pharah: Head Trauma" +Event.PlayerDealtKnockback +Team.Team1 +Player.Pharah +if (abilities[8] == true) +if (EventAbility() == Button.Ability2) +if (Victim() != EventPlayer()) +{ + Damage(Victim(), EventPlayer(), 60); + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.Gray, Victim(), 1); + AbortIf(NormalizedHealth(Victim()) > 0.5); + SetStatus(Victim(), null, Status.Hacked, 1); +} + +rule: "Pharah: Weaponized Storm" +Event.OngoingPlayer +Player.Pharah +if (abilities[12] == true) +if (IsFiringPrimary(EventPlayer()) == true) +if (Ammo(EventPlayer(), false) % 6 == false) +{ + SetProjectileSpeed(EventPlayer(), 125); + abilityEnd = RayCastHitPosition(EyePosition(EventPlayer()), EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 100, AllLivingPlayers(Team.All), EventPlayer(), true); + abilityProjectile = EyePosition(EventPlayer()); + CreateEffect(AllPlayers(Team.All), Effect.BadAura, Color.Orange, abilityProjectile, 1, EffectRev.VisibleToPositionAndRadius); + effects[7] = LastCreatedEntity(); + ChaseVariableAtRate(abilityProjectile, abilityEnd, 35, RateChaseReevaluation.DestinationAndRate); + WaitUntil(!abilities[12] || abilityProjectile == abilityEnd, 99999); + DestroyEffect(effects[7]); + for (p_loopIterator = 0; 6; 1) + { + PlayEffect(AllPlayers(Team.All), PlayEffect.BadPickupEffect, Color.Orange, abilityProjectile + Vector(RandomReal(-1.5, 1.5), RandomReal(-0.5, 0.5), RandomReal(-1.5, 1.5)), 1); + PlayEffect(AllPlayers(Team.All), PlayEffect.ExplosionSound, Color.Team1, abilityProjectile, 25); + Damage(PlayersWithinRadius(abilityProjectile, 4, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 20); + Wait(0.1, WaitBehavior.IgnoreCondition); + } + SetProjectileSpeed(EventPlayer(), 100); + StopChasingVariable(abilityProjectile); +} + +rule: "Ramattra: Vile Dominance" +Event.OngoingPlayer +Team.Team1 +Player.Ramattra +if (abilities[8] == true) +if (HealthOfType(EventPlayer(), HealthType.Armor) >= 100) +{ + speedBoost += 30; + abilityActive = true; + UpdatePlayerStats(); + WaitUntil(AbilityCooldown(EventPlayer(), Button.Ability1) > 0.1 && !IsUsingUltimate(EventPlayer()) || !abilities[8], 9999); + speedBoost -= 30; + abilityActive = false; + UpdatePlayerStats(); +} + +rule: "Ramattra: Vile Dominance" +Event.OnDamageDealt +Team.Team1 +Player.Ramattra +{ + AbortIf(!abilityActive); + AbortIf(EventAbility() == null); + AbortIf(EventAbility() == Button.Ability2); + AbortIf(EventAbility() == Button.Ultimate); + SetStatus(Victim(), EventPlayer(), Status.Rooted, 0.75); +} + +rule: "Ramattra: Nether Sector" +Event.OnDamageDealt +Team.Team1 +Player.Ramattra +{ + AbortIf(!abilities[12]); + AbortIf(!IsOnGround(EventPlayer())); + AbortIf(EventAbility() != Button.Ability2); + Heal(EventPlayer(), EventPlayer(), 20); + SetUltimateCharge(EventPlayer(), UltimateChargePercent(EventPlayer()) + 1); + Wait(0.1, WaitBehavior.IgnoreCondition); +} + +rule: "Reaper: Wraith Wrath" +Event.OngoingPlayer +Team.Team1 +Player.Reaper +if (IsUsingAbility1(EventPlayer()) == true) +if (abilities[8] == true) +{ + Wait(0.1, WaitBehavior.AbortWhenFalse); + CancelPrimaryAction(EventPlayer()); + CreateEffect(AllPlayers(Team.All), Effect.ReaperWraithFormEffect, Color.Team1, EventPlayer(), true, EffectRev.VisibleToPositionAndRadius); + effects[1] = LastCreatedEntity(); + damageBoost[1] += 30; + speedBoost += 50; + UpdatePlayerStats(); + DisallowButton(EventPlayer(), Button.Ability1); + SetStatus(EventPlayer(), null, Status.PhasedOut, 3); + WaitUntil(IsDead(EventPlayer()) || !abilities[8], 3); + AllowButton(EventPlayer(), Button.Ability1); + SetAbilityCooldown(EventPlayer(), Button.Ability1, 8); + damageBoost[1] -= 30; + speedBoost -= 50; + UpdatePlayerStats(); + DestroyEffect(effects[1]); +} + +rule: "Reaper: Loom" +Event.OngoingPlayer +Team.Team1 +Player.Reaper +if (IsUsingAbility1(EventPlayer()) == true) +if (abilities[12] == true) +{ + SetStatus(FilteredArray(PlayersInViewAngle(EventPlayer(), Team.Team2, 45), IsInLineOfSight(EventPlayer(), ArrayElement(), BarrierLOS.NoBarriersBlock)), EventPlayer(), Status.Hacked, 2); + Damage(FilteredArray(PlayersInViewAngle(EventPlayer(), Team.Team2, 45), IsInLineOfSight(ArrayElement(), EventPlayer(), BarrierLOS.NoBarriersBlock)), EventPlayer(), 35); +} + +rule: "Reinhardt: Fire Blast" +Event.OnDamageDealt +Team.Team1 +Player.Reinhardt +{ + AbortIf(!abilities[8]); + AbortIf(EventAbility() != Button.Ability2); + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.Orange, Victim(), 5); + StartDamageOverTime(PlayersWithinRadius(Victim(), 5, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 5, 20); + SetStatus(PlayersWithinRadius(Victim(), 5, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), Status.Burning, 5); +} + +rule: "Reinhardt: Epicenter" +Event.OngoingPlayer +Team.Team1 +Player.Reinhardt +if (abilities[12] == true) +if (IsUsingUltimate(EventPlayer()) == true) +if (IsOnGround(EventPlayer()) == true) +{ + SetStatus(PlayersWithinRadius(EventPlayer(), 20, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), Status.KnockedDown, 2.5); + for (p_loopIterator = 0; 3; 1) + { + Wait(0.032, WaitBehavior.IgnoreCondition); + Damage(PlayersWithinRadius(EventPlayer(), p_loopIterator * 10, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 50); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Orange, PositionOf(EventPlayer()), p_loopIterator * 20); + } + Wait(5, WaitBehavior.IgnoreCondition); +} + +rule: "Roadhog: Stench" +Event.OngoingPlayer +Team.Team1 +Player.Roadhog +if (abilities[8] == true) +if (IsAlive(EventPlayer()) == true) +{ + CreateEffect(AllPlayers(Team.All), Effect.Ring, Color.Violet, EventPlayer(), 8, EffectRev.VisibleToPositionAndRadius); + effects[1] = LastCreatedEntity(); + WaitUntil(!abilities[8] || IsDead(EventPlayer()), 99999); + DestroyEffect(effects[1]); + Wait(0.1, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); +} + +rule: "Roadhog: Stench effect" +Event.OngoingPlayer +Team.Team1 +Player.Roadhog +if (DistanceBetween(EventPlayer(), ClosestPlayerTo(EventPlayer(), Team.Team2)) <= 8) +if (abilities[8] == true) +{ + Damage(PlayersWithinRadius(EventPlayer(), 8, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 9); + Wait(0.4, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); +} + +rule: "Roadhog: Chainsnap" +Event.OngoingPlayer +Team.Team1 +Player.Roadhog +if (abilities[12] == true) +if (IsAlive(EventPlayer()) == true) +{ + StartDamageModification(IsUsingAbility1(EventPlayer()) ? AllPlayers(Team.Team2) : [], EventPlayer(), 400, DamageModificationRev.ReceiversDamagersAndDamagePercent); + damageMod = LastDamageModificationID(); + WaitUntil(!abilities[12] || IsDead(EventPlayer()), 99999); + StopDamageModification(damageMod); + Wait(0.1, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); +} + +rule: "Roadhog: Chainsnap - Reset cooldown" +Event.OnElimination +Team.Team1 +Player.Roadhog +if (abilities[12] == true) +{ + WaitUntil(!IsUsingAbility1(EventPlayer()), 3); + SetAbilityCooldown(EventPlayer(), Button.Ability1, false); +} + +rule: "Sigma: Accretion Disk" +Event.OngoingPlayer +Team.Team1 +Player.Sigma +if (abilities[8] == true) +if (IsUsingAbility2(EventPlayer()) == true) +{ + SetProjectileSpeed(EventPlayer(), 150); + SetProjectileGravity(EventPlayer(), 0); + WaitUntil(!abilities[8] || !IsUsingAbility2(EventPlayer()), 5); + SetProjectileSpeed(EventPlayer(), 100); + SetProjectileGravity(EventPlayer(), 100); +} + +rule: "Sigma: Accretion Disk" +Event.PlayerDealtKnockback +Team.Team1 +Player.Sigma +{ + AbortIf(!abilities[8]); + AbortIf(EventAbility() != Button.Ability2); + AbortIf(Victim() == EventPlayer()); + SetStatus(Victim(), EventPlayer(), Status.KnockedDown, 1.5); + Damage(Victim(), EventPlayer(), EventDamage() * 0.75); +} + +rule: "Sigma: String Theory" +Event.OngoingPlayer +Team.Team1 +Player.Sigma +if (abilities[12] == true) +if (IsUsingAbility1(EventPlayer()) == true) +{ + Wait(1.8, WaitBehavior.AbortWhenFalse); + abilityProjectile = EyePosition(EventPlayer()); + abilityEnd = RayCastHitPosition(EyePosition(EventPlayer()), EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 50, AllPlayers(Team.Team2), EventPlayer(), true); + ChaseVariableAtRate(abilityProjectile, abilityEnd, 40, RateChaseReevaluation.DestinationAndRate); + CreateEffect(AllPlayers(Team.All), Effect.Sphere, Color.Violet, abilityProjectile, 0.6, EffectRev.VisibleToPositionAndRadius); + effects[1] = LastCreatedEntity(); + CreateEffect(AllPlayers(Team.All), Effect.GoodAura, Color.Violet, abilityProjectile, 0.6, EffectRev.VisibleToPositionAndRadius); + effects[2] = LastCreatedEntity(); + Wait(0.25, WaitBehavior.IgnoreCondition); + abilityCountdown = HealthOfType(EventPlayer(), HealthType.Shields); + WaitUntil(!abilities[12] || abilityProjectile == abilityEnd, 5); + StopChasingVariable(abilityProjectile); + DestroyEffect(effects[1]); + DestroyEffect(effects[2]); + Damage(PlayersWithinRadius(abilityProjectile, Min(10, 1.5 + abilityCountdown * 0.017), Team.Team2, RadiusLOS.Off), EventPlayer(), Min(200, 100 + abilityCountdown / 5)); + PlayEffect(AllPlayers(Team.All), PlayEffect.DebuffImpactSound, Color.Violet, abilityProjectile, 150); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadExplosion, Color.Violet, abilityProjectile, Min(10, 1.5 + abilityCountdown * 0.017)); + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.Purple, abilityProjectile, Min(10, 1.5 + abilityCountdown * 0.017)); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Violet, abilityProjectile, Min(20, 3 + abilityCountdown * 0.017)); +} + +rule: "Sojourn: Thunderout Kicks" +Event.OngoingPlayer +Team.Team1 +Player.Sojourn +if (abilities[8] == true) +if (IsUsingAbility1(EventPlayer()) == true) +{ + abilityActive = 1 + TotalTimeElapsed(); + WaitUntil(AbilityCooldown(EventPlayer(), Button.Ability1) > 1 || IsButtonHeld(EventPlayer(), Button.Jump), 1); + AbortIf(abilityActive < TotalTimeElapsed()); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Turquoise, PositionOf(EventPlayer()), 12); + Damage(PlayersWithinRadius(EventPlayer(), 6, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 75); +} + +rule: "Sojourn: Matter Splatter" +Event.OnDamageDealt +Team.Team1 +Player.Sojourn +{ + AbortIf(!abilities[12]); + AbortIf(EventAbility() != Button.SecondaryFire); + AbortIf(!EventWasCriticalHit()); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadExplosion, Color.Turquoise, EyePosition(Victim()), 3.5); + Damage(RemoveFromArray(PlayersWithinRadius(Victim(), 3.5, Team.Team2, RadiusLOS.Surfaces), Victim()), EventPlayer(), EventDamage()); +} + +rule: "Soldier76: Triple Threat" +Event.OngoingPlayer +Team.Team1 +Player.Soldier76 +if (abilities[8] == true) +if (IsFiringSecondary(EventPlayer()) == true) +{ + abilityCountdown = RayCastHitPosition(EyePosition(EventPlayer()), RayCastHitPosition(EyePosition(EventPlayer()), EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 60, AllLivingPlayers(Team.Team2), null, false) + WorldVectorOf(Vector(-2, false, false), EventPlayer(), LocalVector.Rotation), AllLivingPlayers(Team.Team2), null, false); + abilityProjectile = RayCastHitPosition(EyePosition(EventPlayer()), RayCastHitPosition(EyePosition(EventPlayer()), EyePosition(EventPlayer()) + FacingDirectionOf(EventPlayer()) * 60, AllLivingPlayers(Team.Team2), null, false) + WorldVectorOf(Vector(2, false, false), EventPlayer(), LocalVector.Rotation), AllLivingPlayers(Team.Team2), null, false); + abilityAvailable = EyePosition(EventPlayer()) + WorldVectorOf(Vector(false, -0.25, false), EventPlayer(), LocalVector.Rotation); + abilityEnd = EyePosition(EventPlayer()) + WorldVectorOf(Vector(false, -0.25, false), EventPlayer(), LocalVector.Rotation); + ChaseVariableAtRate(abilityAvailable, abilityProjectile, 60, RateChaseReevaluation.DestinationAndRate); + ChaseVariableAtRate(abilityEnd, abilityCountdown, 60, RateChaseReevaluation.DestinationAndRate); +} + +rule: "Soldier76: Triple Threat - First Rocket" +Event.OngoingPlayer +Team.Team1 +Player.Soldier76 +if (abilityProjectile != abilityAvailable) +if (abilities[8] == true) +if (AbilityCooldown(EventPlayer(), Button.SecondaryFire) > 0.1) +{ + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.Aqua, abilityAvailable, 0.4); + Wait(0.064, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.SkyBlue, abilityAvailable, 2.5); + StopChasingVariable(abilityAvailable); + MinWait(); + Damage(PlayersWithinRadius(abilityAvailable, 2.5, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 80); + StopChasingVariable(abilityAvailable); + abilityAvailable = false; + abilityProjectile = false; + MinWait(); +} + +rule: "Soldier76: Triple Threat - Second Rocket" +Event.OngoingPlayer +Team.Team1 +Player.Soldier76 +if (abilityCountdown != abilityEnd) +if (abilities[8] == true) +if (AbilityCooldown(EventPlayer(), Button.SecondaryFire) > 0.1) +{ + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.Aqua, abilityEnd, 0.4); + Wait(0.064, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.SkyBlue, abilityEnd, 2.5); + StopChasingVariable(abilityEnd); + Damage(PlayersWithinRadius(abilityEnd, 2.5, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 80); + abilityEnd = false; + abilityCountdown = false; +} + +rule: "Soldier76: Triple Threat - Init rocket" +Event.OngoingPlayer +Team.Team1 +Player.Soldier76 +if (abilities[8] == true) +{ + abilityProjectile = abilityAvailable; + abilityCountdown = abilityEnd; +} + +rule: "Soldier76: Espionage" +Event.OnHealingDealt +Team.Team1 +Player.Soldier76 +{ + AbortIf(!abilities[12]); + AbortIf(EventAbility() != Button.Ability2); + if (!Healee().soldierEspionage) + { + Healee().soldierEspionage = true; + } +} + +rule: "Soldier76: Espionage - Allies effect" +Event.OngoingPlayer +Team.Team1 +if (soldierEspionage == true) +{ + soldierEspionage = false; + Wait(0.4, WaitBehavior.IgnoreCondition); +} + +rule: "Sombra: Going Viral" +Event.OngoingPlayer +Team.Team1 +Player.Sombra +if (abilities[8] == true) +if (IsUsingAbility1(EventPlayer()) == true) +{ + Wait(0.5, WaitBehavior.AbortWhenFalse); + WaitUntil(!IsUsingAbility1(EventPlayer()), 20); + CreateEffect(AllPlayers(Team.All), Effect.Sphere, Color.Purple, EventPlayer(), 24 * TotalTimeElapsed() % 12, EffectRev.VisibleToPositionAndRadius); + effects[1] = LastCreatedEntity(); + SetAbilityCooldown(EventPlayer(), Button.SecondaryFire, 0); + SetStatus(EventPlayer(), EventPlayer(), Status.Invincible, 0.75); + Wait(0.5, WaitBehavior.IgnoreCondition); + Damage(PlayersWithinRadius(EventPlayer(), 12, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 50); + SetStatus(PlayersWithinRadius(EventPlayer(), 12, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), Status.Hacked, 8); + DestroyEffect(effects[1]); +} + +rule: "Sombra: Cyberattack" +Event.OngoingPlayer +Team.Team1 +Player.Sombra +if (abilities[12] == true) +if (IsUsingAbility2(EventPlayer()) == true) +{ + WaitUntil(!IsUsingAbility2(EventPlayer()), 99999); + AbortIf(IsButtonHeld(EventPlayer(), Button.Interact) || AbilityCooldown(EventPlayer(), Button.Ability2) >= 2.8); + AbortIf(IsDead(EventPlayer())); + Wait(0.25, WaitBehavior.IgnoreCondition); + Damage(PlayersWithinRadius(EventPlayer(), 8, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 80); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosionSound, Color.White, EyePosition(EventPlayer()), 20000); + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.Purple, EyePosition(EventPlayer()), 8); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Violet, EyePosition(EventPlayer()), 16); + SetStatus(PlayersWithinRadius(EyePosition(EventPlayer()), 8, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), Status.Hacked, 3); +} + +rule: "Symmetra: Sentry Paragon" +Event.OngoingPlayer +Team.Team1 +Player.Symmetra +if (abilities[8] == true) +if (IsAlive(EventPlayer()) == true) +{ + Wait(0.5, WaitBehavior.AbortWhenFalse); + StartDamageModification(AllPlayers(Team.Team2), EventPlayer(), 66.667, DamageModificationRev.ReceiversDamagersAndDamagePercent); + damageMod = LastDamageModificationID(); + damageBoost[1] += 50; + UpdatePlayerStats(); + WaitUntil(!abilities[8] || IsDead(EventPlayer()), 99999); + damageBoost[1] -= 50; + UpdatePlayerStats(); + StopDamageModification(damageMod); + Wait(0.1, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); +} + +rule: "Symmetra: Shield Generator" +Event.OnFinalBlow +Team.Team1 +Player.Symmetra +if (abilities[12] == true) +{ + damageBoost[1] += 30; + speedBoost += 30; + UpdatePlayerStats(); + AddHealthPoolToPlayer(AllPlayers(Team.Team1), HealthType.Shields, Min(200, MaxHealth(EventPlayer()) * 0.25), false, false); + hpPool[6] = LastCreatedHealthPool(); + CreateEffect(AllPlayers(Team.All), Effect.AnaNanoBoostedEffect, Color.Team1, EventPlayer(), 1, EffectRev.VisibleToPositionAndRadius); + effects[1] = LastCreatedEntity(); + WaitUntil(!abilities[12] || IsDead(EventPlayer()), 10); + DestroyEffect(effects[1]); + RemoveHealthPoolFromPlayer(hpPool[6]); + damageBoost[1] -= 30; + speedBoost -= 30; + UpdatePlayerStats(); +} + +rule: "Torbjorn: Heatwave" +Event.OngoingPlayer +Team.Team1 +Player.Torbjorn +if (abilities[8] == true) +if ((IsUsingAbility2(EventPlayer()) || IsUsingUltimate(EventPlayer())) == true) +{ + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Orange, PositionOf(EventPlayer()), 11); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Orange, PositionOf(EventPlayer()), 12); + StartDamageOverTime(RemoveFromArray(PlayersWithinRadius(EventPlayer(), 6, Team.Team2, RadiusLOS.Surfaces), EventPlayer()), EventPlayer(), 3, 20); + SetStatus(RemoveFromArray(PlayersWithinRadius(EventPlayer(), 6, Team.Team2, RadiusLOS.Surfaces), EventPlayer()), EventPlayer(), Status.Burning, 3); + Damage(PlayersWithinRadius(EventPlayer(), 6, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 15); + Wait(0.75, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); +} + +rule: "Torbjorn: Melting Point" +Event.OnElimination +Team.Team1 +Player.Torbjorn +if (abilities[12] == true) +if (EventAbility() == Button.Ability1) +{ + abilityCountdown += 6; + ChaseVariableAtRate(abilityCountdown, 0, 1, RateChaseReevaluation.DestinationAndRate); +} + +rule: "Torbjorn: Melting Point - Boost" +Event.OngoingPlayer +Team.Team1 +Player.Torbjorn +if (abilities[12] == true) +if (abilityCountdown > 0) +{ + StartDamageModification(AllPlayers(Team.Team2), EventPlayer(), 33, DamageModificationRev.ReceiversDamagersAndDamagePercent); + damageMod = LastDamageModificationID(); + damageBoost[1] += 300; + UpdatePlayerStats(); + WaitUntil(IsDead(EventPlayer()) || !abilityCountdown || !abilities[12], 99999); + abilityCountdown = false; + StopDamageModification(damageMod); + damageBoost[1] -= 300; + UpdatePlayerStats(); + StopChasingVariable(abilityCountdown); +} + +rule: "Tracer: Vortex" +Event.OngoingPlayer +Team.Team1 +Player.Tracer +if (IsUsingAbility2(EventPlayer()) == true) +if (abilities[8] == true) +{ + Heal(PlayersWithinRadius(EventPlayer(), 10, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 1); + Damage(PlayersWithinRadius(EventPlayer(), 10, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 25); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Red, PositionOf(EventPlayer()), 20); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Yellow, PositionOf(EventPlayer()), 18); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Green, PositionOf(EventPlayer()), 16); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Aqua, PositionOf(EventPlayer()), 14); + SetEnvironmentCreditPlayer(PlayersWithinRadius(EventPlayer(), 10, Team.Team2, RadiusLOS.Surfaces), EventPlayer()); +} + +rule: "Tracer: Vortex 2" +Event.OnHealingTaken +Team.Team2 +{ + AbortIf(!Healer().abilities[8]); + AbortIf(!IsUsingAbility2(Healer())); + DisableMovementCollisionWithPlayers(EventPlayer()); + ApplyImpulse(EventPlayer(), Up(), 3, Relative.ToWorld, ContraryMotion.Cancel); + SetGravity(EventPlayer(), false); + Wait(0.05, WaitBehavior.IgnoreCondition); + ApplyImpulse(EventPlayer(), DirectionTowards(EventPlayer(), Healer()), DistanceBetween(EventPlayer(), Healer()) * 3.4, Relative.ToWorld, ContraryMotion.Cancel); + SetStatus(EventPlayer(), null, Status.Rooted, 1); + Wait(0.23, WaitBehavior.IgnoreCondition); + SetGravity(EventPlayer(), 100); + EnableMovementCollisionWithPlayers(EventPlayer()); + CancelMomentum(); +} + +rule: "Tracer: Chain Reaction" +Event.OngoingPlayer +Team.Team2 +if (IsTrueForAny(FilteredArray(AllLivingPlayers(Team.Team2), ArrayElement().chainReactionOn), DistanceBetween(EventPlayer(), ArrayElement()) <= 7) == true) +if (chainReactionImmune == false) +if (chainReactionOn == false) +if (IsAlive(EventPlayer()) == true) +{ + Wait(0.25, WaitBehavior.IgnoreCondition); + chainReactionOn = true; +} + +rule: "Tracer: Chain Reaction 2" +Event.OngoingPlayer +Team.Team2 +if (chainReactionOn == true) +{ + Wait(0.1, WaitBehavior.IgnoreCondition); + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.Aqua, EventPlayer(), 3); + Damage(EventPlayer(), PlayersOnHero(Hero.Tracer, Team.Team1), 200); + Wait(0.5, WaitBehavior.IgnoreCondition); + chainReactionImmune = true; + chainReactionOn = false; + Wait(2, WaitBehavior.IgnoreCondition); + chainReactionImmune = false; +} + +rule: "Tracer: Chain Reaction 3" +Event.OnDamageDealt +Team.Team1 +Player.Tracer +{ + AbortIf(!abilities[12]); + AbortIf(EventAbility() != Button.Ultimate); + AbortIf(EventDamage() <= 20); + Victim().chainReactionOn = true; +} + +rule: "Widowmaker: Baiser De Soie" +Event.OnDamageDealt +Team.Team1 +Player.Widowmaker +{ + AbortIf(!abilities[8]); + AbortIf(EventAbility() != Button.PrimaryFire); + AbortIf(!IsFiringSecondary(EventPlayer())); + AbortIf(!EventWasCriticalHit()); + AbortIf(NormalizedHealth(Victim()) > 0.3); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadPickupEffect, Color.Violet, Victim(), 3); + Damage(Victim(), EventPlayer(), 10000); + Damage(PlayersWithinRadius(Victim(), 3, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), EventDamage()); +} + +rule: "Widowmaker: Felt More Alive" +Event.OngoingPlayer +Team.Team1 +Player.Widowmaker +if (abilities[12] == true) +if (IsFiringSecondary(EventPlayer()) == true) +if (IsInAir(EventPlayer()) == true) +{ + SetGravity(EventPlayer(), 20); + damageBoost[1] += 40; + UpdatePlayerStats(); + WaitUntil(!IsFiringSecondary(EventPlayer()) || !abilities[12] || !IsInAir(EventPlayer()), 99999); + SetGravity(EventPlayer(), 100); + damageBoost[1] -= 40; + UpdatePlayerStats(); +} + +rule: "Winston: Lightning Strikes Twice" +Event.OnDamageDealt +Team.Team1 +Player.Winston +{ + AbortIf(!abilities[8]); + AbortIf(EventAbility() != Button.SecondaryFire); + Wait(1, WaitBehavior.IgnoreCondition); + AbortIf(IsDead(Victim())); + Damage(Victim(), EventPlayer(), EventDamage()); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosionSound, Color.White, Victim(), 50); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadExplosion, Color.Blue, Victim(), 1); +} + +rule: "Winston: Quake" +Event.OngoingPlayer +Team.Team1 +Player.Winston +if (abilities[12] == true) +if (IsUsingAbility1(EventPlayer()) == true) +{ + Wait(0.25, WaitBehavior.IgnoreCondition); + WaitUntil(IsOnGround(EventPlayer()), 99999); + AbortIf(IsDead(EventPlayer())); + Damage(PlayersWithinRadius(EventPlayer(), 7.5, Team.Team2, RadiusLOS.SurfacesAndAllBarriers), EventPlayer(), 30); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.White, PositionOf(EventPlayer()), 15); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Gray, PositionOf(EventPlayer()), 14); + SetStatus(PlayersWithinRadius(EventPlayer(), 7.5, Team.Team2, RadiusLOS.SurfacesAndAllBarriers), EventPlayer(), Status.Stunned, 1); +} + +rule: "Wrecking Ball: Mirror Ball" +Event.OnDamageTaken +Team.Team1 +Player.WreckingBall +{ + AbortIf(!abilities[8]); + Damage(PlayersWithinRadius(EventPlayer(), 4, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), EventDamage() * 0.6); +} + +rule: "Wrecking Ball: Distort" +Event.OngoingPlayer +Team.Team1 +Player.WreckingBall +if (abilities[12] == true) +if (IsUsingAbility2(EventPlayer()) == true) +{ + for (p_loopIterator = false; 4; 1) + { + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Purple, PositionOf(EventPlayer()), 20); + Damage(PlayersWithinRadius(EventPlayer(), 10, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 25); + SetStatus(PlayersWithinRadius(EventPlayer(), 10, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), Status.Hacked, 2); + Wait(0.1, WaitBehavior.IgnoreCondition); + } +} + +rule: "Zarya: Combusta-bubble - Detect Barrier Target" +Event.OngoingPlayer +Team.Team1 +Player.Zarya +if (abilities[8] == true) +if (IsUsingAbility2(EventPlayer()) == true) +{ + Wait(0.025, WaitBehavior.IgnoreCondition); + abilityEnd = FirstOf(FilteredArray(PlayersWithinRadius(EventPlayer(), 30, Team.Team1, RadiusLOS.Surfaces), HasStatus(ArrayElement(), Status.Invincible) && IsAlive(ArrayElement()) && IsInViewAngle(EventPlayer(), ArrayElement(), 103))); + WaitUntil(!IsUsingAbility2(EventPlayer()), 2); + PlayEffect(AllPlayers(Team.All), PlayEffect.ExplosionSound, Color.Orange, abilityEnd, 120); + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.Orange, EyePosition(abilityEnd), 6); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadPickupEffect, Color.Yellow, EyePosition(abilityEnd), 6); + Damage(PlayersWithinRadius(EyePosition(abilityEnd), 6, Team.Team2, RadiusLOS.Surfaces), abilityEnd, 100); +} + +rule: "Zarya: Combusta-Bubble - Self bubble" +Event.OngoingPlayer +Team.Team1 +Player.Zarya +if (abilities[8] == true) +if (IsUsingAbility1(EventPlayer()) == true) +{ + Wait(0.1, WaitBehavior.AbortWhenFalse); + WaitUntil(!IsUsingAbility1(EventPlayer()), 2); + PlayEffect(AllPlayers(Team.All), PlayEffect.ExplosionSound, Color.Orange, EventPlayer(), 120); + PlayEffect(AllPlayers(Team.All), PlayEffect.GoodExplosion, Color.Orange, EyePosition(EventPlayer()), 6); + PlayEffect(AllPlayers(Team.All), PlayEffect.BadPickupEffect, Color.Yellow, EyePosition(EventPlayer()), 6); + Damage(PlayersWithinRadius(EventPlayer(), 6, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 100); +} + +rule: "Zarya: Power Surge" +Event.OngoingPlayer +Team.Team1 +Player.Zarya +if (abilities[12] == true) +if (IsUsingAbility1(EventPlayer()) == true) +{ + AbortIf(!HasStatus(EventPlayer(), Status.Invincible)); + Damage(EventPlayer(), null, 10000); + Wait(0.1, WaitBehavior.IgnoreCondition); + SetAbilityCooldown(EventPlayer(), Button.Ability1, false); + PressButton(EventPlayer(), Button.Ability1); + Wait(3, WaitBehavior.IgnoreCondition); +} + +rule: "Zenyatta: Stress Relief" +Event.OngoingPlayer +Team.Team1 +Player.Zenyatta +if (abilities[8] == true) +if (IsFiringSecondary(EventPlayer()) == true) +{ + Wait(2, WaitBehavior.AbortWhenFalse); + PlayEffect(EventPlayer(), PlayEffect.ExplosionSound, Color.Black, EventPlayer(), 150); + damageBoost[1] += 50; + UpdatePlayerStats(); + Wait(0.75, WaitBehavior.IgnoreCondition); + damageBoost[1] -= 50; + UpdatePlayerStats(); +} + +rule: "Zenyatta: Perfect Balance" +Event.OngoingPlayer +Team.Team1 +Player.Zenyatta +if (IsUsingUltimate(EventPlayer()) == true) +if (abilities[12] == true) +{ + StartDamageOverTime(PlayersWithinRadius(EventPlayer(), 12, Team.Team2, RadiusLOS.Surfaces), EventPlayer(), 1, 100); + PlayEffect(AllPlayers(Team.All), PlayEffect.RingExplosion, Color.Orange, EventPlayer(), 24); + Wait(1, WaitBehavior.IgnoreCondition); + LoopIfConditionIsTrue(); +} + +rule: "Team 1 (perk): Bulletstorm" +Event.OngoingPlayer +Team.Team1 +if (perk[1] == true) +if ((Ammo(EventPlayer(), 0) < MaxAmmo(EventPlayer(), 0) || Ammo(EventPlayer(), 1) < MaxAmmo(EventPlayer(), 1)) == true) +{ + SetAmmo(EventPlayer(), 0, 1000); + SetAmmo(EventPlayer(), 1, 1000); +} + +rule: "Team 1 Challenges" +Event.OnPlayerJoin +Team.Team1 +{ + if (perk[2] == 1) + { + CreateHudText(EventPlayer(), null, "Up You Go", null, Location.Left, 917, Color.White, Color.Green, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + abilityHUD[17] = LastTextID(); + } + if (perk[0] == 1) + { + CreateHudText(EventPlayer(), null, "Sharpshooter", null, Location.Left, 918, Color.White, Color.Green, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + abilityHUD[18] = LastTextID(); + } + if (perk[1] == 1) + { + CreateHudText(EventPlayer(), null, "Bulletstorm", null, Location.Left, 919, Color.White, Color.Green, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + abilityHUD[19] = LastTextID(); + } + UpdatePlayerStats(); +} + +rule: "Stuff to do when Player leaves" +Event.OnPlayerLeave +Team.Team1 +{ + automaticRepair -= abilities[16]; +} + +void Refund() "Refund" +{ + # Refund Money + money[0] += money[1]; + money[1] = 0; + # Reset Headhunter + abilities[1] = 0; + # Reset Ambush + abilities[2] = 0; + # Reset QuickFix + abilities[3] = 0; + # Reset HeavyWeight + abilities[4] = 0; + # Reset Charged + abilities[5] = 0; + # Reset Haste + abilities[6] = 0; + # Reset HeavyImpact + abilities[7] = 0; + # Reset HeroTalent1 + abilities[8] = 0; + # Reset SecondWind + abilities[9] = 0; + # Reset BindingHeal + abilities[10] = 0; + # Reset Resilience + abilities[11] = 0; + # Reset HeroTalent2 + abilities[12] = 0; + # Reset Damage + abilities[13] = 0; + # Reset Health + abilities[14] = 0; + # Reset Healing + abilities[15] = 0; + # Reset automaticRepair + automaticRepair -= abilities[16]; + abilities[16] = 0; + UpdatePlayerStats(); +} + +rule: "Brig Shield Bash Stun" +Event.PlayerDealtKnockback +Team.Team1 +Player.Brigitte +{ + SetStatus(Victim(), null, Status.Stunned, 1); +} + +rule: "Lucio Dash HUD Creation" +Event.OngoingPlayer +Team.Team1 +if (HeroOf(EventPlayer()) == Hero.Lucio) +{ + if (lucioDashActive == false) + { + lucioDashActive = true; + CreateHudText(EventPlayer(), null, <"<0> Slam on ground - Press: <1>", AbilityIconString(Hero.WreckingBall, Button.Crouch), InputBindingString(Button.Crouch)>, null, Location.Left, 1000, Color.White, Color.Green, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + lucioDashIcon = LastTextID(); + } +} + +rule: "Lucio Dash Remove HUD" +Event.OngoingPlayer +Team.Team1 +if (HeroOf(EventPlayer()) != Hero.Lucio) +if (lucioDashActive == true) +{ + DestroyHudText(lucioDashIcon); + lucioDashActive = false; +} + +rule: "Lucio Dash" +Event.OngoingPlayer +Team.Team1 +if (HeroOf(EventPlayer()) == Hero.Lucio) +if (lucioDashActive == true) +if (IsOnGround(EventPlayer()) == false) +if (IsButtonHeld(EventPlayer(), Button.Crouch) == true) +{ + ApplyImpulse(EventPlayer(), Down(), 20, Relative.ToWorld, ContraryMotion.Cancel); +} + +rule: "Ana Self-Nano" +Event.OngoingPlayer +Team.Team1 +Player.Ana +if (IsButtonHeld(EventPlayer(), Button.Ultimate) == true) +if (UltimateChargePercent(EventPlayer()) == 100) +if (IsDummyBot(EventPlayer()) == false) +{ + AbortIf(selfNanoWorkshopSetting == false && NumberOfPlayers(Team.Team1) > 1); + Wait(0.1, WaitBehavior.IgnoreCondition); + if (IsUsingUltimate(EventPlayer()) == false) + { + CreateDummyBot(Hero.Ana, TeamOf(EventPlayer()), -1, PositionOf(EventPlayer()) + Backward(), EyePosition(EventPlayer())); + anaEntityID = LastCreatedEntity(); + Wait(0.1, WaitBehavior.IgnoreCondition); + SetUltimateCharge(anaEntityID, 100); + StartFacing(anaEntityID, DirectionTowards(EyePosition(anaEntityID), PositionOf(EventPlayer()) + Up()), 1000, Relative.ToWorld, FacingRev.DirectionAndTurnRate); + SetInvisible(anaEntityID, InvisibleTo.All); + SetStatus(anaEntityID, null, Status.PhasedOut, 9999); + Wait(0.15, WaitBehavior.IgnoreCondition); + PressButton(anaEntityID, Button.Ultimate); + SetUltimateCharge(EventPlayer(), 0); + Wait(0.15, WaitBehavior.IgnoreCondition); + Teleport(anaEntityID, PositionOf(FirstOf(SpawnPoints(TeamOf(EventPlayer()))))); + Wait(10, WaitBehavior.IgnoreCondition); + DestroyDummyBot(TeamOf(EventPlayer()), SlotOf(anaEntityID)); + } +} + +disabled rule: "Map Editor Walls" +{ +} + +rule: "Initial Global" +{ + allPositions = []; + allDirections = []; + firstPosition = []; + secondPosition = []; + firstPoint = []; + secondPoint = []; + second = []; + z = []; + wallId = []; + beamType = []; +} + +rule: "Initial Player" +Event.OngoingPlayer +Team.Team1 +{ + filterPosition = 0; + lastSavedPosition = 0; + closestBodyPosition = 0; + fullBodyPosition = 0; + previousPositionIntersection = 0; + activeWall = []; + closestWall = []; +} + +rule: "Collision Logic" +Event.OngoingPlayer +Team.Team1 +if (HasSpawned(EventPlayer()) == true) +{ + lastSavedPosition = (EyePosition(EventPlayer()) + PositionOf(EventPlayer())) / 2; + Wait(0.1, WaitBehavior.IgnoreCondition); + closestWall = FilteredArray(allPositions, DistanceBetween(allPositions[CurrentArrayIndex()], EventPlayer()) <= DistanceBetween(allPositions[CurrentArrayIndex()], firstPosition[CurrentArrayIndex()]) || activeWall[CurrentArrayIndex()] == 1 || DotProduct(DirectionTowards(ArrayElement(), lastSavedPosition), allDirections[CurrentArrayIndex()]) > 0 != DotProduct(DirectionTowards(ArrayElement(), EventPlayer()), allDirections[CurrentArrayIndex()]) > 0); + for (x = 0; CountOf(closestWall); 1) + { + z = IndexOfArrayValue(allPositions, closestWall[x]); + if (wallId[z] == 1 || wallId[z] == 3 || wallId[z] == 5) + { + if (YOf(firstPosition[z]) >= YOf(PositionOf(EventPlayer())) && YOf(firstPosition[z]) <= YOf(EyePosition(EventPlayer()) + Vector([], 0.2, []))) + { + closestBodyPosition = firstPosition[z]; + } + else if (YOf(secondPosition[z]) >= YOf(PositionOf(EventPlayer())) && YOf(secondPosition[z]) <= YOf(EyePosition(EventPlayer()) + Vector([], 0.2, []))) + { + closestBodyPosition = secondPosition[z]; + } + else + { + closestBodyPosition = PositionOf(EventPlayer()); + } + fullBodyPosition = Vector(XOf(EyePosition(EventPlayer())), YOf(closestBodyPosition), ZOf(EyePosition(EventPlayer()))); + filterPosition = fullBodyPosition + allDirections[z] * DotProduct(allPositions[z] - fullBodyPosition, allDirections[z]) / DotProduct(allDirections[z], allDirections[z]); + if (wallId[z] == 1 || wallId[z] == 3) + { + if (DotProduct(DirectionTowards(allPositions[z], lastSavedPosition), allDirections[z]) > 0 != DotProduct(DirectionTowards(allPositions[z], fullBodyPosition), allDirections[z]) > 0) + { + intersectionLength = DotProduct(allPositions[z] - fullBodyPosition, allDirections[z]) / DotProduct(DirectionTowards(lastSavedPosition, fullBodyPosition), allDirections[z]); + previousPositionIntersection = fullBodyPosition + DirectionTowards(lastSavedPosition, fullBodyPosition) * Vector(1, [], 1) * intersectionLength; + if (DotProduct(DirectionTowards(firstPosition[z], Vector(XOf(secondPosition[z]), YOf(firstPosition[z]), ZOf(secondPosition[z]))), DirectionTowards(firstPosition[z], previousPositionIntersection)) >= 0 && DotProduct(DirectionTowards(firstPosition[z], Vector(XOf(firstPosition[z]), YOf(secondPosition[z]), ZOf(firstPosition[z]))), DirectionTowards(firstPosition[z], previousPositionIntersection)) >= 0 && DotProduct(DirectionTowards(secondPosition[z], Vector(XOf(secondPosition[z]), YOf(firstPosition[z]), ZOf(secondPosition[z]))), DirectionTowards(secondPosition[z], previousPositionIntersection)) >= 0 && DotProduct(DirectionTowards(secondPosition[z], Vector(XOf(firstPosition[z]), YOf(secondPosition[z]), ZOf(firstPosition[z]))), DirectionTowards(secondPosition[z], previousPositionIntersection)) >= 0) + { + CancelPrimaryAction(EventPlayer()); + Teleport(EventPlayer(), previousPositionIntersection + DirectionTowards(previousPositionIntersection, lastSavedPosition) * Vector(1, [], 1) * 2); + } + } + } + thickness = 0; + if (wallId[z] == 5) + { + thickness = 4; + } + else + { + thickness = 1; + } + if (DistanceBetween(fullBodyPosition, filterPosition) <= thickness && DotProduct(DirectionTowards(firstPosition[z], Vector(XOf(secondPosition[z]), YOf(firstPosition[z]), ZOf(secondPosition[z]))), DirectionTowards(firstPosition[z], filterPosition)) >= 0 && DotProduct(DirectionTowards(firstPosition[z], Vector(XOf(firstPosition[z]), YOf(secondPosition[z]), ZOf(firstPosition[z]))), DirectionTowards(firstPosition[z], filterPosition)) >= 0 && DotProduct(DirectionTowards(secondPosition[z], Vector(XOf(secondPosition[z]), YOf(firstPosition[z]), ZOf(secondPosition[z]))), DirectionTowards(secondPosition[z], filterPosition)) >= 0 && DotProduct(DirectionTowards(secondPosition[z], Vector(XOf(firstPosition[z]), YOf(secondPosition[z]), ZOf(firstPosition[z]))), DirectionTowards(secondPosition[z], filterPosition)) >= 0) + { + if (!isGrounded) + { + SetGravity(EventPlayer(), 100); + } + if (activeWall[z] == false) + { + activeWall[z] = 1; + if ((wallId[z] == 1 || wallId[z] == 3) && isGrounded == false) + { + SetGravity(EventPlayer(), 100); + } + else if (wallId[z] == 5) + { + DisableMovementCollisionWithEnvironment(EventPlayer(), false); + } + } + if (wallId[z] == 1) + { + ApplyImpulse(EventPlayer(), DirectionTowards(filterPosition, fullBodyPosition) * Vector(1, [], 1), 0.001, Relative.ToWorld, ContraryMotion.Cancel); + SetMoveSpeed(EventPlayer(), 100 - DotProduct(DirectionTowards(EyePosition(EventPlayer()), EyePosition(EventPlayer()) + WorldVectorOf(ThrottleOf(EventPlayer()), EventPlayer(), LocalVector.Rotation)), DirectionTowards(filterPosition, fullBodyPosition) * -1) * 100); + } + else if (wallId[z] == 3) + { + ApplyImpulse(EventPlayer(), DirectionTowards(filterPosition, fullBodyPosition), SpeedOf(EventPlayer()), Relative.ToWorld, ContraryMotion.Cancel); + } + } + else + { + activeWall[z] = 0; + SetMoveSpeed(EventPlayer(), 100); + } + } + } + Loop(); +} + +rule: "Reset" +Event.OngoingPlayer +Team.Team1 +if (CountOf(FilteredArray(activeWall, ArrayElement() != 0)) == 0) +{ + EnableMovementCollisionWithEnvironment(EventPlayer()); +} + +rule: "Wall Data" +{ + allPositions = [Vector(155.968, 12.47, -30.507), Vector(155.962, 12.472, -62.5), Vector(81.153, 6.453, -103.851), Vector(69.148, 6.474, -104.548)]; + allDirections = [Vector(-1, 0, -0.002), Vector(1, 0, -0.001), Vector(0, 0, 1), Vector(0.001, 0, 1)]; + firstPosition = [Vector(155.971, 11.047, -31.771), Vector(155.964, 11.05, -61.229), Vector(79.761, 5.03, -103.852), Vector(67.738, 5.022, -104.547)]; + secondPosition = [Vector(155.965, 13.894, -29.242), Vector(155.96, 13.894, -63.771), Vector(82.544, 7.876, -103.851), Vector(70.558, 7.925, -104.55)]; + firstPoint = [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)]; + secondPoint = [Vector(155.965, 11.047, -29.242), Vector(155.96, 11.05, -63.771), Vector(82.544, 5.03, -103.851), Vector(70.558, 5.022, -104.55)]; + z = 3; + beamType = [1, 1, 1, 1]; + showWalls = true; + wallId = [5, 5, 5, 5]; +} + +disabled rule: "NEW SHOP" +{ +} + +rule: "Setting Shop Position" +{ + shopCamPosition = 900 * Up(); + shopPositionAngle[1] = DirectionFromAngles(HorizontalAngleFromDirection(Forward()), VerticalAngleFromDirection(Forward()) - 90); + shopPositionAngle[0] = CrossProduct(shopPositionAngle[1], Forward()); + shopBasePosition = shopCamPosition - 9 * shopPositionAngle[1] + 142 * Forward(); +} + +rule: "Create Shop Buttons" +{ + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃", shopBasePosition - 41 * shopPositionAngle[1] + 90 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleTo, Color.White, Spectators.DefaultVisibility); + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), "┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃\n┃", shopBasePosition - 41 * shopPositionAngle[1] - 90 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleTo, Color.White, Spectators.DefaultVisibility); + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), "Refund", shopBasePosition + 45 * shopPositionAngle[1] + 67.5 * shopPositionAngle[0], 3, Clipping.DoNotClip, InworldTextRev.VisibleTo, Color.Green, Spectators.DefaultVisibility); + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), <"[<0>] Leave", InputBindingString(Button.Reload)>, shopBasePosition + 45 * shopPositionAngle[1] - 67.5 * shopPositionAngle[0], 3, Clipping.DoNotClip, InworldTextRev.VisibleToAndString, Color.Green, Spectators.DefaultVisibility); + CreateInWorldText(LocalPlayer().isInMenu[0] ? LocalPlayer() : [], <"<0>$\n", LocalPlayer().money[0]>, shopBasePosition + 36.5 * shopPositionAngle[1], 3, Clipping.DoNotClip, InworldTextRev.VisibleToAndString, Color.White, Spectators.DefaultVisibility); + CreateInWorldText(LocalPlayer().isInMenu[0] ? LocalPlayer() : [], "▲", UpdateEveryFrame(shopBasePosition - (4 + VerticalFacingAngleOf(LocalPlayer())) * shopPositionAngle[1] + HorizontalFacingAngleOf(LocalPlayer()) * shopPositionAngle[0]), 4, Clipping.DoNotClip, InworldTextRev.VisibleToPositionAndColor, CustomColor(245 + 10 * SineFromRadians(4 * TotalTimeElapsed()), 205 + 50 * SineFromRadians(4 * TotalTimeElapsed()), 200 * SineFromRadians(4 * TotalTimeElapsed()), 255), Spectators.DefaultVisibility); + # Headhunter + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), LocalPlayer().abilities[1] ? "Headhunter II\n  800$" : "Headhunter I\n  800$", shopBasePosition + 20 * shopPositionAngle[1] + 67.5 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToStringAndColor, LocalPlayer().abilities[1] < 2 ? Color.Green : Color.Gray, Spectators.DefaultVisibility); + # Ambush + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), LocalPlayer().abilities[2] ? "Ambush II\n 800$" : "Ambush I\n 800$", shopBasePosition - 2.5 * shopPositionAngle[1] + 67.5 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToStringAndColor, LocalPlayer().abilities[2] < 2 ? Color.Green : Color.Gray, Spectators.DefaultVisibility); + # Quick Fix + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), LocalPlayer().abilities[3] ? "Quick Fix II\n  700$" : "Quick Fix I\n  700$", shopBasePosition - 25 * shopPositionAngle[1] + 67.5 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToStringAndColor, LocalPlayer().abilities[3] < 2 ? Color.Green : Color.Gray, Spectators.DefaultVisibility); + # Heavyweight + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), LocalPlayer().abilities[4] ? "Heavyweight II\n  1000$" : "Heavyweight I\n  1000$", shopBasePosition - 47.5 * shopPositionAngle[1] + 67.5 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToStringAndColor, LocalPlayer().abilities[4] < 2 ? Color.Green : Color.Gray, Spectators.DefaultVisibility); + # Charged + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), LocalPlayer().abilities[5] ? "Charged II\n  700$" : "Charged I\n  700$", shopBasePosition + 20 * shopPositionAngle[1] + 22.5 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToStringAndColor, LocalPlayer().abilities[5] < 2 ? Color.Green : Color.Gray, Spectators.DefaultVisibility); + # Haste + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), LocalPlayer().abilities[6] ? "Haste II\n 700$" : "Haste I\n 700$", shopBasePosition - 2.5 * shopPositionAngle[1] + 22.5 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToStringAndColor, LocalPlayer().abilities[6] < 2 ? Color.Green : Color.Gray, Spectators.DefaultVisibility); + # Heavy Impact + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), LocalPlayer().abilities[7] ? "Heavy Impact II\n  1000$" : "Heavy Impact I\n  1000$", shopBasePosition - 25 * shopPositionAngle[1] + 22.5 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToStringAndColor, LocalPlayer().abilities[7] < 2 ? Color.Green : Color.Gray, Spectators.DefaultVisibility); + # Hero Talent 1 + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), "Hero Talent 1\n  1200$", shopBasePosition - 47.5 * shopPositionAngle[1] + 22.5 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToStringAndColor, LocalPlayer().abilities[8] < 1 ? Color.Green : Color.Gray, Spectators.DefaultVisibility); + # Second Wind + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), LocalPlayer().abilities[9] ? "Second Wind II\n   900$" : "Second Wind I\n   900$", shopBasePosition + 20 * shopPositionAngle[1] - 22.5 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToStringAndColor, LocalPlayer().abilities[9] < 2 ? Color.Green : Color.Gray, Spectators.DefaultVisibility); + # Binding Heal + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), LocalPlayer().abilities[10] ? "Binding Heal II\n   700$" : "Binding Heal I\n   700$", shopBasePosition - 2.5 * shopPositionAngle[1] - 22.5 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToStringAndColor, LocalPlayer().abilities[10] < 2 ? Color.Green : Color.Gray, Spectators.DefaultVisibility); + # Resilience + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), LocalPlayer().abilities[11] ? "Resilience II\n  800$" : "Resilience I\n  800$", shopBasePosition - 25 * shopPositionAngle[1] - 22.5 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToStringAndColor, LocalPlayer().abilities[11] < 2 ? Color.Green : Color.Gray, Spectators.DefaultVisibility); + # Hero Talent 2 + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), "Hero Talent 2\n  1200$", shopBasePosition - 47.5 * shopPositionAngle[1] - 22.5 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToStringAndColor, LocalPlayer().abilities[12] < 1 ? Color.Green : Color.Gray, Spectators.DefaultVisibility); + # PlusDamage + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), "+5% Damage\n  400$", shopBasePosition + 20 * shopPositionAngle[1] - 67.5 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToStringAndColor, Color.Green, Spectators.DefaultVisibility); + # PlusHealth + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), "+5% Health\n 400$", shopBasePosition - 2.5 * shopPositionAngle[1] - 67.5 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToStringAndColor, Color.Green, Spectators.DefaultVisibility); + # PlusHealing + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), "+5% Healing\n  400$", shopBasePosition - 25 * shopPositionAngle[1] - 67.5 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToAndString, Color.Green, Spectators.DefaultVisibility); + # PlusHealing + CreateInWorldText(FilteredArray(AllPlayers(Team.Team1), ArrayElement().isInMenu[0]), <"+<0> Auto-Repair\n    400$", upgradeGateMaxHealthValue >= upgradeGateMaxHealthMaxValue[2] ? 10 : 5>, shopBasePosition - 47.5 * shopPositionAngle[1] - 67.5 * shopPositionAngle[0], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToStringAndColor, automaticRepair < 5 ? Color.Green : Color.Gray, Spectators.DefaultVisibility); + # Use Update Every Frame to avoid showing the String when the cursor is out of bounds, resulting in 0\r\n ROW 0 + CreateInWorldText(UpdateEveryFrame(LocalPlayer().isInMenu[0] && AbsoluteValue(HorizontalFacingAngleOf(LocalPlayer())) < 90 && AbsoluteValue(VerticalFacingAngleOf(LocalPlayer()) + 11.25) < 47.5 ? LocalPlayer() : []), UpdateEveryFrame(VerticalFacingAngleOf(LocalPlayer()) < -33.75 ? ["Leave Buy Menu\n", "", "", "Refund your money\n"][RoundToInteger((HorizontalFacingAngleOf(LocalPlayer()) + 90) / 45, Rounding.Down)] : ""), shopBasePosition - 75 * shopPositionAngle[1], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToAndString, Color.White, Spectators.DefaultVisibility); + # ROW 1 + CreateInWorldText(UpdateEveryFrame(LocalPlayer().isInMenu[0] && AbsoluteValue(HorizontalFacingAngleOf(LocalPlayer())) < 90 && AbsoluteValue(VerticalFacingAngleOf(LocalPlayer()) + 11.25) < 22.5 ? LocalPlayer() : []), UpdateEveryFrame(VerticalFacingAngleOf(LocalPlayer()) < -11.25 ? ["Increase your damage by 5%\n", LocalPlayer().abilities[9] ? "Second Wind II: 60% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds" : "Second Wind I: 30% chance to revive yourself after going down\n   This cannot occur more than once every 30 seconds", LocalPlayer().abilities[5] ? "Charged II: Ultimates cost 40% less\n" : "Charged I: Ultimates cost 20% less\n", LocalPlayer().abilities[1] ? "Headhunter II: Critical hits deal 60% more damage\n" : "Headhunter I: Critical hits deal 30% more damage\n"][RoundToInteger((HorizontalFacingAngleOf(LocalPlayer()) + 90) / 45, Rounding.Down)] : ""), shopBasePosition - 75 * shopPositionAngle[1], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToAndString, Color.White, Spectators.DefaultVisibility); + # ROW 2 + CreateInWorldText(UpdateEveryFrame(LocalPlayer().isInMenu[0] && AbsoluteValue(HorizontalFacingAngleOf(LocalPlayer())) < 90 && AbsoluteValue(VerticalFacingAngleOf(LocalPlayer()) - 36.25) < 47.5 ? LocalPlayer() : []), UpdateEveryFrame(VerticalFacingAngleOf(LocalPlayer()) < 11.25 ? ["Increase your health by 5%\n", LocalPlayer().abilities[10] ? "Binding Heal II: Heal yourself for 50% the amount when healing allies\n" : "Binding Heal I: Heal yourself for 25% the amount when healing allies\n", LocalPlayer().abilities[6] ? "Haste II: Ability cooldown is reduced by 50%\nDoes not affect abilities with multiple charges" : "Haste I: Ability cooldown is reduced by 25%\nDoes not affect abilities with multiple charges", LocalPlayer().abilities[2] ? "Ambush II: Deal 60% more damage when attacking enemies from behind or above\n" : "Ambush I: Deal 30% more damage when attacking enemies from behind or above\n"][RoundToInteger((HorizontalFacingAngleOf(LocalPlayer()) + 90) / 45, Rounding.Down)] : ""), shopBasePosition - 75 * shopPositionAngle[1], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToAndString, Color.White, Spectators.DefaultVisibility); + # ROW 3 + CreateInWorldText(UpdateEveryFrame(LocalPlayer().isInMenu[0] && AbsoluteValue(HorizontalFacingAngleOf(LocalPlayer())) < 90 && AbsoluteValue(VerticalFacingAngleOf(LocalPlayer()) - 83.75) < 72.5 ? LocalPlayer() : []), UpdateEveryFrame(VerticalFacingAngleOf(LocalPlayer()) < 33.75 ? ["Increase your healing by 5%\n", LocalPlayer().abilities[11] ? "Resilience II: Take 30% less damage while below 60% health\n" : "Resilience I: Take 30% less damage while below 30% health\n", LocalPlayer().abilities[7] ? "Heavy Impact II: Every hit has a chance to stun the enemy for 2 seconds\n" : "Heavy Impact I: Every hit has a chance to stun the enemy for 1 second\n", LocalPlayer().abilities[3] ? "Quick Fix II: Eliminations restore 100 HP and shortly increase speed by 40%\n" : "Quick Fix I: Eliminations restore 50 HP and shortly increase speed by 20%\n"][RoundToInteger((HorizontalFacingAngleOf(LocalPlayer()) + 90) / 45, Rounding.Down)] : ""), shopBasePosition - 75 * shopPositionAngle[1], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToAndString, Color.White, Spectators.DefaultVisibility); + # ROW 4 + CreateInWorldText(UpdateEveryFrame(LocalPlayer().isInMenu[0] && AbsoluteValue(HorizontalFacingAngleOf(LocalPlayer())) < 90 && AbsoluteValue(VerticalFacingAngleOf(LocalPlayer()) - 133) < 99.25 ? LocalPlayer() : []), UpdateEveryFrame(VerticalFacingAngleOf(LocalPlayer()) < 56.25 ? [<"Increase your auto-repair by <0>/5s\n", upgradeGateMaxHealthValue >= upgradeGateMaxHealthMaxValue[2] ? 10 : 5>, <"<0>", LocalPlayer().heroTalentText[2][1]>, <"<0>", LocalPlayer().heroTalentText[1][1]>, LocalPlayer().abilities[4] ? "Heavyweight II: Your knock back attacks deal 50% more damage and knock back\n            You receive 33% less knock back" : "Heavyweight I: Your knock back attacks deal 25% more damage and knock back\n            You receive 20% less knock back"][RoundToInteger((HorizontalFacingAngleOf(LocalPlayer()) + 90) / 45, Rounding.Down)] : ""), shopBasePosition - 75 * shopPositionAngle[1], 2.5, Clipping.DoNotClip, InworldTextRev.VisibleToAndString, Color.White, Spectators.DefaultVisibility); +} + +rule: "Toggle Shop" +Event.OngoingPlayer +Team.Team1 +if (!IsDummyBot(EventPlayer()) == true) +if (IsButtonHeld(EventPlayer(), Button.Reload) == true) +if (!IsCommunicatingAnyEmote(EventPlayer()) == true) +{ + if (isInMenu[0] == false) + { + WaitUntil(!IsButtonHeld(EventPlayer(), Button.Reload), 0.5); + if (!IsButtonHeld(EventPlayer(), Button.Reload)) + { + Abort(); + } + } + isInMenu[0] = !isInMenu[0]; +} + +rule: "Open Shop" +Event.OngoingPlayer +Team.Team1 +if (isInMenu[0] == true) +{ + playerFacing = FacingDirectionOf(EventPlayer()); + StartCamera(EventPlayer(), shopCamPosition, shopCamPosition + Forward(), 0); + DisableHeroHud(EventPlayer()); + DisablePlayer(); + SetAimSpeed(EventPlayer(), 200); +} + +rule: "Close Shop" +Event.OngoingPlayer +Team.Team1 +if (isInMenu[0] == false) +{ + StopCamera(EventPlayer()); + EnableHeroHud(EventPlayer()); + EnablePlayer(); + SetAimSpeed(EventPlayer(), 100); + SetFacing(EventPlayer(), playerFacing, Relative.ToWorld); +} + +void DisablePlayer() "Subroutine: Disable Player" +{ + ForceThrottle(EventPlayer(), 0, 0, 0, 0, 0, 0); + SetPrimaryFireEnabled(EventPlayer(), false); + SetSecondaryFireEnabled(EventPlayer(), false); + SetAbility1Enabled(EventPlayer(), false); + SetAbility2Enabled(EventPlayer(), false); + SetMeleeEnabled(EventPlayer(), false); + SetJumpEnabled(EventPlayer(), false); + SetCrouchEnabled(EventPlayer(), false); + DisallowButton(EventPlayer(), Button.Ultimate); +} + +void EnablePlayer() "Subroutine: Enable Player" +{ + StopForcingThrottle(EventPlayer()); + SetPrimaryFireEnabled(EventPlayer(), true); + SetSecondaryFireEnabled(EventPlayer(), true); + SetAbility1Enabled(EventPlayer(), true); + SetAbility2Enabled(EventPlayer(), true); + SetMeleeEnabled(EventPlayer(), true); + SetJumpEnabled(EventPlayer(), true); + SetCrouchEnabled(EventPlayer(), true); + AllowButton(EventPlayer(), Button.Ultimate); +} + +rule: "Buy Ability" +Event.OngoingPlayer +Team.Team1 +if (isInMenu[0] == true) +if (IsButtonHeld(EventPlayer(), Button.PrimaryFire) == true) +if ((AbsoluteValue(HorizontalFacingAngleOf(EventPlayer())) < 90 && AbsoluteValue(VerticalFacingAngleOf(EventPlayer())) + 11.25 < 67) == true) +{ + # ROW 0 + if (VerticalFacingAngleOf(EventPlayer()) < -33.75) + { + # LEAVE SHOP + if (HorizontalFacingAngleOf(EventPlayer()) + 99.75 < 55) + { + isInMenu[0] = !isInMenu[0]; + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 0 > 45) + { + if (money[1] != 0) + { + Refund(); + } + else + { + SmallMessage(LocalPlayer(), "You don't have anything to refund!"); + } + } + } + else if (VerticalFacingAngleOf(EventPlayer()) < -11.25) + { + # +5% DAMAGE + if (HorizontalFacingAngleOf(EventPlayer()) + 99.75 < 55) + { + if (money[0] >= 400) + { + money[0] -= 400; + money[1] += 400; + abilities[13] += 1; + UpdatePlayerStats(); + } + else + { + SmallMessage(EventPlayer(), "Not enough money!"); + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 22.5 < 22.5) + { + if (abilities[9] != 2) + { + if (money[0] >= 900) + { + money[0] -= 900; + money[1] += 900; + abilities[9] += 1; + } + else + { + SmallMessage(EventPlayer(), "Not enough money!"); + } + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 11.25 < 56) + { + if (abilities[5] != 2) + { + if (money[0] >= 700) + { + money[0] -= 700; + money[1] += 700; + abilities[5] += 1; + } + else + { + SmallMessage(EventPlayer(), "Not enough money!"); + } + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 0 > 45) + { + if (abilities[1] != 2) + { + if (money[0] >= 800) + { + money[0] -= 800; + money[1] += 800; + abilities[1] += 1; + } + else + { + SmallMessage(EventPlayer(), "Not enough money!"); + } + } + } + } + else if (VerticalFacingAngleOf(EventPlayer()) < 11.25) + { + # +5% HEALTH + if (HorizontalFacingAngleOf(EventPlayer()) + 99.75 < 55) + { + if (money[0] >= 400) + { + money[0] -= 400; + money[1] += 400; + abilities[14] += 1; + UpdatePlayerStats(); + } + else + { + SmallMessage(EventPlayer(), "Not enough money!"); + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 22.5 < 22.5) + { + if (abilities[10] != 2) + { + if (money[0] >= 700) + { + money[0] -= 700; + money[1] += 700; + abilities[10] += 1; + } + else + { + SmallMessage(EventPlayer(), "Not enough money!"); + } + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 11.25 < 56) + { + if (abilities[6] != 2) + { + if (money[0] >= 700) + { + money[0] -= 700; + money[1] += 700; + abilities[6] += 1; + } + else + { + SmallMessage(EventPlayer(), "Not enough money!"); + } + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 0 > 45) + { + if (abilities[2] != 2) + { + if (money[0] >= 800) + { + money[0] -= 800; + money[1] += 800; + abilities[2] += 1; + } + else + { + SmallMessage(EventPlayer(), "Not enough money!"); + } + } + } + } + else if (VerticalFacingAngleOf(EventPlayer()) < 33.75) + { + # +5% HEALING + if (HorizontalFacingAngleOf(EventPlayer()) + 99.75 < 55) + { + if (money[0] >= 400) + { + money[0] -= 400; + money[1] += 400; + abilities[15] += 1; + UpdatePlayerStats(); + } + else + { + SmallMessage(EventPlayer(), "Not enough money!"); + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 22.5 < 22.5) + { + if (abilities[11] != 2) + { + if (money[0] >= 800) + { + money[0] -= 800; + money[1] += 800; + abilities[11] += 1; + } + else + { + SmallMessage(EventPlayer(), "Not enough money!"); + } + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 11.25 < 56) + { + if (abilities[7] != 2) + { + if (money[0] >= 1000) + { + money[0] -= 1000; + money[1] += 1000; + abilities[7] += 1; + } + else + { + SmallMessage(EventPlayer(), "Not enough money!"); + } + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 0 > 45) + { + if (abilities[3] != 2) + { + if (money[0] >= 700) + { + money[0] -= 700; + money[1] += 700; + abilities[3] += 1; + } + else + { + SmallMessage(EventPlayer(), "Not enough money!"); + } + } + } + } + else if (VerticalFacingAngleOf(EventPlayer()) < 56.25) + { + # +5 AUTO-REPAIR + if (HorizontalFacingAngleOf(EventPlayer()) + 99.75 < 55) + { + if (automaticRepair != 5) + { + if (money[0] >= 400) + { + money[0] -= 400; + money[1] += 400; + automaticRepair += 1; + abilities[16] += 1; + } + else + { + SmallMessage(EventPlayer(), "Not enough money!"); + } + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 22.5 < 22.5) + { + if (abilities[12] != 1) + { + if (money[0] >= 1200) + { + money[0] -= 1200; + money[1] += 1200; + abilities[12] += 1; + } + else + { + SmallMessage(EventPlayer(), "Not enough money!"); + } + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 11.25 < 56) + { + if (abilities[8] != 1) + { + if (money[0] >= 1200) + { + money[0] -= 1200; + money[1] += 1200; + abilities[8] += 1; + } + else + { + SmallMessage(EventPlayer(), "Not enough money!"); + } + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 0 > 45) + { + if (abilities[4] != 2) + { + if (money[0] >= 1000) + { + money[0] -= 1000; + money[1] += 1000; + abilities[4] += 1; + } + else + { + SmallMessage(EventPlayer(), "Not enough money!"); + } + } + } + } +} + +rule: "Refund Single Ability" +Event.OngoingPlayer +Team.Team1 +if (isInMenu[0] == true) +if (IsButtonHeld(EventPlayer(), Button.SecondaryFire) == true) +if ((AbsoluteValue(HorizontalFacingAngleOf(EventPlayer())) < 90 && AbsoluteValue(VerticalFacingAngleOf(EventPlayer())) + 11.25 < 67) == true) +{ + # ROW 0 + if (VerticalFacingAngleOf(EventPlayer()) < -33.75) + { + # LEAVE SHOP + if (HorizontalFacingAngleOf(EventPlayer()) + 99.75 < 55) + { + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 0 > 45) + { + } + } + else if (VerticalFacingAngleOf(EventPlayer()) < -11.25) + { + # +5% DAMAGE + if (HorizontalFacingAngleOf(EventPlayer()) + 99.75 < 55) + { + if (abilities[13] != 0) + { + money[0] += 400; + money[1] -= 400; + abilities[13] -= 1; + UpdatePlayerStats(); + } + else + { + SmallMessage(EventPlayer(), "You don't have that ability!"); + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 22.5 < 22.5) + { + if (abilities[9] != 0) + { + money[0] += 900; + money[1] -= 900; + abilities[9] -= 1; + } + else + { + SmallMessage(EventPlayer(), "You don't have that ability!"); + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 11.25 < 56) + { + if (abilities[5] != 0) + { + money[0] += 700; + money[1] -= 700; + abilities[5] -= 1; + } + else + { + SmallMessage(EventPlayer(), "You don't have that ability!"); + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 0 > 45) + { + if (abilities[1] != 0) + { + money[0] += 800; + money[1] -= 800; + abilities[1] -= 1; + } + else + { + SmallMessage(EventPlayer(), "You don't have that ability!"); + } + } + } + else if (VerticalFacingAngleOf(EventPlayer()) < 11.25) + { + # +5% HEALTH + if (HorizontalFacingAngleOf(EventPlayer()) + 99.75 < 55) + { + if (abilities[14] != 0) + { + money[0] += 400; + money[1] -= 400; + abilities[14] -= 1; + UpdatePlayerStats(); + } + else + { + SmallMessage(EventPlayer(), "You don't have that ability!"); + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 22.5 < 22.5) + { + if (abilities[10] != 0) + { + money[0] += 700; + money[1] -= 700; + abilities[10] -= 1; + } + else + { + SmallMessage(EventPlayer(), "You don't have that ability!"); + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 11.25 < 56) + { + if (abilities[6] != 0) + { + money[0] += 700; + money[1] -= 700; + abilities[6] -= 1; + } + else + { + SmallMessage(EventPlayer(), "You don't have that ability!"); + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 0 > 45) + { + if (abilities[2] != 0) + { + money[0] += 800; + money[1] -= 800; + abilities[2] -= 1; + } + else + { + SmallMessage(EventPlayer(), "You don't have that ability!"); + } + } + } + else if (VerticalFacingAngleOf(EventPlayer()) < 33.75) + { + # +5% HEALING + if (HorizontalFacingAngleOf(EventPlayer()) + 99.75 < 55) + { + if (abilities[15] != 0) + { + money[0] += 400; + money[1] -= 400; + abilities[15] -= 1; + UpdatePlayerStats(); + } + else + { + SmallMessage(EventPlayer(), "You don't have that ability!"); + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 22.5 < 22.5) + { + if (abilities[11] != 0) + { + money[0] += 800; + money[1] -= 800; + abilities[11] -= 1; + } + else + { + SmallMessage(EventPlayer(), "You don't have that ability!"); + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 11.25 < 56) + { + if (abilities[7] != 0) + { + money[0] += 1000; + money[1] -= 1000; + abilities[7] -= 1; + } + else + { + SmallMessage(EventPlayer(), "You don't have that ability!"); + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 0 > 45) + { + if (abilities[3] != 0) + { + money[0] += 700; + money[1] -= 700; + abilities[3] -= 1; + } + else + { + SmallMessage(EventPlayer(), "You don't have that ability!"); + } + } + } + else if (VerticalFacingAngleOf(EventPlayer()) < 56.25) + { + # +5 AUTO-REPAIR + if (HorizontalFacingAngleOf(EventPlayer()) + 99.75 < 55) + { + if (abilities[16] != 0) + { + money[0] += 400; + money[1] -= 400; + automaticRepair -= 1; + abilities[16] -= 1; + } + else + { + SmallMessage(EventPlayer(), "You don't have that ability!"); + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 22.5 < 22.5) + { + if (abilities[12] != 0) + { + money[0] += 1200; + money[1] -= 1200; + abilities[12] -= 1; + } + else + { + SmallMessage(EventPlayer(), "You don't have that ability!"); + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 11.25 < 56) + { + if (abilities[8] != 0) + { + money[0] += 1200; + money[1] -= 1200; + abilities[8] -= 1; + } + else + { + SmallMessage(EventPlayer(), "You don't have that ability!"); + } + } + else if (HorizontalFacingAngleOf(EventPlayer()) + 0 > 45) + { + if (abilities[4] != 0) + { + money[0] += 1000; + money[1] -= 1000; + abilities[4] -= 1; + } + else + { + SmallMessage(EventPlayer(), "You don't have that ability!"); + } + } + } +} + +rule: "Create Player HUD" +Event.OnPlayerJoin +Team.Team1 +{ + CreateHudText(AllPlayers(Team.Team1), <"<0>", HeroIconString(HeroOf(EventPlayer()))>, <"<0><1>", EventPlayer(), isInMenu[0] ? "(In Shop)" : "">, <"<0><1>", IsAlive(EventPlayer()) ? <"<0> HP", RoundToInteger(Health(EventPlayer()), Rounding.Up)> : "Dead", <", <0>$", money>>, Location.Left, LocalPlayer() == EventPlayer() ? -1 : SlotOf(EventPlayer()), IsDead(EventPlayer()) ? Color.Red : Health(EventPlayer()) > MaxHealth(EventPlayer()) * 0.5 ? Color.Green : Color.Orange, IsDead(EventPlayer()) ? Color.Red : Health(EventPlayer()) > MaxHealth(EventPlayer()) * 0.5 ? Color.Green : Color.Orange, IsDead(EventPlayer()) ? Color.Red : Health(EventPlayer()) > MaxHealth(EventPlayer()) * 0.5 ? Color.Green : Color.Orange, HudTextRev.VisibleToSortOrderStringAndColor, Spectators.DefaultVisibility); + CreateHudText(damageBoost[0] != 0 ? EventPlayer() : null, null, <"+<0>% Damage", damageBoost[0]>, null, Location.Left, 913, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(abilities[9] ? EventPlayer() : null, null, <"Second Wind <0>", abilities[9] == 1 ? "I" : "II">, null, Location.Left, 908, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(abilities[5] ? EventPlayer() : null, null, <"Charged <0>", abilities[5] == 1 ? "I" : "II">, null, Location.Left, 905, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(abilities[1] ? EventPlayer() : null, null, <"Headhunter <0>", abilities[1] == 1 ? "I" : "II">, null, Location.Left, 901, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(playerHealth != 0 ? EventPlayer() : null, null, <"+<0>% Health", playerHealth>, null, Location.Left, 914, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(abilities[10] ? EventPlayer() : null, null, <"Binding Heal <0>", abilities[10] == 1 ? "I" : "II">, null, Location.Left, 909, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(abilities[6] ? EventPlayer() : null, null, <"Haste <0>", abilities[6] == 1 ? "I" : "II">, null, Location.Left, 906, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(abilities[2] ? EventPlayer() : null, null, <"Ambush <0>", abilities[2] == 1 ? "I" : "II">, null, Location.Left, 902, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(healBoost[0] != 0 ? EventPlayer() : null, null, <"+<0>% Healing", healBoost[0]>, null, Location.Left, 915, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(speedBoost != 0 ? EventPlayer() : null, null, <"+<0>% Movement Speed", speedBoost>, null, Location.Left, 915, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(abilities[11] ? EventPlayer() : null, null, <"Resilience <0>", abilities[11] == 1 ? "I" : "II">, null, Location.Left, 910, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(abilities[7] ? EventPlayer() : null, null, <"Heavy Impact <0>", abilities[7] == 1 ? "I" : "II">, null, Location.Left, 907, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(abilities[3] ? EventPlayer() : null, null, <"Quick Fix <0>", abilities[3] == 1 ? "I" : "II">, null, Location.Left, 903, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(automaticRepair ? EventPlayer() : null, null, <"<0> total Auto-Repair/5s", automaticRepair * (upgradeGateMaxHealthValue >= upgradeGateMaxHealthMaxValue[2] ? 10 : 5)>, null, Location.Left, 916, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(abilities[12] ? EventPlayer() : null, null, <"<0> <1>", heroTalentText[2][0], heroTalentText[2][1]>, null, Location.Top, 902, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(abilities[12] ? EventPlayer() : null, null, "Hero Talent 2", null, Location.Left, 912, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(abilities[8] ? EventPlayer() : null, null, <"<0> <1>", heroTalentText[1][0], heroTalentText[1][1]>, null, Location.Top, 901, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(abilities[8] ? EventPlayer() : null, null, "Hero Talent 1", null, Location.Left, 911, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(abilities[4] ? EventPlayer() : null, null, <"Heavyweight <0>", abilities[4] == 1 ? "I" : "II">, null, Location.Left, 904, Color.Green, Color.Green, Color.Green, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); +} + +rule: "Boss Rotation" +if (IsGameInProgress() == true) +if (activeBoss == true) +{ + if (bossRotation == 0 || bossRotation == 3) + { + bossRotation = 1; + lastBoss[1] = HeroOf(activeBoss); + } + else if (bossRotation == 1) + { + bossRotation = 2; + lastBoss[2] = HeroOf(activeBoss); + } + else if (bossRotation == 2) + { + bossRotation = 3; + lastBoss[3] = HeroOf(activeBoss); + } +} + +rule: "BOSS HUD" +if (IsGameInProgress() == true) +if (timeMinutes == 10) +{ + CreateHudText(AllPlayers(Team.Team1), null, activeBoss ? <"Boss: <0>, HP: <1>/<2>", HeroOf(activeBoss), Health(activeBoss), MaxHealth(activeBoss)> : "", null, Location.Top, 900, Color.White, Color.Red, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); +} + +rule: "DEBUG - SKIP TIME" +Event.OngoingPlayer +Team.Team1 +if (isDebug == true) +if ((IsButtonHeld(EventPlayer(), Button.PrimaryFire) && IsButtonHeld(EventPlayer(), Button.Crouch)) == true) +{ + timeSeconds = 59; +} + +rule: "DEBUG - SKIP TIME" +Event.OngoingPlayer +Team.Team1 +if (isDebug == true) +if ((IsButtonHeld(EventPlayer(), Button.SecondaryFire) && IsButtonHeld(EventPlayer(), Button.Crouch)) == true) +{ + botEchoRespawnPosition = Vector(130, 23, -44); +} + +rule: "DEBUG COLLECTION - Make Invincible, Show Player Coords" +Event.OngoingPlayer +Team.Team1 +if (isDebug == true) +{ + CreateHudText(LocalPlayer(), null, <"<0>", PositionOf(EventPlayer())>, null, Location.Left, 0, Color.White, Color.Yellow, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + SetStatus(EventPlayer(), null, Status.Invincible, 9999); + SetStatus(EventPlayer(), null, Status.PhasedOut, 9999); +} + +rule: "OPTIONAL ENDING - CREATE EXFIL POINT" +if (IsGameInProgress() == true) +if (challengeCount >= 12) +{ + CreateHudText(AllPlayers(Team.Team1), null, "Exfiltration available! (optional - ends the mode)", null, Location.Top, 50, Color.White, Color.Red, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + globalHUDs[1] = LastTextID(); + CreateInWorldText(AllPlayers(Team.Team1), <"Exfiltration available! Gather here!\n<0>/<1> Players ready to exfiltrate!", CountOf(FilteredArray(AllPlayers(Team.Team1), DistanceBetween(Vector(186, 11, -46.5), ArrayElement()) <= 9)), CountOf(AllPlayers(Team.Team1))>, Vector(186, 15, -46.5), 1.2, Clipping.DoNotClip, InworldTextRev.VisibleToAndString, Color.Green, Spectators.DefaultVisibility); + Wait(3, WaitBehavior.IgnoreCondition); + DestroyHudText(globalHUDs[1]); +} + +rule: "OPTIONAL ENDING - EXFIL PLAYERS" +if (IsGameInProgress() == true) +if (challengeCount == 12) +if (CountOf(FilteredArray(AllPlayers(Team.Team1), DistanceBetween(Vector(186, 11, -46.5), AllPlayers(Team.Team1)) <= 9)) > CountOf(AllPlayers(Team.Team1)) / 2) +{ + BigMessage(AllPlayers(Team.Team1), "GG! YOU SUCCESSFULLY RAN AWAY, WHILE LEAVING THE GATE TO THE ENEMY!"); + DestroyAllDummyBots(); + DisableMovementCollisionWithEnvironment(AllPlayers(Team.Team1), true); + StartAccelerating(AllPlayers(Team.Team1), Up(), 100, 5, Relative.ToWorld, AccelerateRev.DirectionRateAndMaxSpeed); + Wait(5, WaitBehavior.IgnoreCondition); + DeclareTeamVictory(Team.Team1); +} + +rule: "Team 1 (Ability): Second Wind save life" +Event.OnDamageTaken +Team.Team1 +if (abilities[9] == true) +if (secondWindActive == true) +if (Health(EventPlayer()) == 1) +{ + SmallMessage(AllPlayers(Team.All), <"<0> received a second wind!", EventPlayer()>); + PlayEffect(AllPlayers(Team.Team1), PlayEffect.GoodPickupEffect, Color.Green, EventPlayer(), 1); + ClearStatus(EventPlayer(), Status.Unkillable); + SetPlayerHealth(EventPlayer(), MaxHealth(EventPlayer())); + lastSecondWind = 30; + secondWindActive = 0; +} + +rule: "Team 1 (Ability): Second Wind after buying" +Event.OngoingPlayer +Team.Team1 +if (abilities[9] == true) +if (secondWindActive == false) +if (lastSecondWind == 0) +{ + if (RandomInteger(1, 100) > abilities[9] * 30) + { + Wait(30, WaitBehavior.IgnoreCondition); + Loop(); + } + SetStatus(EventPlayer(), null, Status.Unkillable, 9999); + secondWindActive = 1; +} + +rule: "Team 1 (Ability): Second Wind counter" +Event.OngoingPlayer +Team.Team1 +if (IsGameInProgress() == true) +if (lastSecondWind > 0) +{ + Wait(1, WaitBehavior.IgnoreCondition); + lastSecondWind -= 1; + LoopIfConditionIsTrue(); +} + +rule: "Team 1: Change Hero" +Event.OngoingPlayer +Team.Team1 +if (DistanceBetween(Vector(159, 11, -46.5), EventPlayer()) <= 2) +if (IsButtonHeld(EventPlayer(), Button.Interact) == true) +{ + SetAllowedHeroes(EventPlayer(), Hero.Pharah); + SetAllowedHeroes(EventPlayer(), Hero.Ana); + ResetHeroAvailability(EventPlayer()); + Wait(0.5, WaitBehavior.IgnoreCondition); + WaitUntil(HasSpawned(EventPlayer()), 99999); + Teleport(EventPlayer(), Vector(159, 11, -46.5)); +} + +rule: "Team 1: Player Dealt Healing" +Event.OnHealingDealt +Team.Team1 +{ + AbortIf(Healee() != EventPlayer()); + if (abilities[10] == true) + { + SetPlayerHealth(EventPlayer(), Health(EventPlayer()) + abilities[10] * 0.25 * EventHealing()); + } +} + +rule: "Team 1: Player Dealt Damage" +Event.OnDamageDealt +Team.Team1 +{ + if (EventWasCriticalHit() == true) + { + if (upgradeCriticalDamageValue >= upgradeCriticalDamageMaxValue[0]) + { + Damage(Victim(), EventPlayer(), EventDamage() * 0.5); + } + if (abilities[1] == true) + { + Damage(Victim(), EventPlayer(), EventDamage() * abilities[1] * 0.4); + } + } + if (abilities[2] == true && EventAbility() != null && (YOf(PositionOf(EventPlayer())) - YOf(PositionOf(Victim())) >= 3 || AbsoluteValue(HorizontalAngleTowards(Victim(), EventPlayer())) >= 90) == true) + { + Damage(Victim(), EventPlayer(), EventDamage() * abilities[2] * 0.3); + } + if (perk[0] == true && EventAbility() != null && DistanceBetween(EventPlayer(), Victim()) >= 10) + { + Damage(Victim(), EventPlayer(), EventDamage() * 0.5); + } +} + +rule: "▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒【Josbird's Cursor Menu】▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒" +{ +} + +rule: "Global init" +{ + CreateHudText(IsGameInProgress() == false && HostPlayer().isInMenu[1] ? HostPlayer() : null, null, <"Cursor Menu created by Josbird <0> Code: GETVX", AbilityIconString(Hero.Mercy, Button.Ultimate)>, null, Location.Right, -100, Color.White, Color.Turquoise, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(timeSeconds == 0 && timeMinutes == 0 && !HostPlayer().isInMenu[1] ? HostPlayer() : null, null, <"<0>", <"Press <0> - Crouch to open workshop settings", InputBindingString(Button.Crouch)>>, null, Location.Top, 1, Color.White, Color.Yellow, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + CreateHudText(IsGameInProgress() == false && HostPlayer().isInMenu[1] ? HostPlayer() : null, null, <"<0>", <"Press <0> - Primary Fire to increase by X\nPress <1> - Secondary Fire to decrease by X", InputBindingString(Button.PrimaryFire), InputBindingString(Button.SecondaryFire)>>, null, Location.Right, 1, Color.White, Color.Yellow, Color.White, HudTextRev.VisibleToAndString, Spectators.DefaultVisibility); + extendedGlobalCollection[1] = 10; + extendedGlobalCollection[2] = 5; + extendedGlobalCollection[6] = true; + exitButtonProperties = ["exit menu", extendedGlobalCollection[1] / 2 - 0.15, extendedGlobalCollection[2] / 2 - 0.15, 0.35]; +} + +void createMenuButton() "Create a menu button" +{ + if (CountOf(newButton) != 13) + { + LogToInspector(<"[CursorMenu.createMenuButton] Error: incorrect number of arguments (got <0>, expected <1>)", destroyButtonID, 13>); + } + else + { + lastMenuButtonID = CountOf(buttons); + extendedPlayerCollection[2] = 0; + while (extendedPlayerCollection[2] < CountOf(buttons)) + { + if (buttons[extendedPlayerCollection[2]] == null) + { + lastMenuButtonID = extendedPlayerCollection[2]; + extendedPlayerCollection[2] = CountOf(buttons); + } + extendedPlayerCollection[2] += 1; + } + buttons[lastMenuButtonID] = newButton; + } +} + +void destroyMenuButton() "Destroy a menu button" +{ + if (destroyButtonID >= CountOf(buttons) || !buttons[destroyButtonID]) + { + LogToInspector(<"[CursorMenu.destroyMenuButton] Error: tried to destroy an invalid button ID (<0>)", destroyButtonID>); + } + else + { + arrayBuilder = buttons[destroyButtonID]; + arrayBuilder[15] = true; + buttons[destroyButtonID] = arrayBuilder; + } +} + +void modifyMenuButton() "Modify a menu button" +{ + if (CountOf(buttonModification) % 2 == 0 || CountOf(buttonModification) < 3) + { + LogToInspector(<"[CursorMenu.modifyMenuButton] Error: incorrect number of arguments (<0>)", CountOf(FirstOf(buttonModification))>); + } + else if (FirstOf(buttonModification) >= CountOf(buttons) || !buttons[FirstOf(buttonModification)]) + { + LogToInspector(<"[CursorMenu.modifyMenuButton] Error: tried to modify an invalid button ID (<0>)", FirstOf(buttonModification)>); + } + else + { + extendedPlayerCollection[2] = 1; + while (extendedPlayerCollection[2] < CountOf(buttonModification)) + { + if (buttonModification[extendedPlayerCollection[2]] < 0 || buttonModification[extendedPlayerCollection[2]] >= 13) + { + LogToInspector(<"[CursorMenu.modifyMenuButton] Error: tried to modify an invalid property index (<0>)", CountOf(buttonModification[extendedPlayerCollection[2]])>); + } + else + { + arrayBuilder = buttons[FirstOf(buttonModification)]; + arrayBuilder[buttonModification[extendedPlayerCollection[2]]] = buttonModification[extendedPlayerCollection[2] + 1]; + buttons[FirstOf(buttonModification)] = arrayBuilder; + } + extendedPlayerCollection[2] += 2; + } + } +} + +void getButtonProperties() "Get properties of a menu button" +{ + if (getProperties >= CountOf(buttons) || !buttons[getProperties]) + { + LogToInspector(<"[CursorMenu.getButtonProperties] Error: tried to access an invalid button ID (<0>)", getProperties>); + } + else + { + getProperties = ArraySlice(buttons[getProperties], 0, 13); + } +} + +rule: "Toggle menu" +Event.OngoingPlayer +Team.Team1 +if (IsGameInProgress() == false) +if (EventPlayer() == HostPlayer()) +if (!IsDummyBot(EventPlayer()) == true) +if (IsButtonHeld(EventPlayer(), Button.Crouch) == true) +if (!IsCommunicatingAnyEmote(EventPlayer()) == true) +{ + isInMenu[1] = !isInMenu[1]; +} + +void createCursor() "Create menu cursor" +{ + CreateInWorldText(FilteredArray(EventPlayer(), TotalTimeElapsed() % 0.032 < 0.016), "▲", UpdateEveryFrame(EyePosition(EventPlayer()) + 100 * (AngleDifference(HorizontalAngleFromDirection(FacingDirectionOf(EventPlayer())), HorizontalAngleFromDirection(menuOriginalFacing)) * CrossProduct(FacingDirectionOf(EventPlayer()), DirectionFromAngles(HorizontalAngleFromDirection(FacingDirectionOf(EventPlayer())), VerticalAngleFromDirection(FacingDirectionOf(EventPlayer())) - 90)) + (AngleDifference(VerticalAngleFromDirection(FacingDirectionOf(EventPlayer())), VerticalAngleFromDirection(menuOriginalFacing)) - 0.2) * DirectionFromAngles(HorizontalAngleFromDirection(FacingDirectionOf(EventPlayer())), VerticalAngleFromDirection(FacingDirectionOf(EventPlayer())) - 90) + 3 * FacingDirectionOf(EventPlayer()))), 3, Clipping.DoNotClip, InworldTextRev.VisibleToPositionStringAndColor, Color.White, Spectators.DefaultVisibility); + ModifyVariable(menuFrame, Operation.AppendToArray, LastTextID()); + CreateInWorldText(FilteredArray(EventPlayer(), TotalTimeElapsed() % 0.032 >= 0.016), "▲", UpdateEveryFrame(EyePosition(EventPlayer()) + 100 * (AngleDifference(HorizontalAngleFromDirection(FacingDirectionOf(EventPlayer())), HorizontalAngleFromDirection(menuOriginalFacing)) * CrossProduct(FacingDirectionOf(EventPlayer()), DirectionFromAngles(HorizontalAngleFromDirection(FacingDirectionOf(EventPlayer())), VerticalAngleFromDirection(FacingDirectionOf(EventPlayer())) - 90)) + (AngleDifference(VerticalAngleFromDirection(FacingDirectionOf(EventPlayer())), VerticalAngleFromDirection(menuOriginalFacing)) - 0.2) * DirectionFromAngles(HorizontalAngleFromDirection(FacingDirectionOf(EventPlayer())), VerticalAngleFromDirection(FacingDirectionOf(EventPlayer())) - 90) + 3 * FacingDirectionOf(EventPlayer()))), 3, Clipping.DoNotClip, InworldTextRev.VisibleToPositionStringAndColor, Color.White, Spectators.DefaultVisibility); + ModifyVariable(menuFrame, Operation.AppendToArray, LastTextID()); +} + +void doButtonUpdate() "Do button update" +{ + extendedPlayerCollection[2] = 0; + while (extendedPlayerCollection[2] < CountOf(buttons)) + { + if (buttons[extendedPlayerCollection[2]]) + { + if (buttons[extendedPlayerCollection[2]][15]) + { + if (buttons[extendedPlayerCollection[2]][14]) + { + DestroyInWorldText(buttons[extendedPlayerCollection[2]][13]); + } + buttons[extendedPlayerCollection[2]] = null; + } + else if (!buttons[extendedPlayerCollection[2]][12] && buttons[extendedPlayerCollection[2]][14] || !isInMenu[1]) + { + DestroyInWorldText(buttons[extendedPlayerCollection[2]][13]); + arrayBuilder = buttons[extendedPlayerCollection[2]]; + arrayBuilder[14] = false; + buttons[extendedPlayerCollection[2]] = arrayBuilder; + } + else if (buttons[extendedPlayerCollection[2]][12] && !buttons[extendedPlayerCollection[2]][14]) + { + CreateInWorldText(EventPlayer(), buttons[EvaluateOnce(extendedPlayerCollection[2])][10] ? <"<0>", FirstOf(buttons[EvaluateOnce(extendedPlayerCollection[2])])> : FirstOf(buttons[EvaluateOnce(extendedPlayerCollection[2])]), UpdateEveryFrame(EyePosition(EventPlayer()) + 100 * (buttons[EvaluateOnce(extendedPlayerCollection[2])][4] * CrossProduct(FacingDirectionOf(EventPlayer()), DirectionFromAngles(HorizontalAngleFromDirection(FacingDirectionOf(EventPlayer())), VerticalAngleFromDirection(FacingDirectionOf(EventPlayer())) - 90)) + (buttons[EvaluateOnce(extendedPlayerCollection[2])][5] - 0.2) * DirectionFromAngles(HorizontalAngleFromDirection(FacingDirectionOf(EventPlayer())), VerticalAngleFromDirection(FacingDirectionOf(EventPlayer())) - 90) + 3 * FacingDirectionOf(EventPlayer()))), buttons[EvaluateOnce(extendedPlayerCollection[2])][3], Clipping.DoNotClip, InworldTextRev.VisibleToPositionStringAndColor, buttons[EvaluateOnce(extendedPlayerCollection[2])][11] && AbsoluteValue(AngleDifference(HorizontalAngleFromDirection(FacingDirectionOf(EventPlayer())), HorizontalAngleFromDirection(menuOriginalFacing)) - buttons[EvaluateOnce(extendedPlayerCollection[2])][4]) <= buttons[EvaluateOnce(extendedPlayerCollection[2])][6] / 2 && AbsoluteValue(AngleDifference(VerticalAngleFromDirection(FacingDirectionOf(EventPlayer())), VerticalAngleFromDirection(menuOriginalFacing)) - buttons[EvaluateOnce(extendedPlayerCollection[2])][5]) <= buttons[EvaluateOnce(extendedPlayerCollection[2])][7] / 2 ? buttons[EvaluateOnce(extendedPlayerCollection[2])][9] : buttons[EvaluateOnce(extendedPlayerCollection[2])][8], Spectators.DefaultVisibility); + arrayBuilder = buttons[EvaluateOnce(extendedPlayerCollection[2])]; + arrayBuilder[13] = LastTextID(); + buttons[EvaluateOnce(extendedPlayerCollection[2])] = arrayBuilder; + arrayBuilder = buttons[EvaluateOnce(extendedPlayerCollection[2])]; + arrayBuilder[14] = true; + buttons[EvaluateOnce(extendedPlayerCollection[2])] = arrayBuilder; + } + } + extendedPlayerCollection[2] += 1; + } +} + +rule: "Close menu on start" +Event.OngoingPlayer +Team.Team1 +if (IsGameInProgress() == true) +if (isInMenu[1] == true) +{ + isInMenu[1] = false; + SetAimSpeed(EventPlayer(), 100); + SetPrimaryFireEnabled(EventPlayer(), true); + SetSecondaryFireEnabled(EventPlayer(), true); + EnableHeroHud(EventPlayer()); + extendedPlayerCollection[2] = 0; + while (extendedPlayerCollection[2] < CountOf(menuFrame)) + { + DestroyInWorldText(menuFrame[extendedPlayerCollection[2]]); + extendedPlayerCollection[2] += 1; + } + DestroyIcon(FirstOf(extendedPlayerCollection)); + doButtonUpdate(); + EnablePlayer(); +} + +rule: "Open menu" +Event.OngoingPlayer +Team.Team1 +if (IsGameInProgress() == false) +if (!IsDummyBot(EventPlayer()) == true) +if (isInMenu[1] == true) +{ + SetAimSpeed(EventPlayer(), 15); + menuOriginalFacing = FacingDirectionOf(EventPlayer()); + SetPrimaryFireEnabled(EventPlayer(), false); + SetSecondaryFireEnabled(EventPlayer(), false); + DisableHeroHud(EventPlayer()); + DisableGameModeHud(EventPlayer()); + menuFrame = []; + createCursor(); + MinWait(); + MinWait(); + MinWait(); + doButtonUpdate(); + DisablePlayer(); +} + +rule: "Close menu" +Event.OngoingPlayer +Team.Team1 +if (IsGameInProgress() == false) +if (!IsDummyBot(EventPlayer()) == true) +if (!isInMenu[1] == true) +{ + SetAimSpeed(EventPlayer(), 100); + SetPrimaryFireEnabled(EventPlayer(), true); + SetSecondaryFireEnabled(EventPlayer(), true); + EnableHeroHud(EventPlayer()); + EnableGameModeHud(EventPlayer()); + extendedPlayerCollection[2] = 0; + while (extendedPlayerCollection[2] < CountOf(menuFrame)) + { + DestroyInWorldText(menuFrame[extendedPlayerCollection[2]]); + extendedPlayerCollection[2] += 1; + } + DestroyIcon(FirstOf(extendedPlayerCollection)); + doButtonUpdate(); + EnablePlayer(); +} + +rule: "Check for button update" +Event.OngoingPlayer +Team.Team1 +if (IsGameInProgress() == false) +if (isInMenu[1] == true) +if (IsTrueForAny(buttons, ArrayElement() && (ArrayElement()[15] || !ArrayElement()[12] && ArrayElement()[14] || ArrayElement()[12] && !ArrayElement()[14])) == true) +{ + doButtonUpdate(); + MinWait(); +} + +rule: "Detect primary fire button press" +Event.OngoingPlayer +Team.Team1 +if (IsGameInProgress() == false) +if (isInMenu[1] == true) +if (IsButtonHeld(EventPlayer(), Button.PrimaryFire) == true) +{ + if (AbsoluteValue(AngleDifference(HorizontalAngleFromDirection(FacingDirectionOf(EventPlayer())), HorizontalAngleFromDirection(menuOriginalFacing)) - exitButtonProperties[1]) <= exitButtonProperties[3] / 2 && AbsoluteValue(AngleDifference(VerticalAngleFromDirection(FacingDirectionOf(EventPlayer())), VerticalAngleFromDirection(menuOriginalFacing)) - exitButtonProperties[2]) <= exitButtonProperties[3] / 2) + { + currActionID = FirstOf(exitButtonProperties); + } + extendedPlayerCollection[3] = 0; + while (extendedPlayerCollection[3] < CountOf(buttons)) + { + if (buttons[extendedPlayerCollection[3]][11] && AbsoluteValue(AngleDifference(HorizontalAngleFromDirection(FacingDirectionOf(EventPlayer())), HorizontalAngleFromDirection(menuOriginalFacing)) - buttons[extendedPlayerCollection[3]][4]) <= buttons[extendedPlayerCollection[3]][6] / 2 && AbsoluteValue(AngleDifference(VerticalAngleFromDirection(FacingDirectionOf(EventPlayer())), VerticalAngleFromDirection(menuOriginalFacing)) - buttons[extendedPlayerCollection[3]][5]) <= buttons[extendedPlayerCollection[3]][7] / 2) + { + currActionID = buttons[extendedPlayerCollection[3]][1]; + } + extendedPlayerCollection[3] += 1; + } + if (currActionID && extendedGlobalCollection[6]) + { + PlayEffect(EventPlayer(), PlayEffect.ExplosionSound, Color.White, EventPlayer(), 30); + } + MinWait(); + currActionID = null; +} + +rule: "Detect secondary fire button press" +Event.OngoingPlayer +Team.Team1 +if (IsGameInProgress() == false) +if (isInMenu[1] == true) +if (IsButtonHeld(EventPlayer(), Button.SecondaryFire) == true) +{ + if (AbsoluteValue(AngleDifference(HorizontalAngleFromDirection(FacingDirectionOf(EventPlayer())), HorizontalAngleFromDirection(menuOriginalFacing)) - exitButtonProperties[1]) <= exitButtonProperties[3] / 2 && AbsoluteValue(AngleDifference(VerticalAngleFromDirection(FacingDirectionOf(EventPlayer())), VerticalAngleFromDirection(menuOriginalFacing)) - exitButtonProperties[2]) <= exitButtonProperties[3] / 2) + { + currActionID = FirstOf(exitButtonProperties); + } + extendedPlayerCollection[4] = 0; + while (extendedPlayerCollection[4] < CountOf(buttons)) + { + if (buttons[extendedPlayerCollection[4]][11] && AbsoluteValue(AngleDifference(HorizontalAngleFromDirection(FacingDirectionOf(EventPlayer())), HorizontalAngleFromDirection(menuOriginalFacing)) - buttons[extendedPlayerCollection[4]][4]) <= buttons[extendedPlayerCollection[4]][6] / 2 && AbsoluteValue(AngleDifference(VerticalAngleFromDirection(FacingDirectionOf(EventPlayer())), VerticalAngleFromDirection(menuOriginalFacing)) - buttons[extendedPlayerCollection[4]][5]) <= buttons[extendedPlayerCollection[4]][7] / 2) + { + currActionID = buttons[extendedPlayerCollection[4]][2]; + } + extendedPlayerCollection[4] += 1; + } + if (currActionID && extendedGlobalCollection[6]) + { + PlayEffect(EventPlayer(), PlayEffect.ExplosionSound, Color.White, EventPlayer(), 30); + } + MinWait(); + currActionID = null; +} + +rule: "Cursor bounds" +Event.OngoingPlayer +Team.Team1 +if (IsGameInProgress() == false) +if (isInMenu[1] == true) +if ((AbsoluteValue(AngleDifference(HorizontalAngleFromDirection(FacingDirectionOf(EventPlayer())), HorizontalAngleFromDirection(menuOriginalFacing))) > extendedGlobalCollection[1] / 2 + 0.05 || AbsoluteValue(AngleDifference(VerticalAngleFromDirection(FacingDirectionOf(EventPlayer())), VerticalAngleFromDirection(menuOriginalFacing))) > extendedGlobalCollection[2] / 2 + 0.05) == true) +{ + SetFacing(EventPlayer(), DirectionFromAngles(Min(Max(HorizontalAngleFromDirection(menuOriginalFacing) - AngleDifference(HorizontalAngleFromDirection(FacingDirectionOf(EventPlayer())), HorizontalAngleFromDirection(menuOriginalFacing)), HorizontalAngleFromDirection(menuOriginalFacing) - extendedGlobalCollection[1] / 2), HorizontalAngleFromDirection(menuOriginalFacing) + extendedGlobalCollection[1] / 2), Min(Max(VerticalAngleFromDirection(menuOriginalFacing) - AngleDifference(VerticalAngleFromDirection(FacingDirectionOf(EventPlayer())), VerticalAngleFromDirection(menuOriginalFacing)), VerticalAngleFromDirection(menuOriginalFacing) - extendedGlobalCollection[2] / 2), VerticalAngleFromDirection(menuOriginalFacing) + extendedGlobalCollection[2] / 2)), Relative.ToWorld); + MinWait(); + LoopIfConditionIsTrue(); +} + +rule: "▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒a" +{ +} + +rule: "workshop rules" +Event.OngoingPlayer +Team.Team1 +if (IsGameInProgress() == false) +if (EventPlayer() == HostPlayer()) +{ + gateMaxHealth[1] = 100; + gateMaxHealth[2] = 1000; + moneyMultiplier[1] = 0.5; + moneyMultiplier[2] = 2; + HostPlayer().newButton = [<"GATE MAX HEALTH: <0>", gateMaxHealth[0]>, null, null, 3, -1, 0.5, 0, 0.3, Color.Green, Color.Green, true, true, true]; + createMenuButton(); + HostPlayer().workshopButtons[0] = HostPlayer().lastMenuButtonID; + HostPlayer().newButton = ["+/- 1", "gateMaxHealthAddOne", "gateMaxHealthSubtractOne", 3, 0.65, 0.5, 0.5, 0.3, Color.Green, Color.Yellow, true, true, true]; + createMenuButton(); + HostPlayer().workshopButtons[1] = HostPlayer().lastMenuButtonID; + HostPlayer().newButton = ["+/- 10", "gateMaxHealthAddTen", "gateMaxHealthSubtractTen", 3, 1.15, 0.5, 0.5, 0.3, Color.Green, Color.Yellow, true, true, true]; + createMenuButton(); + HostPlayer().workshopButtons[2] = HostPlayer().lastMenuButtonID; + HostPlayer().newButton = ["+/- 100", "gateMaxHealthAddHundred", "gateMaxHealthSubtractHundred", 3, 1.7, 0.5, 0.5, 0.3, Color.Green, Color.Yellow, true, true, true]; + createMenuButton(); + HostPlayer().workshopButtons[3] = HostPlayer().lastMenuButtonID; + HostPlayer().newButton = [<"Money Multiplier: <0>", moneyMultiplier[0]>, null, null, 3, -1, 0, 0, 0.3, Color.Green, Color.Green, true, true, true]; + createMenuButton(); + HostPlayer().workshopButtons[4] = HostPlayer().lastMenuButtonID; + HostPlayer().newButton = ["+/- 0.01", "moneyMultAddTen", "moneyMultSubtractTen", 3, 0.75, 0, 0.5, 0.3, Color.Green, Color.Yellow, true, true, true]; + createMenuButton(); + HostPlayer().workshopButtons[5] = HostPlayer().lastMenuButtonID; + HostPlayer().newButton = ["+/- 0.10", "moneyMultAddHundred", "moneyMultSubtractHundred", 3, 1.5, 0, 0.5, 0.3, Color.Green, Color.Yellow, true, true, true]; + createMenuButton(); + HostPlayer().workshopButtons[6] = HostPlayer().lastMenuButtonID; + HostPlayer().newButton = [<"Ana Self Nano: <0>", selfNanoWorkshopSetting>, null, null, 3, -1, -0.5, 0, 0.3, Color.Green, Color.Green, true, true, true]; + createMenuButton(); + HostPlayer().workshopButtons[7] = HostPlayer().lastMenuButtonID; + HostPlayer().newButton = ["Toggle", "anaSelfNano", null, 3, 0.75, -0.5, 1, 0.3, Color.Green, Color.Yellow, true, true, true]; + createMenuButton(); + HostPlayer().workshopButtons[8] = HostPlayer().lastMenuButtonID; + WaitUntil(IsGameInProgress() == true, 9999); + HostPlayer().destroyButtonID = HostPlayer().workshopButtons[0]; + destroyMenuButton(); + HostPlayer().destroyButtonID = HostPlayer().workshopButtons[1]; + destroyMenuButton(); + HostPlayer().destroyButtonID = HostPlayer().workshopButtons[2]; + destroyMenuButton(); + HostPlayer().destroyButtonID = HostPlayer().workshopButtons[3]; + destroyMenuButton(); + HostPlayer().destroyButtonID = HostPlayer().workshopButtons[4]; + destroyMenuButton(); + HostPlayer().destroyButtonID = HostPlayer().workshopButtons[5]; + destroyMenuButton(); + HostPlayer().destroyButtonID = HostPlayer().workshopButtons[6]; + destroyMenuButton(); + HostPlayer().destroyButtonID = HostPlayer().workshopButtons[7]; + destroyMenuButton(); + HostPlayer().destroyButtonID = HostPlayer().workshopButtons[8]; + destroyMenuButton(); +} + +rule: "Actions" +Event.OngoingPlayer +Team.Team1 +if (IsGameInProgress() == false) +if (currActionID != null) +{ + if (currActionID == "gateMaxHealthAddOne") + { + if (gateMaxHealth[0] + 1 <= gateMaxHealth[2]) + { + gateMaxHealth[0] += 1; + } + else + { + gateMaxHealth[0] = gateMaxHealth[2]; + } + } + else if (currActionID == "gateMaxHealthSubtractOne") + { + if (gateMaxHealth[0] - 1 >= gateMaxHealth[1]) + { + gateMaxHealth[0] -= 1; + } + else + { + gateMaxHealth[0] = gateMaxHealth[1]; + } + } + else if (currActionID == "gateMaxHealthAddTen") + { + if (gateMaxHealth[0] + 10 <= gateMaxHealth[2]) + { + gateMaxHealth[0] += 10; + } + else + { + gateMaxHealth[0] = gateMaxHealth[2]; + } + } + else if (currActionID == "gateMaxHealthSubtractTen") + { + if (gateMaxHealth[0] - 10 >= gateMaxHealth[1]) + { + gateMaxHealth[0] -= 10; + } + else + { + gateMaxHealth[0] = gateMaxHealth[1]; + } + } + else if (currActionID == "gateMaxHealthAddHundred") + { + if (gateMaxHealth[0] + 100 <= gateMaxHealth[2]) + { + gateMaxHealth[0] += 100; + } + else + { + gateMaxHealth[0] = gateMaxHealth[2]; + } + } + else if (currActionID == "gateMaxHealthSubtractHundred") + { + if (gateMaxHealth[0] - 100 >= gateMaxHealth[1]) + { + gateMaxHealth[0] -= 100; + } + else + { + gateMaxHealth[0] = gateMaxHealth[1]; + } + } + else if (currActionID == "moneyMultAddTen") + { + if (moneyMultiplier[0] + 0.01 <= moneyMultiplier[2]) + { + moneyMultiplier[0] += 0.01; + } + else + { + moneyMultiplier[0] = moneyMultiplier[2]; + } + } + else if (currActionID == "moneyMultSubtractTen") + { + if (moneyMultiplier[0] - 0.01 >= moneyMultiplier[1]) + { + moneyMultiplier[0] -= 0.01; + } + else + { + moneyMultiplier[0] = moneyMultiplier[1]; + } + } + else if (currActionID == "moneyMultAddHundred") + { + if (moneyMultiplier[0] + 0.1 <= moneyMultiplier[2]) + { + moneyMultiplier[0] += 0.1; + } + else + { + moneyMultiplier[0] = moneyMultiplier[2]; + } + } + else if (currActionID == "moneyMultSubtractHundred") + { + if (moneyMultiplier[0] - 0.1 >= moneyMultiplier[1]) + { + moneyMultiplier[0] -= 0.1; + } + else + { + moneyMultiplier[0] = moneyMultiplier[1]; + } + } + else if (currActionID == "anaSelfNano") + { + selfNanoWorkshopSetting = !selfNanoWorkshopSetting; + } + upgradeGateMaxHealthMaxValue[0] = RoundToInteger(gateMaxHealth[0] + gateMaxHealth[0] * 0.5, Rounding.Up) > 1000 ? 1000 : RoundToInteger(gateMaxHealth[0] + gateMaxHealth[0] * 0.5, Rounding.Up); + upgradeGateMaxHealthMaxValue[1] = RoundToInteger(upgradeGateMaxHealthMaxValue[0] + upgradeGateMaxHealthMaxValue[0] * 0.5, Rounding.Up); + upgradeGateMaxHealthMaxValue[2] = RoundToInteger(upgradeGateMaxHealthMaxValue[1] + upgradeGateMaxHealthMaxValue[1] * 0.5, Rounding.Up); + buttonModification = [workshopButtons[0], 0, <"GATE MAX HEALTH: <0>", gateMaxHealth[0]>]; + modifyMenuButton(); + buttonModification = [workshopButtons[4], 0, <"Money Multiplier: <0>", moneyMultiplier[0]>]; + modifyMenuButton(); + buttonModification = [workshopButtons[7], 0, <"Ana Self Nano: <0>", selfNanoWorkshopSetting>]; + modifyMenuButton(); +} \ No newline at end of file