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(); }