diff --git a/TopSecret.oww b/TopSecret.oww new file mode 100644 index 0000000..da9795d --- /dev/null +++ b/TopSecret.oww @@ -0,0 +1,4293 @@ +settings +{ + main + { + Description: "Genji Dodgeball v7.9.1. Developed by Mazawrath. Credit for others avaliable in GitHub repository https://github.com/Mazawrath/Overwatch-Genji-Dodgeball. Deflect the ball when it is red to target someone else! Use jump pads to get air!" + Mode Name: "Genji Dodgeball v7.9.1" + } + + lobby + { + Allow Players Who Are In Queue: Yes + Map Rotation: After A Game + Match Voice Chat: Enabled + Max Spectators: 6 + Return To Lobby: Never + Swap Teams After Match: No + Team Balancing: After A Game + } + + modes + { + Deathmatch + { + Game Length In Minutes: 15 + Self Initiated Respawn: Off + + enabled maps + { + Workshop Island Night 972777519512064579 + } + } + + disabled Team Deathmatch + { + Game Length In Minutes: 15 + Imbalanced Team Score To Win: On + Team 1 Score To Win: 10 + Team 2 Score To Win: 10 + } + + General + { + Allow Hero Switching: Off + Game Mode Start: Immediately + Hero Limit: Off + Respawn As Random Hero: On + } + } + + heroes + { + General + { + Genji + { + Deflect Cooldown Time: 0% + No Ammunition Requirement: On + Primary Fire: Off + Quick Melee: Off + Secondary Fire: Off + Swift Strike Cooldown Time: 38% + Ultimate Generation - Combat Dragonblade: 0% + Ultimate Generation - Passive Dragonblade: 0% + } + + Torbjörn + { + Overload Duration Scalar: 300% + } + + enabled heroes + { + Genji + } + } + } + + workshop + { + Client Prediction Amount: 1.000 + } + + extensions + { + Buff and Debuff Sounds + Kinetic Explosion Effects + Explosion Sounds + Spawn More Dummy Bots + Projectiles + } +} + +variables +{ + global: + 0: target + 1: previousTargetedPlayer + 2: ballSpeed + 3: ballPosition + 4: ballSpawnCountdown + 5: ballIsOut + 6: ballDeleteRequested + 7: roundInProgress + 8: bouncePadCooldownLength + 9: ballSpawnSpeed + 10: maxBallSpeed + 11: isInFinalDuel + 13: bouncePadDistance + 14: bouncePadStrength + 15: bouncePad1 + 16: bouncePad2 + 17: bouncePad3 + 18: bouncePad4 + 19: deathSphere + 20: deathSphereRad + 21: isEnoughPlayersToStart + 22: waitingForPlayersHUD + 23: CenterOffLimitsSize + 24: SphereSize + 25: circleCenter + 26: redGreenColorblindMode + 27: watermarkEnabled + 28: bouncepadDashingEnabled + 29: gameEndEnabled + 30: cooldownDashingEnabled + 31: deathSpherePos + 32: deathBeam + 33: ballDirection + 34: ballCollisionSurfaceNormal + 35: prevBallPos + 36: prevBallPos2 + 38: ballTail1 + 39: ballTail2 + 41: highestScore + 42: tieBreakerActive + 43: randomExplosionPicker + 44: explosionSoundVolume + 45: improvedExplosions + 46: randomExplosionSounds + 47: finalDuelNuke + 48: ballDirectionRate + 49: entityReference + 51: allowMatchEnd + 52: passingDamage + 53: isPassingTeam1 + 54: isPassingTeam2 + 55: scoreToWin + 56: passingEnabled + 57: bouncePadSuperjumpNerf + 58: passingPlayer + 59: passingAssistId + 60: passingPlayerName + 61: passingAuraToggle + 62: torbBall + 63: ballHero + 64: playerHero + 65: ballPlayer + 66: ballPlayerMock + 67: ballHeroRegretText + 68: ballHeroRandom + 69: name + 70: wasFinalDuel + 71: startingText + 72: arenaType + 73: startingBallSpeed + 74: bouncePadRange + 75: maxRoundsToggle + 76: maxRounds + 77: currentRound + 78: bouncePadToggle + 79: perspectiveMode + 80: rulesetMode + 81: bouncePadCooldownLengthStart + 82: invisibleBall + 83: invisiblePlayers + 84: endlessBall + 85: ballTailColor + 86: tournamentMode + 87: breaksEnabled + 88: breakFrequency + 89: breakLength + 90: stressTorbs + 91: breakInProgress + 92: spawnPoints + 93: invisTeamsAntiCheat + 107: gravity + + player: + 0: hasMoved + 1: currentUltPercent + 2: bouncePadCooldown + 4: playerDeflects + 5: playerKills + 6: playerDeaths + 7: playerEffects + 9: isDashEnabled + 10: moveSpeed + 11: maxBallSpeed + 12: antiFloatProtection + 13: antiStuckProtection + 14: toggleHUD + 15: dashNerf + 16: passingSignal + 17: thirdPerson + 18: yeetPlayer + 19: latency + 20: latencyToggle + 21: emoteCheatCount + 22: stunCooldown + 26: currentGravity +} + +subroutines +{ + 0: CoolDeathEffects + 1: UpdatedDeathEffects + 2: DeflectFailed + 3: ShortFun + 4: LongFun + 5: deleteBall + 6: BallCurve +} + +rule("// SETTINGS") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.perspectiveMode = Workshop Setting Combo(Custom String("Dodgeball Settings"), Custom String("Perspective Mode"), 0, Array( + Custom String("Toggle 1st/3rd Person"), Custom String("1st Person"), Custom String("3rd Person")), 0); + Global.rulesetMode = Workshop Setting Combo(Custom String("Dodgeball Settings"), Custom String("Genji Dodgeball Ruleset"), 0, + Array(Custom String("Modern"), Custom String("Retro")), 1); + Global.arenaType = Workshop Setting Combo(Custom String("Dodgeball Settings"), Custom String("Arena Type"), 0, Array(Custom String( + "Standard"), Custom String("Airbending"), Custom String("Earth/waterbending"), Custom String("Firebending")), 2); + Global.startingBallSpeed = Workshop Setting Integer(Custom String("Dodgeball Settings"), Custom String("Starting Ball Speed"), 40, + 30, 100, 3); + Global.maxBallSpeed = Workshop Setting Integer(Custom String("Dodgeball Settings"), Custom String("Maximum Ball Speed"), 500, 100, + 500, 4); + Global.endlessBall = Workshop Setting Toggle(Custom String("Dodgeball Settings"), Custom String("Endless Ball"), False, 5); + Global.bouncePadToggle = Workshop Setting Toggle(Custom String("Dodgeball Settings"), Custom String("Bouncepads"), True, 6); + Global.passingEnabled = Workshop Setting Toggle(Custom String("Dodgeball Settings"), Custom String("Passing"), False, 7); + Global.torbBall = Workshop Setting Combo(Custom String("Fun Settings"), Custom String("Torb Ball"), 0, Array(Custom String( + "Please don't."), Custom String("Torb Ball")), 0); + Global.ballTailColor = Workshop Setting Combo(Custom String("Fun Settings"), Custom String("Ball Tail Color"), 0, Array( + Custom String("Sky Blue"), Custom String("Lethality"), Custom String("Lethality+")), 1); + Global.invisibleBall = Workshop Setting Toggle(Custom String("Fun Settings"), Custom String("Invisible Ball"), False, 2); + Global.invisiblePlayers = Workshop Setting Toggle(Custom String("Fun Settings"), Custom String("Invisible Players"), False, 3); + Global.tournamentMode = Workshop Setting Toggle(Custom String("Tournament Settings (FFA Only)"), Custom String("Tournament Mode"), + False, 0); + Global.maxRounds = Workshop Setting Integer(Custom String("Tournament Settings (FFA Only)"), Custom String("Total Rounds"), 30, 1, + 50, 1); + Global.breaksEnabled = Workshop Setting Toggle(Custom String("Tournament Settings (FFA Only)"), Custom String("Breaks"), True, 2); + Global.breakFrequency = Workshop Setting Integer(Custom String("Tournament Settings (FFA Only)"), Custom String( + "Run Break Every __ Rounds"), 10, 1, 25, 3); + Global.allowMatchEnd = Workshop Setting Toggle(Custom String("Teams Settings"), Custom String("Allow Match to End At Score"), True, + 0); + Global.scoreToWin = Workshop Setting Integer(Custom String("Teams Settings"), Custom String("Score to Win"), 10, 1, 30, 1); + Global.passingAuraToggle = Workshop Setting Toggle(Custom String("Teams Settings"), Custom String("Passing Aura"), True, 2); + Global.invisTeamsAntiCheat = Workshop Setting Toggle(Custom String("Teams Settings"), Custom String( + "Invisible Players Anti-cheat"), True, 3); + "Currently, there is an issue where the server will end, based on how many players there are. If there are less it will take longer to crash. But it WILL crash. This rule simply lets there be a \"winner\" at the end VS crashing in the middle of Final Duel." + Global.gameEndEnabled = Workshop Setting Toggle(Custom String("Teams Settings"), Custom String("Allow Match to End At Time"), + False, 2); + Global.watermarkEnabled = Workshop Setting Toggle(Custom String("Visual Settings"), Custom String("Watermark"), True, 0); + Global.cooldownDashingEnabled = True; + Global.redGreenColorblindMode = Workshop Setting Toggle(Custom String("Visual Settings"), Custom String( + "Red/Green Colorblind Mode"), False, 2); + Global.finalDuelNuke = Workshop Setting Toggle(Custom String("Visual Settings"), Custom String("Final Duel Explosion"), True, 3); + } +} + +rule("// MAP ZONES") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.target = 0; + } +} + +rule("Set Workshop Island") +{ + event + { + Ongoing - Global; + } + + conditions + { + (Current Map == Map(Workshop Island) || Current Map == Map(Workshop Island Night)) == True; + } + + actions + { + Global.circleCenter = Vector(0, 1.199, 0); + Global.SphereSize = 60; + } +} + +rule("Set Workshop Chamber") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Workshop Chamber); + } + + actions + { + Global.circleCenter = Vector(0, 1.199, 0); + Global.SphereSize = 29.700; + } +} + +rule("Set Workshop Expanse Center") +{ + event + { + Ongoing - Global; + } + + conditions + { + (Current Map == Map(Workshop Expanse) || Current Map == Map(Workshop Expanse Night)) == True; + } + + actions + { + Global.circleCenter = Vector(0, 1.199, 0); + If(Global.arenaType == 2); + Global.SphereSize = 60; + Else; + Global.SphereSize = 20; + } +} + +rule("Set Workshop Green Screen Center") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Workshop Green Screen); + } + + actions + { + Global.circleCenter = Vector(0, 1.199, 0); + Global.SphereSize = 20; + } +} + +rule("Set Oasis University Center") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Oasis University); + } + + actions + { + Global.circleCenter = Vector(-192.609, 60.349, 2.252); + Global.SphereSize = 20; + } +} + +rule("Set Kings Row center (NOTE: Lower the max players! This arena is smaller then the others!)") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(King's Row); + } + + actions + { + Global.circleCenter = Vector(-20.504, 40.538, -74.601); + Global.SphereSize = 17; + } +} + +rule("Set Blizz World center (fun fact: you can't use the name of the company who made this game in rule names)") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Blizzard World); + } + + actions + { + Global.circleCenter = Vector(2.554, -4.651, -71.211); + Global.SphereSize = 20; + } +} + +rule("Init player variables") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + actions + { + Wait Until(Has Spawned(Event Player), 20); + If(Global.roundInProgress && Is Game In Progress); + Teleport(Event Player, Global.circleCenter + Vector(0, 500, 0)); + Set Invisible(Event Player, All); + Wait(0.050, Ignore Condition); + Kill(Event Player, Null); + Wait(0.250, Ignore Condition); + End; + If(Slot Of(Event Player) <= Count Of(Global.spawnPoints) && Current Game Mode == Game Mode(Deathmatch)); + Teleport(Event Player, Global.spawnPoints[Slot Of(Event Player)]); + Else; + Teleport(Event Player, Global.circleCenter + Vector(Random Integer(-10, 10), 8, Random Integer(-10, 10))); + End; + Wait(0.016, Ignore Condition); + Event Player.hasMoved = True; + If(Global.ballHero != Null && !Is Game In Progress); + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Global.ballPlayer)), 100, To World, + Direction and Turn Rate); + End; + Event Player.isDashEnabled = False; + Set Status(Event Player, Null, Invincible, 9999); + Skip If(Global.cooldownDashingEnabled, 1); + Set Ability 1 Enabled(Event Player, False); + Disable Built-In Game Mode Respawning(Event Player); + Enable Death Spectate All Players(Event Player); + Enable Death Spectate Target HUD(Event Player); + Event Player.bouncePadCooldown = Global.bouncePadCooldownLengthStart; + Event Player.antiFloatProtection = False; + Event Player.antiStuckProtection = False; + Event Player.toggleHUD = True; + Event Player.dashNerf = False; + Event Player.latencyToggle = False; + Event Player.stunCooldown = 0; + Chase Player Variable At Rate(Event Player, stunCooldown, 0, 1, None); + Wait Until(!Global.roundInProgress || !Is Game In Progress || Is Alive(Event Player), 9999); + Set Invisible(Event Player, None); + If(Global.invisiblePlayers); + Set Invisible(All Players(All Teams), All); + End; + Wait Until(Is Alive(Event Player) && Is Game In Progress, 90); + If(Global.ballHero != Null); + Stop Facing(Event Player); + End; + "Force 3rd person if it's toggled on." + If(Global.perspectiveMode == 2); + Event Player.thirdPerson = True; + Start Camera(Event Player, Event Player + World Vector Of(Vector(-0.750, 0.250, -0.250), Event Player, Rotation) + + Up * 1.500 + Facing Direction Of(Event Player) * -2, Event Player + Facing Direction Of(Event Player) * 1000, 0); + Else If(Global.invisiblePlayers); + Start Camera(Event Player, Update Every Frame(Eye Position(Event Player)), Update Every Frame(Event Player + Facing Direction Of( + Event Player) * 1000), 0); + End; + Wait(3, Ignore Condition); + Small Message(Event Player, Custom String("Press {0} to enable/disable the scoreboard", Input Binding String(Button(Interact)))); + If(Global.perspectiveMode == 0); + Wait(3, Ignore Condition); + Small Message(Event Player, Custom String("Press {0} to toggle 1st/3rd person", Input Binding String(Button(Reload)))); + End; + If(Current Game Mode == Game Mode(Team Deathmatch) && Global.invisiblePlayers && Global.invisTeamsAntiCheat); + Big Message(Event Player, Custom String("Invisible Players: No emoting!")); + Wait(3, Ignore Condition); + Small Message(Event Player, Custom String("Invisible players active: No emoting allowed! (This rule is enforced, be careful!)")); + } +} + +rule("Init global variables") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.target = -1; + Global.previousTargetedPlayer = -1; + If(Random Integer(1, 100) == 69); + Global.ballSpawnCountdown = 69; + Else; + Global.ballSpawnCountdown = 5; + End; + If(Global.tournamentMode && Current Game Mode != Game Mode(Deathmatch)); + Global.tournamentMode = False; + Create HUD Text(Host Player, Null, Null, Custom String("Tournament mode is only supported in FFA"), Left, -20, Null, Null, Color( + White), Visible To, Visible Always); + End; + Disable Built-In Game Mode Scoring; + Disable Built-In Game Mode Completion; + Disable Built-In Game Mode Music; + Disable Built-In Game Mode Announcer; + Disable Inspector Recording; + "Set the countdown to be a bit longer to let players who haven't loaded the map yet load in" + Set Match Time(10); + If(Global.torbBall == 1 && Current Game Mode == Game Mode(Deathmatch)); + Global.ballHero = Hero(Torbjörn); + Global.name = Global.ballHero; + Else; + "No touchy. I'm talking to you, person thinking it's funny to put your name here. Only Torbjörn can steal credit for making my game." + Global.name = Custom String("Mazawrath"); + Global.ballHero = Null; + End; + "TODO get this working\r\n playerHero = [hero for hero in getAllHeroes() if hero != ballHero]" + Global.playerHero = Hero(Genji); + Global.bouncePadStrength = 30; + Global.ballSpeed = Global.startingBallSpeed; + Global.ballSpawnSpeed = 30; + If(Global.arenaType == 2); + If(Current Map == Map(Workshop Expanse) || Current Map == Map(Workshop Expanse Night)); + Global.CenterOffLimitsSize = 20; + Else; + Global.CenterOffLimitsSize = 12.500; + End; + Else; + Global.CenterOffLimitsSize = 3.500; + End; + Global.spawnPoints = Array(Vector(X Component Of(Global.circleCenter) + 12, Y Component Of(Global.circleCenter), 0), Vector( + X Component Of(Global.circleCenter) - 12, Y Component Of(Global.circleCenter), 0), Vector(0, Y Component Of( + Global.circleCenter), Z Component Of(Global.circleCenter) + 12), Vector(0, Y Component Of(Global.circleCenter), Z Component Of( + Global.circleCenter) - 12), Vector(X Component Of(Global.circleCenter) + 12, Y Component Of(Global.circleCenter), + Z Component Of(Global.circleCenter) + 12), Vector(X Component Of(Global.circleCenter) + 12, Y Component Of( + Global.circleCenter), Z Component Of(Global.circleCenter) - 12), Vector(X Component Of(Global.circleCenter) - 12, + Y Component Of(Global.circleCenter), Z Component Of(Global.circleCenter) + 12), Vector(X Component Of(Global.circleCenter) + - 12, Y Component Of(Global.circleCenter), Z Component Of(Global.circleCenter) - 12), Vector(X Component Of( + Global.circleCenter) + 12, Y Component Of(Global.circleCenter), Z Component Of(Global.circleCenter) + 6), Vector( + X Component Of(Global.circleCenter) - 12, Y Component Of(Global.circleCenter), Z Component Of(Global.circleCenter) - 6), + Vector(X Component Of(Global.circleCenter) + 12, Y Component Of(Global.circleCenter), Z Component Of(Global.circleCenter) - 6), + Vector(X Component Of(Global.circleCenter) - 12, Y Component Of(Global.circleCenter), Z Component Of(Global.circleCenter) + + 6)); + Global.isInFinalDuel = False; + Global.bouncePadCooldownLengthStart = 3; + Global.bouncePadCooldownLength = 3; + Global.bouncePadSuperjumpNerf = 6; + Global.ballPosition = Vector(0, -1, 0); + Global.explosionSoundVolume = 30; + Global.improvedExplosions = True; + Global.randomExplosionSounds = True; + Global.cooldownDashingEnabled = True; + Global.passingDamage = 100; + Global.isPassingTeam1 = False; + Global.isPassingTeam2 = False; + Global.passingPlayer = Null; + Global.currentRound = 1; + Global.breakLength = 120; + Global.maxRoundsToggle = False; + If(Current Game Mode == Game Mode(Deathmatch)); + If(Global.tournamentMode); + Global.maxRoundsToggle = True; + Global.gameEndEnabled = False; + Else; + Global.gameEndEnabled = True; + End; + End; + "Using passing with retro ruleset DOES NOT work" + If(Global.rulesetMode == 1 && Global.passingEnabled && Current Game Mode == Game Mode(Deathmatch)); + Global.passingEnabled = False; + Create HUD Text(Host Player, Null, Null, Custom String( + "Hi host. Very clever idea but sorry retro rules totally breaks self passing. Like, what do you think it can even do? The b{0}", + Custom String( + "all can only go in a straight direction and self passing sends the ball away from you and then curves around so in this ca{0}", + Custom String("se where would it even go? In your head. That's where it goes. I tested it. So you don't have to."))), Right, 0, + Null, Null, Color(White), Visible To, Default Visibility); + End; + Create Effect(Empty Array, Sphere, False, Down, False, None); + Destroy Effect(Last Created Entity); + Global.entityReference = Last Created Entity; + } +} + +rule("Create game sphere") +{ + event + { + Ongoing - Global; + } + + actions + { + Create Effect(All Players(All Teams), Sphere, Color(Black), Vector(X Component Of(Global.circleCenter), Y Component Of( + Global.circleCenter), Z Component Of(Global.circleCenter)), Global.CenterOffLimitsSize, Visible To); + "Workshop Island doesn't need a circle." + If(Current Map != Map(Workshop Island) && Current Map != Map(Workshop Island Night)); + Create Effect(All Players(All Teams), Light Shaft, Color(Orange), Vector(X Component Of(Global.circleCenter), Y Component Of( + Global.circleCenter) - 25, Z Component Of(Global.circleCenter)), Global.SphereSize, Visible To); + Else; + Create Effect(Filtered Array(All Players(All Teams), Distance Between(Position Of(Current Array Element), Global.circleCenter) + >= Global.SphereSize - 10), Light Shaft, Color(Blue), Vector(X Component Of(Global.circleCenter), Y Component Of( + Global.circleCenter) - 15, Z Component Of(Global.circleCenter)), Global.SphereSize, Visible To); + } +} + +rule("Create global HUD elements") +{ + event + { + Ongoing - Global; + } + + actions + { + "hudText(getAllPlayers(), null, null, \"BETA BUILD - NOT FULLY TESTED - CHANGES ARE NOT FINAL\", HudPosition.LEFT, -20, null, null, Color.AQUA, HudReeval.VISIBILITY, SpecVisibility.ALWAYS)" + If(Current Game Mode == Game Mode(Deathmatch)); + "white normal" + Create HUD Text(Array Contains(All Players(All Teams), Local Player) ? Remove From Array(All Players(All Teams), Global.target) + : Empty Array, Null, Custom String("Current Player Targeted: {0}", Global.target), Null, Left, -2, Null, Color(White), Null, + Visible To and String, Default Visibility); + End; + If(Current Game Mode == Game Mode(Team Deathmatch)); + "white normal" + Create HUD Text(Filtered Array(All Players(All Teams), Current Array Element != Global.target && Team Of(Current Array Element) + != Team Of(Global.target)), Null, Custom String("Current Player Targeted: {0}", Global.target), Null, Left, -2, Null, Color( + White), Null, Visible To and String, Default Visibility); + "sky blue targeting teammate" + Create HUD Text(Filtered Array(All Players(All Teams), Current Array Element != Global.target && Team Of(Current Array Element) + == Team Of(Global.target)), Null, Custom String("Current Player Targeted: {0}", Global.target), Null, Left, -2, Null, Color( + Sky Blue), Null, Visible To and String, Default Visibility); + End; + "red when you're targeted" + Create HUD Text(Array Contains(All Players(All Teams), Local Player) ? Global.target : Empty Array, Null, Custom String( + "Current Player Targeted: {0}", Global.target), Null, Left, -2, Null, Color(Red), Null, Visible To and String, + Default Visibility); + Create HUD Text(All Dead Players(All Teams), Custom String("Waiting for next round"), Custom String( + "You have been eliminated or joined during a round"), Custom String("You will spawn once the next round starts"), Top, 2, + Color(White), Color(White), Color(White), Visible To, Default Visibility); + "pass" + disabled Abort; + "hudSubtext(getAllPlayers(), \"If you get hit, you die. Last man standing wins!\", HudPosition.RIGHT, -9, Color.WHITE, HudReeval.VISIBILITY_AND_STRING, SpecVisibility.DEFAULT)\r\nball speed text color change with speed" + Create HUD Text(All Players(All Teams), Null, Null, Custom String("Current Ball Speed: {0}", Global.ballSpeed), Left, -3, Null, + Null, Custom Color(Max(0, Min(1333.333 / (Global.maxBallSpeed - Global.ballSpawnSpeed) * ( + Global.ballSpeed - Global.ballSpawnSpeed) - 200, 200)) + 55 * (Global.ballSpeed != Global.maxBallSpeed), Max(55, Min( + 455 - 666.667 / (Global.maxBallSpeed - Global.ballSpawnSpeed) * (Global.ballSpeed - Global.ballSpawnSpeed), 255)) + Min( + 666.667 / (Global.maxBallSpeed - Global.ballSpawnSpeed) * (Global.ballSpeed - Global.ballSpawnSpeed) - 100, 0), Max(55, 500 / ( + Global.maxBallSpeed - Global.ballSpawnSpeed) * (Global.ballSpeed - Global.ballSpawnSpeed) - 245) - Min(59259.258 / ( + Global.maxBallSpeed - Global.ballSpawnSpeed) ^ 3 * (Global.ballSpeed - Global.ballSpawnSpeed) ^ 3 - 200, 0), 255), + Visible To String and Color, Default Visibility); + "hudSubheader(getAllPlayers(), \"Updates by u/FearlessKat, u/Blink, u/TheRedstoneBlaze, tumtum9000#1232,david8686406#1523\", HudPosition.LEFT, -10, Color.WHITE, HudReeval.VISIBILITY_AND_STRING, SpecVisibility.DEFAULT)" + If(Global.watermarkEnabled && !Global.tournamentMode); + Create HUD Text(All Players(All Teams), Null, Custom String("Discord.gg/GenjiDodgeball"), Null, Left, 0, Null, Color(White), Null, + Visible To, Default Visibility); + End; + Create In-World Text(Filtered Array(All Players(All Teams), + Global.ballSpawnCountdown != 0 && Current Array Element != Global.target), Custom String("Ball Spawning In: {0}", + Round To Integer(Global.ballSpawnCountdown, Up)), Vector(X Component Of(Global.circleCenter), Y Component Of( + Global.circleCenter) + 2.500, Z Component Of(Global.circleCenter)), 2.500, Clip Against Surfaces, Visible To and String, Color( + Sky Blue), Default Visibility); + Create In-World Text(Global.ballSpawnCountdown != 0 ? Global.target : Empty Array, Custom String("Ball Spawning In: {0}", + Round To Integer(Global.ballSpawnCountdown, Up)), Update Every Frame(Vector(X Component Of(Global.circleCenter), + Y Component Of(Global.circleCenter) + 2.500, Z Component Of(Global.circleCenter)) + Direction Towards(Vector(X Component Of( + Global.circleCenter), Y Component Of(Global.circleCenter) + 2.500, Z Component Of(Global.circleCenter)), Eye Position( + Global.target)) / 50), 2.500, Clip Against Surfaces, Visible To Position and String, Custom Color(255, 50, 50, 255), + Default Visibility); + If(Global.rulesetMode == 1); + If(Current Game Mode == Game Mode(Deathmatch)); + Create HUD Text(All Players(All Teams), Null, Custom String("Retro ruleset. Dash deflecting is disabled."), Null, Right, 0, Null, + Color(White), Null, Visible To, Default Visibility); + Else; + Create HUD Text(All Players(All Teams), Null, Custom String("Retro ruleset. Dash deflecting & self passing are disabled."), Null, + Right, 0, Null, Color(White), Null, Visible To, Default Visibility); + End; + End; + If(Global.passingEnabled && Global.rulesetMode == 0); + If(Current Game Mode == Game Mode(Team Deathmatch)); + Create HUD Text(All Players(All Teams), Null, Custom String("Hold {0} while deflecting to pass the ball to another teammate!", + Input Binding String(Button(Secondary Fire))), Null, Right, 0, Null, Color(White), Null, Visible To and String, + Default Visibility); + Else If(Current Game Mode == Game Mode(Deathmatch)); + Create HUD Text(All Players(All Teams), Null, Custom String("Hold {0} while deflecting to self pass the ball!", + Input Binding String(Button(Secondary Fire))), Null, Right, 0, Null, Color(White), Null, Visible To and String, + Default Visibility); + End; + End; + If(Global.tournamentMode); + Create HUD Text(All Players(All Teams), Null, Custom String("Tourney Mode. Rounds Remaining: {0}", + Global.maxRounds - Global.currentRound + 1), Null, Left, -10, Null, Color(Aqua), Null, Visible To and String, + Default Visibility); + } +} + +rule("Create player HUD elements") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Global.rulesetMode != 2; + } + + actions + { + Create HUD Text(Array Contains(All Players(All Teams), Local Player) ? Event Player : Empty Array, Null, Custom String( + "Lag compensation [{0}]: {1}", Input Binding String(Button(Ultimate)), Event Player.latencyToggle ? Custom String("On") + : Custom String("Off")), Null, Left, 1, Null, Color(White), Null, Visible To and String, Visible Never); + If(Global.perspectiveMode == 0); + Create HUD Text(Array Contains(All Players(All Teams), Local Player) ? Event Player : Empty Array, Null, Custom String( + "Third person: [{0}]", Input Binding String(Button(Reload))), Null, Left, 1, Null, Color(White), Null, Visible To and String, + Visible Never); + } +} + +rule("Create bounce pads") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.bouncePadToggle != False; + } + + actions + { + If(Global.arenaType == 0); + Global.bouncePadDistance = 12; + Global.bouncePadRange = 2.750; + Global.bouncePad1 = Vector(X Component Of(Global.circleCenter) + Global.bouncePadDistance, Y Component Of(Global.circleCenter), + Z Component Of(Global.circleCenter)); + Global.bouncePad2 = Vector(X Component Of(Global.circleCenter) + Global.bouncePadDistance * -1, Y Component Of( + Global.circleCenter), Z Component Of(Global.circleCenter)); + Global.bouncePad3 = Vector(X Component Of(Global.circleCenter), Y Component Of(Global.circleCenter), Z Component Of( + Global.circleCenter) + Global.bouncePadDistance); + Global.bouncePad4 = Vector(X Component Of(Global.circleCenter), Y Component Of(Global.circleCenter), Z Component Of( + Global.circleCenter) + Global.bouncePadDistance * -1); + "Bouncepad ready" + Create Effect(Filtered Array(All Players(All Teams), Current Array Element.bouncePadCooldown == 0), Ring, Color(Sky Blue), + Global.bouncePad1, 2, Visible To); + Create Effect(Filtered Array(All Players(All Teams), Current Array Element.bouncePadCooldown == 0), Ring, Color(Sky Blue), + Global.bouncePad2, 2, Visible To); + Create Effect(Filtered Array(All Players(All Teams), Current Array Element.bouncePadCooldown == 0), Ring, Color(Sky Blue), + Global.bouncePad3, 2, Visible To); + Create Effect(Filtered Array(All Players(All Teams), Current Array Element.bouncePadCooldown == 0), Ring, Color(Sky Blue), + Global.bouncePad4, 2, Visible To); + "Bouncepad not ready" + Create Effect(Filtered Array(All Players(All Teams), Current Array Element.bouncePadCooldown > 0), Ring, Color(White), + Global.bouncePad1, 2, Visible To); + Create Effect(Filtered Array(All Players(All Teams), Current Array Element.bouncePadCooldown > 0), Ring, Color(White), + Global.bouncePad2, 2, Visible To); + Create Effect(Filtered Array(All Players(All Teams), Current Array Element.bouncePadCooldown > 0), Ring, Color(White), + Global.bouncePad3, 2, Visible To); + Create Effect(Filtered Array(All Players(All Teams), Current Array Element.bouncePadCooldown > 0), Ring, Color(White), + Global.bouncePad4, 2, Visible To); + Else If(Global.arenaType == 1); + Global.bouncePadDistance = 0; + Global.bouncePadRange = 20.750; + Global.bouncePad1 = Vector(X Component Of(Global.circleCenter) + Global.bouncePadDistance, Y Component Of(Global.circleCenter), + Z Component Of(Global.circleCenter)); + "Bouncepad ready" + Create Effect(Filtered Array(All Players(All Teams), Current Array Element.bouncePadCooldown == 0), Ring, Color(Sky Blue), + Global.bouncePad1, 20, Visible To); + "Bouncepad not ready" + Create Effect(Filtered Array(All Players(All Teams), Current Array Element.bouncePadCooldown > 0), Ring, Color(White), + Global.bouncePad1, 20, Visible To); + } +} + +rule("Create ball & targeted effect") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Current Game Mode == Game Mode(Deathmatch); + } + + actions + { + If(!Global.ballHero && !Global.invisibleBall); + "Orb for when ball is not getting passed" + Create Projectile Effect(All Players(All Teams), Sigma Hypersphere, Null, Global.ballPosition, Global.ballDirection, 0.010, + Visible To Position Direction and Size); + Create Effect(Update Every Frame((Array Contains(All Players(All Teams), Local Player) || String Contains(Custom String("$#@{0}", + Local Player), Custom String("$#@{0} ", String Split(Global.entityReference, Custom String(" "))))) && Is Alive(Local Player) + && Local Player.latencyToggle ? Remove From Array(All Players(All Teams), Global.target) : Empty Array), Orb, Color(White), + Update Every Frame(Global.ballPosition), 0.400, Visible To Position and Radius); + Create Effect(Update Every Frame(!(Array Contains(All Players(All Teams), Local Player) || String Contains(Custom String("$#@{0}", + Local Player), Custom String("$#@{0} ", String Split(Global.entityReference, Custom String(" "))))) || (Is Alive(Local Player) + && Local Player.latencyToggle) ? Empty Array : Remove From Array(All Players(All Teams), Global.target)), Orb, Color(White), + Global.ballPosition, 0.400, Visible To Position and Radius); + Create Effect(Update Every Frame((Array Contains(All Players(All Teams), Local Player) || String Contains(Custom String("$#@{0}", + Local Player), Custom String("$#@{0} ", String Split(Global.entityReference, Custom String(" "))))) && Is Alive(Local Player) + && Local Player.latencyToggle ? Global.target : Empty Array), Orb, Global.redGreenColorblindMode ? Color(Yellow) : Color(Red), + Update Every Frame(Global.ballPosition + Global.ballSpeed * Normalize(Global.ballDirection) * ( + Global.ballSpawnCountdown == 0 ? Local Player.latency : 0)), 0.400, Visible To Position and Radius); + Create Effect(Update Every Frame(!(Array Contains(All Players(All Teams), Local Player) || String Contains(Custom String("$#@{0}", + Local Player), Custom String("$#@{0} ", String Split(Global.entityReference, Custom String(" "))))) || (Is Alive(Local Player) + && Local Player.latencyToggle) ? Empty Array : Global.target), Orb, Global.redGreenColorblindMode ? Color(Yellow) : Color(Red), + Global.ballPosition, 0.400, Visible To Position and Radius); + End; + If(!Global.invisiblePlayers); + Create Effect(Remove From Array(All Players(All Teams), Global.target), Good Aura, Global.redGreenColorblindMode ? Color(Yellow) + : Color(Red), Update Every Frame(Position Of(Global.target) + Up), 1, Visible To Position and Radius); + Create Effect(Update Every Frame(Filtered Array(All Players(All Teams), Current Array Element != Global.target && ( + Global.isPassingTeam1 || Global.isPassingTeam2))), Good Aura, Color(Sky Blue), Global.target, 1, + Visible To Position and Radius); + "Can't have an else if for deciding the color, only if else so just make a basic check for colorblind mode otherwise use the more complex first/third color" + If(Global.redGreenColorblindMode); + Create Effect(Global.target, Good Aura, Color(Yellow), Update Every Frame(Position Of(Global.target) + Up), + Global.target.thirdPerson ? 0.500 : 1, Visible To Position and Radius); + Else; + Create Effect(Global.target, Good Aura, Color(Red), Update Every Frame(Position Of(Global.target) + Up), + Global.target.thirdPerson ? 0.500 : 1, Visible To Position Radius and Color); + End; + End; + If(!Global.invisibleBall); + Create Effect(Update Every Frame(Array Contains(All Players(All Teams), Local Player) && Is Alive(Local Player) + && Local Player.latencyToggle ? Global.target : Empty Array), Good Aura, Global.redGreenColorblindMode ? Color(Yellow) : Color( + Red), Update Every Frame(Global.ballPosition + Global.ballSpeed * Normalize(Global.ballDirection) * ( + Global.ballSpawnCountdown == 0 ? Local Player.latency : 0)), 1, Visible To Position and Radius); + Create Effect(Update Every Frame(Array Contains(All Players(All Teams), Local Player) && !(Is Alive(Local Player) + && Local Player.latencyToggle) ? Global.target : Empty Array), Good Aura, Global.redGreenColorblindMode ? Color(Yellow) + : Color(Red), Global.ballPosition, 1, Visible To Position and Radius); + Create Effect(Update Every Frame(Global.isPassingTeam1 || Global.isPassingTeam2 ? Remove From Array(All Players(All Teams), + Global.target) : Empty Array), Good Aura, Color(Sky Blue), Update Every Frame(Global.ballPosition), 1, + Visible To Position and Radius); + } +} + +rule("Create ball & targeted effect - TEAMS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Current Game Mode == Game Mode(Team Deathmatch); + } + + actions + { + If(!Global.invisibleBall); + "Team A standard targeting Team B ball" + Create Effect(Update Every Frame((Array Contains(All Players(All Teams), Local Player) || String Contains(Custom String("$#@{0}", + Local Player), Custom String("$#@{0} ", String Split(Global.entityReference, Custom String(" "))))) && Is Alive(Local Player) + && Local Player.latencyToggle ? Filtered Array(All Players(All Teams), Current Array Element != Global.target && Team Of( + Global.target) != Team Of(Current Array Element)) : Empty Array), Orb, Color(White), Update Every Frame(Global.ballPosition), + 0.400, Visible To Position and Radius); + Create Effect(Update Every Frame(!(Array Contains(All Players(All Teams), Local Player) || String Contains(Custom String("$#@{0}", + Local Player), Custom String("$#@{0} ", String Split(Global.entityReference, Custom String(" "))))) || (Is Alive(Local Player) + && Local Player.latencyToggle) ? Empty Array : Filtered Array(All Players(All Teams), + Current Array Element != Global.target && Team Of(Global.target) != Team Of(Current Array Element))), Orb, Color(White), + Global.ballPosition, 0.400, Visible To Position and Radius); + "Team A standard targeting Team A ball" + Create Effect(Update Every Frame((Array Contains(All Players(All Teams), Local Player) || String Contains(Custom String("$#@{0}", + Local Player), Custom String("$#@{0} ", String Split(Global.entityReference, Custom String(" "))))) && Is Alive(Local Player) + && Local Player.latencyToggle ? Filtered Array(All Players(All Teams), Current Array Element != Global.target && Team Of( + Global.target) == Team Of(Current Array Element)) : Empty Array), Orb, Color(Sky Blue), Update Every Frame( + Global.ballPosition), 0.400, Visible To Position and Radius); + Create Effect(Update Every Frame(!(Array Contains(All Players(All Teams), Local Player) || String Contains(Custom String("$#@{0}", + Local Player), Custom String("$#@{0} ", String Split(Global.entityReference, Custom String(" "))))) || (Is Alive(Local Player) + && Local Player.latencyToggle) ? Empty Array : Filtered Array(All Players(All Teams), + Current Array Element != Global.target && Team Of(Global.target) == Team Of(Current Array Element))), Orb, Color(Sky Blue), + Global.ballPosition, 0.400, Visible To Position and Radius); + Create Effect(Update Every Frame((Array Contains(All Players(All Teams), Local Player) || String Contains(Custom String("$#@{0}", + Local Player), Custom String("$#@{0} ", String Split(Global.entityReference, Custom String(" "))))) && Is Alive(Local Player) + && Local Player.latencyToggle ? Global.target : Empty Array), Orb, Global.redGreenColorblindMode ? Color(Yellow) : Color(Red), + Update Every Frame(Global.ballPosition + Global.ballSpeed * Normalize(Global.ballDirection) * ( + Global.ballSpawnCountdown == 0 ? Local Player.latency : 0)), 0.400, Visible To Position and Radius); + Create Effect(Update Every Frame(!(Array Contains(All Players(All Teams), Local Player) || String Contains(Custom String("$#@{0}", + Local Player), Custom String("$#@{0} ", String Split(Global.entityReference, Custom String(" "))))) || (Is Alive(Local Player) + && Local Player.latencyToggle) ? Empty Array : Global.target), Orb, Global.redGreenColorblindMode ? Color(Yellow) : Color(Red), + Global.ballPosition, 0.400, Visible To Position and Radius); + End; + If(!Global.invisiblePlayers); + Create Effect(Remove From Array(All Players(All Teams), Global.target), Good Aura, Global.redGreenColorblindMode ? Color(Yellow) + : Color(Red), Update Every Frame(Position Of(Global.target) + Up), 1, Visible To Position and Radius); + Create Effect(Filtered Array(All Players(All Teams), Current Array Element != Global.target && ( + Global.isPassingTeam1 || Global.isPassingTeam2)), Good Aura, Color(Sky Blue), Update Every Frame(Global.target + Up), 1, + Visible To Position and Radius); + "Can't have an else if for deciding the color, only if else so just make a basic check for colorblind mode otherwise use the more complex first/third color" + If(Global.redGreenColorblindMode); + Create Effect(Global.target, Good Aura, Color(Yellow), Update Every Frame(Position Of(Global.target) + Up), + Global.target.thirdPerson ? 0.500 : 1, Visible To Position and Radius); + Else; + Create Effect(Global.target, Good Aura, Color(Red), Update Every Frame(Position Of(Global.target) + Up), + Global.target.thirdPerson ? 0.500 : 1, Visible To Position Radius and Color); + End; + End; + If(!Global.invisibleBall); + Create Effect(Update Every Frame((Array Contains(All Players(All Teams), Local Player) || String Contains(Custom String("$#@{0}", + Local Player), Custom String("$#@{0} ", String Split(Global.entityReference, Custom String(" "))))) && Is Alive(Local Player) + && Local Player.latencyToggle ? Global.target : Empty Array), Good Aura, Global.redGreenColorblindMode ? Color(Yellow) : Color( + Red), Update Every Frame(Global.ballPosition + Global.ballSpeed * Normalize(Global.ballDirection) * ( + Global.ballSpawnCountdown == 0 ? Local Player.latency : 0)), 1, Visible To Position and Radius); + Create Effect(Update Every Frame(!(Array Contains(All Players(All Teams), Local Player) || String Contains(Custom String("$#@{0}", + Local Player), Custom String("$#@{0} ", String Split(Global.entityReference, Custom String(" "))))) || (Is Alive(Local Player) + && Local Player.latencyToggle) ? Empty Array : Global.target), Good Aura, Global.redGreenColorblindMode ? Color(Yellow) + : Color(Red), Global.ballPosition, 1, Visible To Position and Radius); + Create Effect(Update Every Frame((Global.isPassingTeam1 || Global.isPassingTeam2) && (Array Contains(All Players(All Teams), + Local Player) || String Contains(Custom String("$#@{0}", Local Player), Custom String("$#@{0} ", String Split( + Global.entityReference, Custom String(" "))))) && Is Alive(Local Player) && Local Player.latencyToggle ? Remove From Array( + All Players(All Teams), Global.target) : Empty Array), Good Aura, Color(Sky Blue), Update Every Frame(Global.ballPosition), 1, + Visible To Position and Radius); + Create Effect(Update Every Frame((Global.isPassingTeam1 || Global.isPassingTeam2) && !(!(Array Contains(All Players(All Teams), + Local Player) || String Contains(Custom String("$#@{0}", Local Player), Custom String("$#@{0} ", String Split( + Global.entityReference, Custom String(" "))))) || (Is Alive(Local Player) && Local Player.latencyToggle)) ? Remove From Array( + All Players(All Teams), Global.target) : Empty Array), Good Aura, Color(Sky Blue), Global.ballPosition, 1, + Visible To Position and Radius); + } +} + +disabled rule("Ball tail effects") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.invisibleBall == False; + } + + actions + { + Create Beam Effect(Update Every Frame((Array Contains(All Players(All Teams), Local Player) || String Contains(Custom String( + "$#@{0}", Local Player), Custom String("$#@{0} ", String Split(Global.entityReference, Custom String(" "))))) && Is Alive( + Local Player) && Local Player.latencyToggle ? All Players(All Teams) : Empty Array), Bad Beam, Global.prevBallPos, + Mapped Array( + Global.target == Local Player && Global.ballSpawnCountdown == 0 ? Global.ballPosition + Global.ballSpeed * Normalize( + Global.ballDirection) * Local Player.latency : Global.ballPosition, Distance Between(Eye Position(Local Player), + Current Array Element) < 17.800 ? Update Every Frame(Current Array Element) : Current Array Element), Array(Color(Sky Blue), + Color(Yellow), Global.ballTail1)[Global.ballTailColor], Visible To Position Radius and Color); + Create Beam Effect(Update Every Frame(Array(!((Array Contains(All Players(All Teams), Local Player) || String Contains( + Custom String("$#@{0}", Local Player), Custom String("$#@{0} ", String Split(Global.entityReference, Custom String(" "))))) + && Is Alive(Local Player) && Local Player.latencyToggle))), Bad Beam, Global.prevBallPos, Global.ballPosition, Array(Color( + Sky Blue), Color(Yellow), Global.ballTail2)[Global.ballTailColor], Visible To Position Radius and Color); + Create Beam Effect(All Players(All Teams), Bad Beam, Global.prevBallPos2, Global.prevBallPos, Array(Color(Sky Blue), Color(Yellow), + Global.ballTail2)[Global.ballTailColor], Visible To Position Radius and Color); + } +} + +rule("Spectator effects and HUD") +{ + event + { + Ongoing - Global; + } + + actions + { + Create HUD Text(Update Every Frame(Array(!(Array Contains(All Players(All Teams), Local Player) || String Contains(Custom String( + "$#@{0}", Local Player), Custom String("$#@{0} ", String Split(Global.entityReference, Custom String(" "))))))), Null, + Custom String("Current Player Targeted: {0}", Global.target), Null, Left, -2, Null, Color(White), Null, Visible To and String, + Default Visibility); + Create In-World Text(Update Every Frame(Array(Global.ballSpawnCountdown != 0 && !(Array Contains(All Players(All Teams), + Local Player) || String Contains(Custom String("$#@{0}", Local Player), Custom String("$#@{0} ", String Split( + Global.entityReference, Custom String(" "))))))), Custom String("Ball Spawning In: {0}", Round To Integer( + Global.ballSpawnCountdown, Up)), Vector(X Component Of(Global.circleCenter), Y Component Of(Global.circleCenter) + 2.500, + Z Component Of(Global.circleCenter)), 2.500, Clip Against Surfaces, Visible To and String, Color(Sky Blue), + Default Visibility); + Abort If(Global.ballHero || Global.invisibleBall); + Wait Until(Is Game In Progress, 99999); + Create Effect(Update Every Frame(Array(!(Array Contains(All Players(All Teams), Local Player) || String Contains(Custom String( + "$#@{0}", Local Player), Custom String("$#@{0} ", String Split(Global.entityReference, Custom String(" "))))))), Orb, Color( + White), Global.ballPosition, 0.400, Visible To Position and Radius); + } +} + +rule("Set time to 0 if teams and game end disabled") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Game Mode == Game Mode(Team Deathmatch); + Global.gameEndEnabled == False; + Is Game In Progress == True; + } + + actions + { + Set Match Time(0); + } +} + +rule("Set Time To 0 in Tourney Mode") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.tournamentMode != False; + } + + actions + { + Set Match Time(0); + } +} + +rule("Tournament Break") +{ + event + { + Subroutine; + deleteBall; + } + + actions + { + Global.breakInProgress = True; + Wait(1, Ignore Condition); + Global.ballSpawnCountdown = Global.breakLength; + Chase Global Variable At Rate(ballSpawnCountdown, 0, 1, None); + Chase Player Variable At Rate(All Players(All Teams), bouncePadCooldown, 0, 1, None); + Enable Built-In Game Mode Announcer; + Set Match Time(Global.breakLength); + Big Message(All Players(All Teams), Custom String("Break Time!")); + Chase Player Variable At Rate(All Players(All Teams), bouncePadCooldown, 0, 2, None); + Disable Built-In Game Mode Scoring; + "Spawn the stress relief Torbs" + If(Current Game Mode == Game Mode(Deathmatch)); + Create Dummy Bot(Hero(Torbjörn), All Teams, 15, Global.circleCenter + Vector(Random Integer(-10, 10), 8, Random Integer(-10, 10)), + Vector(0, 0, 0)); + Create Dummy Bot(Hero(Torbjörn), All Teams, 16, Global.circleCenter + Vector(Random Integer(-10, 10), 8, Random Integer(-10, 10)), + Vector(0, 0, 0)); + Create Dummy Bot(Hero(Torbjörn), All Teams, 17, Global.circleCenter + Vector(Random Integer(-10, 10), 8, Random Integer(-10, 10)), + Vector(0, 0, 0)); + Else If(Current Game Mode == Game Mode(Team Deathmatch)); + Create Dummy Bot(Hero(Torbjörn), Team 1, 15, Global.circleCenter + Vector(Random Integer(-10, 10), 8, Random Integer(-10, 10)), + Vector(0, 0, 0)); + Create Dummy Bot(Hero(Torbjörn), Team 1, 16, Global.circleCenter + Vector(Random Integer(-10, 10), 8, Random Integer(-10, 10)), + Vector(0, 0, 0)); + Create Dummy Bot(Hero(Torbjörn), Team 2, 17, Global.circleCenter + Vector(Random Integer(-10, 10), 8, Random Integer(-10, 10)), + Vector(0, 0, 0)); + Create Dummy Bot(Hero(Torbjörn), Team 2, 18, Global.circleCenter + Vector(Random Integer(-10, 10), 8, Random Integer(-10, 10)), + Vector(0, 0, 0)); + End; + Global.stressTorbs = Remove From Array(Players On Hero(Hero(Torbjörn), All Teams), Global.ballPlayer); + Start Forcing Dummy Bot Name(Global.stressTorbs, Custom String("Stress Relief Torb")); + Set Primary Fire Enabled(All Players(All Teams), True); + Set Secondary Fire Enabled(All Players(All Teams), True); + Wait(1, Ignore Condition); + Big Message(All Players(All Teams), Custom String("Weapons activated")); + Wait(2, Ignore Condition); + Small Message(All Players(All Teams), Custom String("Press {0} to pick up a torb", Input Binding String(Button(Reload)))); + Wait(2, Ignore Condition); + Small Message(All Players(All Teams), Custom String("Press {0} again to yeet them!", Input Binding String(Button(Reload)))); + Wait Until(Global.ballSpawnCountdown <= 10, 9999); + Global.breakInProgress = False; + If(Current Game Mode == Game Mode(Deathmatch)); + Destroy Dummy Bot(All Teams, Slot Of(First Of(Global.stressTorbs))); + Destroy Dummy Bot(All Teams, Slot Of(Global.stressTorbs[1])); + Destroy Dummy Bot(All Teams, Slot Of(Global.stressTorbs[2])); + Else If(Current Game Mode == Game Mode(Team Deathmatch)); + Destroy Dummy Bot(Team 1, Slot Of(First Of(Global.stressTorbs))); + Destroy Dummy Bot(Team 1, Slot Of(Global.stressTorbs[1])); + Destroy Dummy Bot(Team 2, Slot Of(Global.stressTorbs[2])); + Destroy Dummy Bot(Team 2, Slot Of(Global.stressTorbs[3])); + End; + Set Primary Fire Enabled(All Players(All Teams), False); + Set Secondary Fire Enabled(All Players(All Teams), False); + Disable Built-In Game Mode Announcer; + } +} + +rule("Stress relief Torbs join") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Global.tournamentMode != False; + Array Contains(Global.stressTorbs, Event Player) == True; + } + + actions + { + Wait(0.500, Ignore Condition); + Enable Built-In Game Mode Respawning(Event Player); + Set Respawn Max Time(Event Player, 5); + Clear Status(Event Player, Invincible); + Set Status(Event Player, Null, Unkillable, 9999); + "eventPlayer.startFacing(directionTowards(eventPlayer.getEyePosition(), sorted([player for player in getLivingPlayers(Team.ALL) if player.getCurrentHero() == playerHero]).getEyePosition()), 200, Relativity.TO_WORLD, FacingReeval.DIRECTION_AND_TURN_RATE)" + Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(First Of(Sorted Array(Players On Hero( + Global.playerHero, All Teams), Distance Between(Event Player, Current Array Element))))), 500, To World, + Direction and Turn Rate); + Wait(Random Real(1, 2), Ignore Condition); + Communicate(Event Player, No); + } +} + +rule("Torb must die") +{ + event + { + Ongoing - Each Player; + All; + Torbjörn; + } + + conditions + { + Health(Event Player) == 1; + } + + actions + { + If(Random Integer(1, 4) == 1); + If(Random Integer(0, 1)); + If(True); + Skip(Array(4, 0, 2)[1 + Index Of Array Value(Array(1, 2), Random Integer(1, 2))]); + Apply Impulse(Event Player, Up, 75, To World, Cancel Contrary Motion); + Else; + Apply Impulse(Event Player, Direction Towards(Eye Position(Event Player), Vector(X Component Of(Global.circleCenter), + Y Component Of(Global.circleCenter) + 4, Z Component Of(Global.circleCenter))), 75, To World, Cancel Contrary Motion); + Else; + End; + End; + Communicate(Event Player, Goodbye); + Wait(Random Real(0.016, 0.500), Ignore Condition); + Else; + Wait(0.016, Ignore Condition); + End; + Detach Players(Event Player); + Clear Status(Event Player, Unkillable); + Kill(Event Player, Null); + Set Status(Event Player, Null, Unkillable, 9999); + Wait Until(Is Alive(Event Player), 9999); + Teleport(Event Player, Vector(Random Integer(-10, 10), 8, Random Integer(-10, 10))); + Wait(0.250, Ignore Condition); + Communicate(Event Player, Hello); + } +} + +rule("Yeet Stress relief Torb") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Global.breakInProgress != False; + Distance Between(Event Player, Position Of(First Of(Sorted Array(Filtered Array(Players On Hero(Hero(Torbjörn), All Teams), + Array Contains(Global.stressTorbs, Current Array Element) && Is Alive(Current Array Element)), Distance Between(Event Player, + Current Array Element))))) <= 2; + Is Button Held(Event Player, Button(Reload)) == True; + } + + actions + { + Event Player.yeetPlayer = First Of(Sorted Array(Filtered Array(Players On Hero(Hero(Torbjörn), All Teams), Array Contains( + Global.stressTorbs, Current Array Element) && Is Alive(Current Array Element)), Distance Between(Event Player, + Current Array Element))); + Attach Players(Event Player.yeetPlayer, Event Player, Vector(0, 0.500, 1)); + Communicate(Event Player.yeetPlayer, Hello); + Wait(0.500, Ignore Condition); + Wait Until(Is Button Held(Event Player, Button(Reload)) || !Global.breakInProgress, 9999); + Set Status(Event Player.yeetPlayer, Null, Knocked Down, 4); + Detach Players(Event Player.yeetPlayer); + Apply Impulse(Event Player.yeetPlayer, Direction Towards(Position Of(Event Player), Eye Position(Event Player) + + Facing Direction Of(Event Player) * 20), 25, To World, Cancel Contrary Motion); + Wait(1, Ignore Condition); + Event Player.yeetPlayer = Null; + } +} + +rule("Get knocked down by yeeted Torb") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Global.breakInProgress != False; + "Only knock the player down if the stress torb is in the air (hopefully only when getting yeeted)" + Is In Air(First Of(Sorted Array(Filtered Array(Players On Hero(Hero(Torbjörn), All Teams), Array Contains(Global.stressTorbs, + Current Array Element) && Is Alive(Current Array Element)), Distance Between(Eye Position(Event Player), + Current Array Element)))) == True; + Has Status(First Of(Sorted Array(Filtered Array(Players On Hero(Hero(Torbjörn), All Teams), Array Contains(Global.stressTorbs, + Current Array Element) && Is Alive(Current Array Element)), Distance Between(Eye Position(Event Player), + Current Array Element))), Knocked Down) == True; + "Chceck for the nearest stress torb" + Distance Between(Event Player, Position Of(First Of(Sorted Array(Filtered Array(Players On Hero(Hero(Torbjörn), All Teams), + Array Contains(Global.stressTorbs, Current Array Element) && Is Alive(Current Array Element)), Distance Between(Eye Position( + Event Player), Current Array Element))))) <= 1.500; + First Of(Sorted Array(Filtered Array(Players On Hero(Hero(Torbjörn), All Teams), Array Contains(Global.stressTorbs, + Current Array Element) && Is Alive(Current Array Element)), Distance Between(Eye Position(Event Player), + Current Array Element))) != Event Player.yeetPlayer; + } + + actions + { + If(Global.target.stunCooldown == 0); + Set Status(Event Player, Null, Knocked Down, 1.500); + Global.target.stunCooldown = 0.500; + } +} + +rule("Enable Scoreboard") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Is Button Held(Event Player, Button(Interact)) == True; + Event Player.toggleHUD == True; + } + + actions + { + Disable Game Mode HUD(Event Player); + Wait Until(!Is Button Held(Event Player, Button(Interact)), 10); + Event Player.toggleHUD = False; + } +} + +rule("Disable Scoreboard") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Is Button Held(Event Player, Button(Interact)) == True; + Event Player.toggleHUD == False; + } + + actions + { + Enable Game Mode HUD(Event Player); + Wait Until(!Is Button Held(Event Player, Button(Interact)), 10); + Event Player.toggleHUD = True; + } +} + +rule("Create hero ball") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.ballHero != Null; + } + + actions + { + "getAllPlayers().startFacing(directionTowards([getAllPlayers() player in player], getPlayersOnHero(ballHero)), 1000, Relativity.TO_WORLD, FacingReeval.NONE)" + Create Dummy Bot(Global.ballHero, All Teams, 14, Global.circleCenter, Vector(0, 0, 0)); + Wait Until(Has Spawned(Host Player), 9999); + Start Facing(Players On Hero(Global.ballHero, All Teams), Direction Towards(Eye Position(Players On Hero(Global.ballHero, + All Teams)), Eye Position(Host Player)), 1000, To World, Direction and Turn Rate); + Global.ballPlayer = First Of(Players On Hero(Global.ballHero, All Teams)); + If(Global.ballHero == Hero(Torbjörn)); + If(True); + Skip(Array(42, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40)[1 + Index Of Array Value(Array(1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), Random Integer(1, 21))]); + Global.startingText = Custom String("People always underestimate the engineers!"); + Else; + Global.startingText = Custom String("I'm giving it all I've got!"); + Else; + Global.startingText = Custom String("I'd rather be the hammer, than the nail."); + Else; + Global.startingText = Custom String("My baby!"); + Else; + Global.startingText = Custom String("Build 'em up, break 'em down!"); + Else; + Global.startingText = Custom String("Heh, time to roll up my sleeves!"); + Else; + Global.startingText = Custom String("Time to get my hands dirty."); + Else; + Global.startingText = Custom String("Torbjörn! Ready to work!"); + Else; + Global.startingText = Custom String("You're making a chicken out of a feather."); + Else; + Global.startingText = Custom String("Du gör en höna av en fjäder."); + Else; + Global.startingText = Custom String("Fastna inte med skägget i brevlådan."); + Else; + Global.startingText = Custom String("Köp inte grisen i säcken."); + Else; + Global.startingText = Custom String("De är som en katt som går runt het gröt!"); + Else; + Global.startingText = Custom String("Too hot for you?"); + Else; + Global.startingText = Custom String("Bingo!"); + Else; + Global.startingText = Custom String("For the last time, I'm Swedish!"); + Else; + Global.startingText = Custom String("Ha ha! There's more where that came from."); + Else; + Global.startingText = Custom String("Tehh... Poor craftsmen blames their tools..."); + Else; + Global.startingText = Custom String("Just start hammering."); + Else; + Global.startingText = Custom String("I smell trouble brewing"); + Else; + Global.startingText = Custom String("There's no prize for coming in second"); + Else; + End; + Else; + Global.startingText = Custom String("Wait... I'm ") + Global.ballHero + Custom String("? What did you do ") + + Host Player + Custom String("?"); + End; + Create In-World Text(All Players(All Teams), Global.startingText, Eye Position(Global.ballPlayer) + Vector(0, 0.500, 0), 5, + Clip Against Surfaces, Visible To and Position, Color(Orange), Visible Always); + Global.ballHeroRegretText = Last Text ID; + } +} + +rule("Init hero ball") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.ballHero != False; + Is Game In Progress == True; + } + + actions + { + Destroy In-World Text(Global.ballHeroRegretText); + Stop Facing(Global.ballPlayer); + Set Gravity(Global.ballPlayer, 0); + Disable Movement Collision With Players(Global.ballPlayer); + "ballPlayer.startForcingPosition(updateEveryTick(ballPosition) + vect(0, -1, 0) , true)" + Wait(0.500, Ignore Condition); + Start Facing(Global.ballPlayer, Direction Towards(Eye Position(Global.ballPlayer), Eye Position(Global.target)), 1000, To World, + Direction and Turn Rate); + } +} + +rule("Teleport hero ball") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.ballHero != False; + Is Game In Progress == True; + Global.ballPlayerMock == False; + } + + actions + { + Teleport(Global.ballPlayer, Global.ballPosition - Vector(0, 1, 0)); + Wait(0.001, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Don't move while ball isn't in play") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.ballHero != False; + Is Game In Progress == True; + Global.ballPlayerMock != False; + } + + actions + { + Set Gravity(Global.ballPlayer, 100); + Wait Until(!Global.ballPlayerMock, 9999); + If(!Has Status(Global.ballPlayer, Frozen)); + Start Facing(Global.ballPlayer, Direction Towards(Eye Position(Global.ballPlayer), Eye Position(Global.target)), 1000, To World, + Direction and Turn Rate); + End; + Set Gravity(Global.ballPlayer, 0); + } +} + +rule("Set hero ball outline") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.ballHero != False; + Is Game In Progress == True; + } + + actions + { + Start Forcing Player Outlines(Global.ballPlayer, Remove From Array(All Players(All Teams), Global.target), True, Color(White), + Default); + Start Forcing Player Outlines(Global.ballPlayer, Filtered Array(All Players(All Teams), Current Array Element == Global.target), + True, Color(Red), Default); + Wait(0.100, Ignore Condition); + Loop; + } +} + +rule("Don't look around while frozen") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.ballHero != False; + Is Game In Progress == True; + Has Status(Global.ballPlayer, Frozen) == True; + } + + actions + { + Stop Facing(Global.ballPlayer); + } +} + +rule("Hero ball do funny thing") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.ballHero != False; + Global.ballPlayerMock == True; + } + + actions + { + If(Random Integer(0, 100) <= 80); + If(Random Integer(0, 1)); + Communicate(Global.ballPlayer, Sorry); + Else; + Communicate(Global.ballPlayer, You are Welcome); + End; + End; + If(Global.wasFinalDuel || Number Of Heroes(Global.playerHero, All Teams) <= 2); + Global.wasFinalDuel = False; + If(!Has Status(Global.ballPlayer, Frozen)); + Call Subroutine(LongFun); + End; + Else If(!Global.isInFinalDuel); + If(!Has Status(Global.ballPlayer, Frozen)); + Call Subroutine(ShortFun); + End; + Else; + Global.wasFinalDuel = True; + Apply Impulse(Global.ballPlayer, Up, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Backward, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Forward, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Right, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Left, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Down, 0.001, To World, Cancel Contrary Motion); + Teleport(Global.ballPlayer, Global.circleCenter + Vector(0, 5, 0)); + If(!Has Status(Global.ballPlayer, Frozen)); + Start Facing(Global.ballPlayer, Direction Towards(Eye Position(Global.ballPlayer), Eye Position(Global.target)), 500, To World, + Direction and Turn Rate); + End; + End; + Wait Until(!Global.ballPlayerMock, 9999); + "do a funny thing maybe." + Global.ballHeroRandom = Random Integer(0, 100); + If(Global.ballHeroRandom <= 3); + Set Status(Global.ballPlayer, Null, Frozen, Random Integer(10, 60)); + Else If(Global.ballHeroRandom >= 5 && Global.ballHeroRandom <= 8); + Set Status(Global.ballPlayer, Null, Burning, Random Integer(10, 60)); + Else If(Global.ballHeroRandom >= 10 && Global.ballHeroRandom <= 13); + Set Status(Global.ballPlayer, Null, Hacked, Random Integer(10, 30)); + End; + If(Random Integer(0, 100) <= 10); + Communicate(Global.ballPlayer, Hello); + End; + If(Random Integer(0, 100) <= 5); + Press Button(Global.ballPlayer, Button(Ability 2)); + End; + If(Random Integer(0, 100) <= 5); + Start Modifying Hero Voice Lines(Global.ballPlayer, Random Real(0, 2), False); + Else; + Start Modifying Hero Voice Lines(Global.ballPlayer, 1, False); + } +} + +rule("Hero ball do a long super fun thing") +{ + event + { + Subroutine; + LongFun; + } + + actions + { + Global.ballHeroRandom = Random Integer(0, 100); + "Have an 8.3% chance of doing a fun thing for each player, up to 45%, minus torb" + Abort If(Random Integer(0, 100) >= Min(Number Of Players(All Teams) * 9.500 - 9.500, 60)); + If(True); + Skip(Array(171, 0, 11, 21, 27, 39, 58, 74, 97, 115, 142, 159)[1 + Index Of Array Value(Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), + Random Integer(1, 11))]); + "I think this one is easily my favorite." + Set Facing(Global.ballPlayer, Vector(0, 0, 0), To Player); + Start Facing(Global.ballPlayer, Facing Direction Of(Global.ballPlayer) + Left, 1000, To Player, Direction and Turn Rate); + Wait(1.500, Ignore Condition); + Create In-World Text(All Players(All Teams), Custom String("Torbcopter, ready for takeoff."), Position Of(Global.ballPlayer), 2, + Clip Against Surfaces, Visible To, Color(Orange), Visible Always); + Global.ballHeroRegretText = Last Text ID; + While(Global.ballPlayerMock); + Apply Impulse(Global.ballPlayer, Up, 5.500, To World, Incorporate Contrary Motion); + Wait Until(!Global.ballPlayerMock, 0.250); + End; + Destroy In-World Text(Global.ballHeroRegretText); + Else; + "Hammer their dead body" + Wait(0.500, Ignore Condition); + Communicate(Global.ballPlayer, No); + Set Weapon(Global.ballPlayer, 2); + Press Button(Global.ballPlayer, Button(Ability 1)); + Start Holding Button(Global.ballPlayer, Button(Primary Fire)); + Wait Until(!Global.ballPlayerMock, 9999); + Stop Holding Button(Global.ballPlayer, Button(Primary Fire)); + Set Weapon(Global.ballPlayer, Random Integer(0, 1)); + Press Button(Global.ballPlayer, Button(Interact)); + Else; + "That was so boring that Torb is going to take a nap" + Set Status(Global.ballPlayer, Null, Asleep, 9999); + Wait(0.500, Ignore Condition); + Communicate(Global.ballPlayer, Goodbye); + Wait Until(!Global.ballPlayerMock, 9999); + Clear Status(Global.ballPlayer, Asleep); + Else; + Wait(2.250, Ignore Condition); + Set Gravity(Global.ballPlayer, 0); + Start Forcing Player Position(Global.ballPlayer, Eye Position(Global.target) + Vector(0, 1, 0), True); + Set Facing(Global.ballPlayer, Vector(0, -1, 0), To Player); + Create In-World Text(All Players(All Teams), Custom String("{0} is next, don't tell them :)", Global.target), Eye Position( + Global.ballPlayer) + Vector(0, 0.500, 0), 3, Clip Against Surfaces, Visible To Position and String, Color(Orange), + Visible Always); + Global.ballHeroRegretText = Last Text ID; + Wait(0.500, Ignore Condition); + Communicate(Global.ballPlayer, Hello); + Wait Until(!Global.ballPlayerMock, 9999); + Destroy In-World Text(Global.ballHeroRegretText); + Stop Forcing Player Position(Global.ballPlayer); + Else; + Set Ultimate Charge(Global.ballPlayer, 100); + Start Holding Button(Global.ballPlayer, Button(Ultimate)); + Set Gravity(Global.ballPlayer, 0); + Apply Impulse(Global.ballPlayer, Up, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Backward, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Forward, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Right, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Left, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Down, 0.001, To World, Cancel Contrary Motion); + Teleport(Global.ballPlayer, Global.circleCenter + Vector(0, 5, 0)); + Wait(1, Ignore Condition); + While(Is Using Ultimate(Global.ballPlayer) && Global.ballPlayerMock); + Set Facing(Global.ballPlayer, Direction Towards(Eye Position(Global.ballPlayer), Vector(Random Real(-20, 20), Random Real(0, 5), + Random Real(-20, 20))), To World); + Wait(0.050, Ignore Condition); + Stop Holding Button(Global.ballPlayer, Button(Ultimate)); + Press Button(Global.ballPlayer, Button(Primary Fire)); + End; + Start Facing(Global.ballPlayer, Facing Direction Of(Global.ballPlayer) + Left, 500, To Player, Direction and Turn Rate); + Else; + "Torb got a case of the zoomies." + Set Move Speed(Global.ballPlayer, 500); + Global.ballHeroRandom = Vector(Random Real(-18, 18), 1, Random Real(-18, 18)); + Start Throttle In Direction(Global.ballPlayer, Direction Towards(Position Of(Global.ballPlayer), Global.ballHeroRandom), 1, + To World, Replace existing throttle, Direction and Magnitude); + Start Facing(Global.ballPlayer, Direction Towards(Eye Position(Global.ballPlayer), Global.ballHeroRandom), 1000, To World, + Direction and Turn Rate); + Create In-World Text(All Players(All Teams), Custom String("Zip zoom"), Update Every Frame(Eye Position(Global.ballPlayer)) + + Vector(0, 1, 0), 2, Clip Against Surfaces, Visible To and Position, Color(Orange), Visible Always); + Global.ballHeroRegretText = Last Text ID; + While(Global.ballPlayerMock); + If(Distance Between(Position Of(Global.ballPlayer), Global.ballHeroRandom) < 2); + Global.ballHeroRandom = Vector(Random Real(-18, 18), 1, Random Real(-18, 18)); + End; + Wait(0.100, Ignore Condition); + End; + Destroy In-World Text(Global.ballHeroRegretText); + Stop Throttle In Direction(Global.ballPlayer); + Set Move Speed(Global.ballPlayer, 100); + Else; + "nice" + If(Global.ballHeroRandom == 69); + "HYPER TBAG!" + Set Weapon(Global.ballPlayer, 2); + While(Global.ballPlayerMock == True); + Communicate(Global.ballPlayer, Yes); + Wait(0.050, Ignore Condition); + Start Holding Button(Global.ballPlayer, Button(Crouch)); + Wait(0.050, Ignore Condition); + Stop Holding Button(Global.ballPlayer, Button(Crouch)); + End; + Else; + "Tbag them" + Communicate(Global.ballPlayer, Yes); + Set Weapon(Global.ballPlayer, 2); + Start Holding Button(Global.ballPlayer, Button(Primary Fire)); + While(Global.ballPlayerMock == True); + Wait(0.100, Ignore Condition); + Start Holding Button(Global.ballPlayer, Button(Crouch)); + Wait(0.100, Ignore Condition); + Stop Holding Button(Global.ballPlayer, Button(Crouch)); + End; + Stop Holding Button(Global.ballPlayer, Button(Primary Fire)); + Set Weapon(Global.ballPlayer, Random Integer(0, 1)); + End; + Else; + "Torb thinks one Genji in specific is broken." + Wait(1, Ignore Condition); + Global.ballHeroRandom = Random Value In Array(Players On Hero(Global.playerHero, All Teams)); + Enable Movement Collision With Players(Global.ballPlayer); + Set Move Speed(Global.ballPlayer, 150); + Start Throttle In Direction(Global.ballPlayer, Direction Towards(Position Of(Global.ballPlayer), Position Of( + Global.ballHeroRandom)), 1, To World, Replace existing throttle, Direction and Magnitude); + Start Facing(Global.ballPlayer, Direction Towards(Eye Position(Global.ballPlayer), Eye Position(Global.ballHeroRandom)), 500, + To World, Direction and Turn Rate); + Set Weapon(Global.ballPlayer, 2); + Start Holding Button(Global.ballPlayer, Button(Primary Fire)); + Create In-World Text(All Players(All Teams), Custom String("Come here {0}, I'll fix you right up!", Global.ballHeroRandom), + Eye Position(Global.ballPlayer) + Vector(0, 1, 0), 2, Clip Against Surfaces, Visible To and Position, Color(Orange), + Visible Always); + Global.ballHeroRegretText = Last Text ID; + Wait Until(!Global.ballPlayerMock, 9999); + Disable Movement Collision With Players(Global.ballPlayer); + Stop Throttle In Direction(Global.ballPlayer); + Set Move Speed(Global.ballPlayer, 100); + Stop Holding Button(Global.ballPlayer, Button(Primary Fire)); + Set Weapon(Global.ballPlayer, Random Integer(0, 1)); + Destroy In-World Text(Global.ballHeroRegretText); + Else; + Apply Impulse(Global.ballPlayer, Up, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Backward, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Forward, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Right, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Left, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Down, 0.001, To World, Cancel Contrary Motion); + Teleport(Global.ballPlayer, Global.circleCenter + Vector(0, 5, 0)); + Stop Facing(Global.ballPlayer); + Global.ballHeroRandom = 0; + Chase Global Variable Over Time(ballHeroRandom, 2, 7.500, None); + "Pretty sure this variable literally does nothing, I added this when I started develpoment and couldn't even get it to work..." + Global.ballPlayer.currentUltPercent = 4; + Chase Player Variable Over Time(Global.ballPlayer, currentUltPercent, 0, 7.500, None); + Global.ballHeroRegretText = 0.750; + Start Scaling Player(Global.ballPlayer, Global.ballPlayer.currentUltPercent, True); + Start Modifying Hero Voice Lines(Global.ballPlayer, Global.ballHeroRandom, True); + Global.ballHeroRegretText = 0.750; + Chase Global Variable Over Time(ballHeroRegretText, 0.050, 15, None); + While(Global.ballPlayerMock); + Set Facing(Global.ballPlayer, Direction Towards(Eye Position(Global.ballPlayer), Eye Position(Random Value In Array( + Players On Hero(Global.playerHero, All Teams)))), To World); + Communicate(Global.ballPlayer, Hello); + Wait Until(!Global.ballPlayerMock, Global.ballHeroRegretText); + End; + Start Scaling Player(Global.ballPlayer, 1, False); + Stop Chasing Global Variable(ballHeroRandom); + Stop Chasing Global Variable(ballHeroRegretText); + Stop Chasing Player Variable(Global.ballPlayer, currentUltPercent); + Else; + "Get the chance to let your anger out and yeet torb." + Wait(0.250, Ignore Condition); + Global.ballHeroRandom = Global.target; + Communicate(Global.ballPlayer, No); + Set Gravity(Global.ballPlayer, 0); + Start Forcing Player Position(Global.ballPlayer, Update Every Frame(Eye Position(Global.ballHeroRandom)) + Vector(0, -1.100, 0) + + Facing Direction Of(Global.ballHeroRandom) * 2, True); + Start Facing(Global.ballPlayer, Direction Towards(Eye Position(Global.ballPlayer), Eye Position(Global.ballHeroRandom)), 1000, + To World, Direction and Turn Rate); + Create In-World Text(Global.ballHeroRandom, Custom String("Press reload to yeet {0}", Global.ballHero), Update Every Frame( + Eye Position(Global.ballHeroRandom)) + Vector(0, -0.060, 0) + Facing Direction Of(Global.ballHeroRandom) * 0.500, 2.500, + Clip Against Surfaces, Visible To and Position, Color(Orange), Visible Always); + Wait Until(Is Button Held(Global.ballHeroRandom, Button(Reload)) || !Global.ballPlayerMock, 5); + Set Gravity(Global.ballPlayer, 100); + Destroy In-World Text(Last Text ID); + Stop Forcing Player Position(Global.ballPlayer); + Stop Facing(Global.ballPlayer); + Set Status(Global.ballPlayer, Null, Knocked Down, 9999); + Apply Impulse(Global.ballPlayer, Direction Towards(Position Of(Global.ballPlayer), Eye Position(Global.ballHeroRandom) + + Facing Direction Of(Global.ballHeroRandom) * 20), 75, To World, Cancel Contrary Motion); + Wait Until(!Global.ballPlayerMock, 4); + Clear Status(Global.ballPlayer, Knocked Down); + Else; + Wait(0.016, Ignore Condition); + Set Gravity(Global.ballPlayer, 100); + Apply Impulse(Global.ballPlayer, Up, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Backward, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Forward, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Right, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Left, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Down, 0.001, To World, Cancel Contrary Motion); + Teleport(Global.ballPlayer, Global.circleCenter + Vector(0, 5, 0)); + Start Facing(Global.ballPlayer, Direction Towards(Eye Position(Global.ballPlayer), Eye Position(Global.target)), 1000, To World, + Direction and Turn Rate); + Communicate(Global.ballPlayer, Hello); + Else; + End; + } +} + +rule("Hero ball do a quick fun thing") +{ + event + { + Subroutine; + ShortFun; + } + + actions + { + "Only have a 45% chance of doing a fun thing" + Abort If(Random Integer(1, 100) > 45); + Global.ballHeroRandom = Random Integer(0, 100); + If(True); + Skip(Array(123, 0, 24, 33, 39, 46, 58, 61, 72, 86, 96, 106)[1 + Index Of Array Value(Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), + Random Integer(1, 11))]); + "nice" + If(Global.ballHeroRandom == 69); + Global.ballSpawnCountdown = 5; + "HYPER TBAG!" + Set Weapon(Global.ballPlayer, 2); + While(Global.ballPlayerMock == True); + Communicate(Global.ballPlayer, Yes); + Wait(0.050, Ignore Condition); + Start Holding Button(Global.ballPlayer, Button(Crouch)); + Wait(0.050, Ignore Condition); + Stop Holding Button(Global.ballPlayer, Button(Crouch)); + End; + Else; + "Tbag them" + Communicate(Global.ballPlayer, Yes); + Set Weapon(Global.ballPlayer, 2); + Start Holding Button(Global.ballPlayer, Button(Primary Fire)); + While(Global.ballPlayerMock == True); + Wait(0.100, Ignore Condition); + Start Holding Button(Global.ballPlayer, Button(Crouch)); + Wait(0.100, Ignore Condition); + Stop Holding Button(Global.ballPlayer, Button(Crouch)); + End; + Stop Holding Button(Global.ballPlayer, Button(Primary Fire)); + Set Weapon(Global.ballPlayer, Random Integer(0, 1)); + End; + Else; + "Hammer their dead body" + Wait(0.500, Ignore Condition); + Communicate(Global.ballPlayer, No); + Set Weapon(Global.ballPlayer, 2); + Start Holding Button(Global.ballPlayer, Button(Primary Fire)); + Wait Until(!Global.ballPlayerMock, 9999); + Stop Holding Button(Global.ballPlayer, Button(Primary Fire)); + Set Weapon(Global.ballPlayer, Random Integer(0, 1)); + Press Button(Global.ballPlayer, Button(Interact)); + Else; + "That was so boring Torb is going to take a nap" + Set Status(Global.ballPlayer, Null, Asleep, 9999); + Wait(0.500, Ignore Condition); + Communicate(Global.ballPlayer, Goodbye); + Wait Until(!Global.ballPlayerMock, 9999); + Clear Status(Global.ballPlayer, Asleep); + Else; + "Torb is not joking around." + Start Facing(Global.ballPlayer, Direction Towards(Eye Position(Global.ballPlayer), Eye Position(Global.target)), 1000, To World, + Direction and Turn Rate); + Wait Until(Global.target != Custom String("-1"), 9999); + Create In-World Text(All Players(All Teams), Custom String("You're next, {0}.", Global.target), Eye Position(Global.ballPlayer) + + Vector(0, 0.500, 0), 3, Clip Against Surfaces, Visible To Position and String, Color(Red), Visible Always); + Global.ballHeroRegretText = Last Text ID; + Wait Until(!Global.ballPlayerMock, 9999); + Destroy In-World Text(Global.ballHeroRegretText); + Else; + Wait Until(Global.target != Custom String("-1"), 10); + Set Gravity(Global.ballPlayer, 0); + Start Forcing Player Position(Global.ballPlayer, Eye Position(Global.target) + Vector(0, 1, 0), True); + Set Facing(Global.ballPlayer, Vector(0, -1, 0), To Player); + Create In-World Text(All Players(All Teams), Custom String("{0} is next, don't tell them :)", Global.target), Eye Position( + Global.ballPlayer) + Vector(0, 0.500, 0), 3, Clip Against Surfaces, Visible To Position and String, Color(Sky Blue), + Visible Always); + Global.ballHeroRegretText = Last Text ID; + Wait(0.500, Ignore Condition); + Communicate(Global.ballPlayer, Hello); + Wait Until(!Global.ballPlayerMock, 9999); + Destroy In-World Text(Global.ballHeroRegretText); + Stop Forcing Player Position(Global.ballPlayer); + Else; + "SPEEN" + Set Facing(Global.ballPlayer, Vector(0, 0, 0), To Player); + Start Facing(Global.ballPlayer, Facing Direction Of(Global.ballPlayer) + Left, 500, To Player, Direction and Turn Rate); + Else; + "To the person who keeps telling me to remove the center orb." + Start Forcing Player Position(Global.ballPlayer, Global.circleCenter + Vector(Random Real(-1 * Global.CenterOffLimitsSize + 0.750, + Global.CenterOffLimitsSize - 0.750), -1 * Y Component Of(Global.circleCenter), Random Real(-1 * Global.CenterOffLimitsSize + 1, + Global.CenterOffLimitsSize - 1)), True); + Start Facing(Global.ballPlayer, Direction Towards(Eye Position(Global.ballPlayer), Eye Position(Global.target)), 1000, To World, + Direction and Turn Rate); + Wait(0.016, Ignore Condition); + Create In-World Text(All Players(All Teams), Custom String("Jealous that I can be in here and you can't? :)"), Eye Position( + Global.ballPlayer) + Vector(0, 0.500, 0), 2.500, Clip Against Surfaces, Visible To, Color(Orange), Visible Always); + Global.ballHeroRegretText = Last Text ID; + Wait(0.500, Ignore Condition); + Communicate(Global.ballPlayer, Hello); + Wait Until(!Global.ballPlayerMock, 9999); + Destroy In-World Text(Global.ballHeroRegretText); + Stop Forcing Player Position(Global.ballPlayer); + Else; + Wait(0.016, Ignore Condition); + Global.ballHeroRandom = Position Of(Global.ballPlayer); + Chase Global Variable At Rate(ballHeroRandom, Eye Position(Global.target), 20, Destination and Rate); + Create Effect(All Players(All Teams), Orb, Color(Red), Global.ballHeroRandom, 1, Visible To Position and Radius); + Global.ballHeroRegretText = Last Created Entity; + Start Facing(Global.ballPlayer, Direction Towards(Eye Position(Global.ballPlayer), Eye Position(Global.target)), 500, To World, + Direction and Turn Rate); + Create In-World Text(All Players(All Teams), Custom String("Think fast!"), Global.ballHeroRandom + Vector(0, 0.500, 0), 2.500, + Clip Against Surfaces, Visible To and Position, Color(Orange), Visible Always); + Wait Until(Distance Between(Global.ballHeroRandom, Eye Position(Global.target)) < 1.900 || !Global.ballPlayerMock, 9999); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Sky Blue), Global.ballHeroRandom, 40); + Play Effect(All Players(All Teams), Good Explosion, Color(White), Global.ballHeroRandom, 2); + Destroy Effect(Global.ballHeroRegretText); + Destroy In-World Text(Last Text ID); + Stop Chasing Global Variable(ballHeroRandom); + Else; + "Torb horror game." + Wait(0.016, Ignore Condition); + Global.ballHeroRandom = Random Value In Array(Filtered Array(All Living Players(All Teams), Hero Of(Current Array Element) + != Global.ballHero)); + Set Gravity(Global.ballPlayer, 0); + Start Forcing Player Position(Global.ballPlayer, Update Every Frame(Eye Position(Global.ballHeroRandom)) + Vector(0, -1.100, 0) + + Facing Direction Of(Global.ballHeroRandom) * 0.750, True); + Start Facing(Global.ballPlayer, Direction Towards(Eye Position(Global.ballPlayer), Eye Position(Global.ballHeroRandom)), 1000, + To World, Direction and Turn Rate); + Create In-World Text(All Players(All Teams), Custom String("Boo!"), Eye Position(Global.ballPlayer) + Vector(0, 0.500, 0), 2.500, + Clip Against Surfaces, Visible To and Position, Color(Orange), Visible Always); + Wait Until(!Global.ballPlayerMock, 9999); + Stop Forcing Player Position(Global.ballPlayer); + Destroy In-World Text(Last Text ID); + Else; + Apply Impulse(Global.ballPlayer, Up, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Backward, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Forward, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Right, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Left, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Global.ballPlayer, Down, 0.001, To World, Cancel Contrary Motion); + Teleport(Global.ballPlayer, Global.circleCenter + Vector(0, 5, 0)); + Start Facing(Global.ballPlayer, Direction Towards(Eye Position(Global.ballPlayer), Eye Position(Global.target)), 1000, To World, + Direction and Turn Rate); + Communicate(Global.ballPlayer, Hello); + Else; + Wait(0.016, Ignore Condition); + Global.ballHeroRandom = 1; + Global.ballHeroRegretText = 1; + Start Scaling Player(Global.ballPlayer, Global.ballHeroRandom, True); + Start Modifying Hero Voice Lines(Global.ballPlayer, Global.ballHeroRegretText, True); + Chase Global Variable Over Time(ballHeroRandom, 0, 1.500, None); + Chase Global Variable Over Time(ballHeroRegretText, 2, 1, None); + Communicate(Global.ballPlayer, Goodbye); + Wait(1.500, Ignore Condition); + Set Invisible(Global.ballPlayer, All); + Wait Until(!Global.ballPlayerMock, 9999); + Stop Chasing Global Variable(ballHeroRandom); + Stop Chasing Global Variable(ballHeroRegretText); + Set Invisible(Global.ballPlayer, None); + Stop Scaling Player(Global.ballPlayer); + Stop Modifying Hero Voice Lines(Global.ballPlayer); + Else; + End; + } +} + +rule("// Not enough players testing") +{ + event + { + Ongoing - Global; + } + + actions + { + Skip If(!Global.watermarkEnabled, 1); + Create HUD Text(All Players(All Teams), Null, Custom String("Original by {0}. Version 7.9.1", Global.name), Null, Left, -1000, + Null, Color(Aqua), Null, Visible To, Visible Always); + } +} + +rule("Check for <2 players") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Game Mode == Game Mode(Deathmatch); + Is Game In Progress == True; + Number Of Heroes(Global.playerHero, All Teams) == 1; + } + + actions + { + Global.isInFinalDuel = False; + Create HUD Text(All Players(All Teams), Custom String("Waiting for more players"), Null, Null, Top, 0, Color(White), Null, Null, + Visible To, Default Visibility); + Global.waitingForPlayersHUD = Last Text ID; + Global.isEnoughPlayersToStart = False; + Stop Chasing Global Variable(ballSpawnCountdown); + Skip If(Global.roundInProgress == False, 1); + Global.ballDeleteRequested = True; + Global.roundInProgress = False; + Global.ballPlayerMock = False; + Pause Match Time; + } +} + +rule("Check for <2 players - TEAMS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Game Mode == Game Mode(Team Deathmatch); + Is Game In Progress == True; + "@Condition getNumberOfHeroes(playerHero, Team.ALL) == 1" + (Number Of Players(Team 1) && Number Of Players(Team 2)) == False; + } + + actions + { + Global.isInFinalDuel = False; + Create HUD Text(All Players(All Teams), Custom String("Waiting for more players"), Null, Null, Top, 0, Color(White), Null, Null, + Visible To, Default Visibility); + Global.waitingForPlayersHUD = Last Text ID; + Global.isEnoughPlayersToStart = False; + Stop Chasing Global Variable(ballSpawnCountdown); + Skip If(Global.roundInProgress == False, 1); + Global.ballDeleteRequested = True; + Global.roundInProgress = False; + Pause Match Time; + } +} + +rule("Wait for more players") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Game Mode == Game Mode(Deathmatch); + Number Of Heroes(Global.playerHero, All Teams) > 1; + Global.isEnoughPlayersToStart == False; + } + + actions + { + Destroy HUD Text(Global.waitingForPlayersHUD); + Big Message(All Players(All Teams), Custom String("Starting game in 5 seconds!")); + Wait(5.500, Ignore Condition); + Abort If(Number Of Heroes(Global.playerHero, All Teams) < 2); + Unpause Match Time; + Global.isEnoughPlayersToStart = True; + Global.target = -1; + Global.previousTargetedPlayer = -1; + } +} + +rule("Wait for more players - TEAMS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Game Mode == Game Mode(Team Deathmatch); + Number Of Players(Team 1) != False; + Number Of Players(Team 2) != False; + Global.isEnoughPlayersToStart == False; + } + + actions + { + Destroy HUD Text(Global.waitingForPlayersHUD); + Big Message(All Players(All Teams), Custom String("Starting game in 5 seconds!")); + Wait(5.500, Ignore Condition); + Abort If(Number Of Heroes(Global.playerHero, All Teams) < 2); + Unpause Match Time; + Global.isEnoughPlayersToStart = True; + Global.target = -1; + Global.previousTargetedPlayer = -1; + } +} + +rule("Shorten Deflect Length") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Is Using Ability 2(Event Player) == True; + Is Using Ultimate(Event Player) == False; + } + + actions + { + Wait(0.300, Ignore Condition); + Set Ability 2 Enabled(Event Player, False); + Set Ability 1 Enabled(Event Player, False); + Wait(0.500, Ignore Condition); + Set Ability 2 Enabled(Event Player, True); + Set Ability 1 Enabled(Event Player, True); + } +} + +rule("Unlock dash after using jumppad") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Global.bouncepadDashingEnabled == True; + Event Player.isDashEnabled == True; + } + + actions + { + Set Ability 1 Enabled(Event Player, True); + } +} + +rule("Disable dash after using") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Global.bouncepadDashingEnabled == True; + Is Using Ability 1(Event Player) == True; + } + + actions + { + Set Ability 1 Enabled(Event Player, False); + Event Player.isDashEnabled = False; + } +} + +rule("Target random player") +{ + event + { + Ongoing - Global; + } + + conditions + { + Is Game In Progress == True; + Global.target == -1; + } + + actions + { + Wait(0.016, Ignore Condition); + Global.target = Random Value In Array(Filtered Array(All Living Players(All Teams), + Current Array Element.hasMoved && Current Array Element != Global.ballPlayer)); + } +} + +disabled rule("Anti-Bounce Detection Positive X") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Y Component Of(Position Of(Event Player)) < 0; + X Component Of(Position Of(Event Player)) > 20.500; + "Workshop Island Fix" + (Current Map == Map(Workshop Island) || Current Map == Map(Workshop Island Night)) == True; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + "Busted!" + Event Player.antiFloatProtection = True; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +disabled rule("Anti-Bounce Detection Netgative X") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Y Component Of(Position Of(Event Player)) < 0; + X Component Of(Position Of(Event Player)) < -20.500; + "Workshop Island Fix" + (Current Map == Map(Workshop Island) || Current Map == Map(Workshop Island Night)) == True; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + "Busted!" + Event Player.antiFloatProtection = True; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +disabled rule("Anti-Bounce Detection Positive Z") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Y Component Of(Position Of(Event Player)) < 0; + Z Component Of(Position Of(Event Player)) > 20.500; + "Workshop Island Fix" + (Current Map == Map(Workshop Island) || Current Map == Map(Workshop Island Night)) == True; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + "Busted!" + Event Player.antiFloatProtection = True; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +disabled rule("Anti-Bounce Detection Negative Z") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Y Component Of(Position Of(Event Player)) < 0; + Z Component Of(Position Of(Event Player)) < -20.500; + "Workshop Island Fix" + (Current Map == Map(Workshop Island) || Current Map == Map(Workshop Island Night)) == True; + } + + actions + { + Start Forcing Throttle(Event Player, 0, 0, 0, 0, 0, 0); + "Busted!" + Event Player.antiFloatProtection = True; + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +disabled rule("Disable Anti-Bounce") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Y Component Of(Position Of(Event Player)) >= 0; + Event Player.antiFloatProtection == True; + "Workshop Island Fix" + (Current Map == Map(Workshop Island) || Current Map == Map(Workshop Island Night)) == True; + } + + actions + { + Stop Forcing Throttle(Event Player); + Event Player.antiFloatProtection = False; + } +} + +rule("Anti-Stuck Activation") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Array Contains(Global.stressTorbs, Event Player) == False; + Y Component Of(Position Of(Event Player)) < -4; + (Current Map == Map(Workshop Island) || Current Map == Map(Workshop Island Night)) == True; + } + + actions + { + Apply Impulse(Event Player, Up, 5, To World, Cancel Contrary Motion XYZ); + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Bounce when near pad 1") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Global.bouncePad1 != Null; + Distance Between(Position Of(Event Player), Global.bouncePad1) <= Global.bouncePadRange; + Event Player.bouncePadCooldown == 0; + Is Alive(Event Player) == True; + Is Button Held(Event Player, Button(Jump)) == True; + } + + actions + { + Event Player.isDashEnabled = True; + If(Event Player.dashNerf); + Apply Impulse(Event Player, Up, Global.bouncePadStrength - Global.bouncePadSuperjumpNerf, To World, Cancel Contrary Motion); + Else; + Apply Impulse(Event Player, Up, Global.bouncePadStrength, To World, Cancel Contrary Motion); + End; + Event Player.bouncePadCooldown = Global.bouncePadCooldownLength; + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Global.bouncePad1, 25); + Event Player.playerEffects[1] = Last Created Entity; + Wait(2, Ignore Condition); + Destroy Effect(Event Player.playerEffects[1]); + } +} + +rule("Bounce when near pad 2") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Global.bouncePad2 != Null; + Distance Between(Position Of(Event Player), Global.bouncePad2) <= Global.bouncePadRange; + Event Player.bouncePadCooldown == 0; + Is Alive(Event Player) == True; + Is Button Held(Event Player, Button(Jump)) == True; + } + + actions + { + Event Player.isDashEnabled = True; + If(Event Player.dashNerf); + Apply Impulse(Event Player, Up, Global.bouncePadStrength - Global.bouncePadSuperjumpNerf, To World, Cancel Contrary Motion); + Else; + Apply Impulse(Event Player, Up, Global.bouncePadStrength, To World, Cancel Contrary Motion); + End; + Event Player.bouncePadCooldown = Global.bouncePadCooldownLength; + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Global.bouncePad1, 25); + Event Player.playerEffects[1] = Last Created Entity; + Wait(2, Ignore Condition); + Destroy Effect(Event Player.playerEffects[1]); + } +} + +rule("Bounce when near pad 3") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Global.bouncePad3 != Null; + Distance Between(Position Of(Event Player), Global.bouncePad3) <= Global.bouncePadRange; + Event Player.bouncePadCooldown == 0; + Is Alive(Event Player) == True; + Is Button Held(Event Player, Button(Jump)) == True; + } + + actions + { + Event Player.isDashEnabled = True; + If(Event Player.dashNerf); + Apply Impulse(Event Player, Up, Global.bouncePadStrength - Global.bouncePadSuperjumpNerf, To World, Cancel Contrary Motion); + Else; + Apply Impulse(Event Player, Up, Global.bouncePadStrength, To World, Cancel Contrary Motion); + End; + Event Player.bouncePadCooldown = Global.bouncePadCooldownLength; + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Global.bouncePad1, 25); + Event Player.playerEffects[1] = Last Created Entity; + Wait(2, Ignore Condition); + Destroy Effect(Event Player.playerEffects[1]); + } +} + +rule("Bounce when near pad 4") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Global.bouncePad4 != Null; + Distance Between(Position Of(Event Player), Global.bouncePad4) <= Global.bouncePadRange; + Event Player.bouncePadCooldown == 0; + Is Alive(Event Player) == True; + Is Button Held(Event Player, Button(Jump)) == True; + } + + actions + { + Event Player.isDashEnabled = True; + If(Event Player.dashNerf); + Apply Impulse(Event Player, Up, Global.bouncePadStrength - Global.bouncePadSuperjumpNerf, To World, Cancel Contrary Motion); + Else; + Apply Impulse(Event Player, Up, Global.bouncePadStrength, To World, Cancel Contrary Motion); + End; + Event Player.bouncePadCooldown = Global.bouncePadCooldownLength; + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Global.bouncePad1, 25); + Event Player.playerEffects[1] = Last Created Entity; + Wait(2, Ignore Condition); + Destroy Effect(Event Player.playerEffects[1]); + } +} + +rule("Ball delete requested") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.ballDeleteRequested == True; + } + + actions + { + Global.ballDeleteRequested = False; + Global.ballPlayerMock = True; + Global.target = -1; + Stop Chasing Global Variable(ballDirection); + Stop Chasing Global Variable(ballPosition); + Stop Chasing Global Variable(ballSpeed); + Global.ballPosition = Vector(0, -1, 0); + Global.ballDirection = Vector(0, 0, 0); + Global.ballIsOut = False; + Global.previousTargetedPlayer = -1; + Global.ballSpawnCountdown = 2; + Global.prevBallPos = Vector(0, 0, 0); + Global.prevBallPos2 = Vector(0, 0, 0); + } +} + +rule("Only end game when there isn't a round in progress") +{ + event + { + Ongoing - Global; + } + + conditions + { + Match Time == 0; + Global.roundInProgress == False; + Global.gameEndEnabled == True; + Global.tieBreakerActive == False; + } + + actions + { + Enable Built-In Game Mode Music; + Enable Built-In Game Mode Completion; + } +} + +rule("primary = dash") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Global.breakInProgress == False; + Is Button Held(Event Player, Button(Primary Fire)) == True; + Custom String("{0}", Event Player) != Custom String("bytestats"); + Hero Of(Event Player) != Global.ballHero; + } + + actions + { + Press Button(Event Player, Button(Ability 1)); + } +} + +rule("secondary = deflect") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Global.breakInProgress == False; + Is Button Held(Event Player, Button(Secondary Fire)) == True; + Custom String("{0}", Event Player) != Custom String("bytestats"); + Global.passingEnabled == False; + Hero Of(Event Player) != Global.ballHero; + } + + actions + { + Press Button(Event Player, Button(Ability 2)); + } +} + +rule("Start round") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Game Mode == Game Mode(Deathmatch); + Global.isEnoughPlayersToStart == True; + Is Game In Progress == True; + } + + actions + { + Chase Global Variable At Rate(ballSpawnCountdown, 0, 1, None); + Global.roundInProgress = True; + Global.ballPlayerMock = False; + Chase Player Variable At Rate(All Players(All Teams), bouncePadCooldown, 0, 1, None); + Global.ballSpawnCountdown = 5; + } +} + +rule("Start round - TEAMS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Game Mode == Game Mode(Team Deathmatch); + Global.isEnoughPlayersToStart == True; + Is Game In Progress == True; + } + + actions + { + Chase Global Variable At Rate(ballSpawnCountdown, 0, 1, None); + Global.roundInProgress = True; + Chase Player Variable At Rate(All Players(All Teams), bouncePadCooldown, 0, 1, None); + Global.ballSpawnCountdown = 5; + } +} + +rule("Spawn ball") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.ballSpawnCountdown == 0; + } + + actions + { + Global.ballPosition = Global.circleCenter; + Global.ballDirection = Direction Towards(Global.ballPosition, Eye Position(Global.target)); + Global.ballDirectionRate = 1.750; + Global.ballSpeed = Global.startingBallSpeed; + Global.ballPlayerMock = False; + Global.ballIsOut = True; + } +} + +rule("Modern ball motion") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.rulesetMode == 0; + Global.ballIsOut == True; + } + + actions + { + Chase Global Variable At Rate(ballPosition, Global.ballPosition + Global.ballDirection * Global.ballSpeed, Global.ballSpeed, + Destination and Rate); + Chase Global Variable At Rate(ballDirection, Direction Towards(Global.ballPosition, Eye Position(Global.target)), + Global.ballDirectionRate, Destination and Rate); + Chase Global Variable At Rate(ballSpeed, Global.maxBallSpeed, 0.250, Destination and Rate); + } +} + +rule("Retro ball motion") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.rulesetMode == 1; + Global.ballIsOut == True; + } + + actions + { + Chase Global Variable At Rate(ballPosition, Eye Position(Global.target), Global.ballSpeed, Destination and Rate); + Chase Global Variable At Rate(ballSpeed, Global.maxBallSpeed, 0.250, Destination and Rate); + } +} + +rule("Astro ball motion") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.rulesetMode == 2; + Global.ballIsOut == True; + } + + actions + { + Chase Global Variable At Rate(ballPosition, Update Every Frame(Global.ballPosition + Global.ballDirection), Update Every Frame( + Magnitude Of(Global.ballDirection)), Destination and Rate); + "ballDirection is the ball's velocity" + Chase Global Variable At Rate(ballDirection, Update Every Frame(Global.ballDirection * 0.930 + Eye Position(Global.target) + - Global.ballPosition), Update Every Frame(Square Root((Global.ballSpeed - Max(Dot Product(Global.ballDirection, + Direction Towards(Global.ballPosition, Eye Position(Global.target))), 0)) * Global.ballSpeed) * 3), Destination and Rate); + "ballSpeed is the ball's acceleration coefficient" + Chase Global Variable At Rate(ballSpeed, Global.maxBallSpeed, 0.250, Destination and Rate); + "Chase client prediction fix" + Wait(0.016, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Update ball postiion") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.ballIsOut == True; + } + + actions + { + "This is for the ball tail to be updated." + Global.prevBallPos2 = Global.prevBallPos; + Global.prevBallPos = Global.ballPosition; + Wait(0.050, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ball reaches player") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Game Mode == Game Mode(Deathmatch); + Distance Between(Global.ballPosition, Eye Position(Global.target)) <= 1.900; + Global.ballIsOut == True; + } + + actions + { + If(!(Is Using Ability 2(Global.target) || (Is Using Ability 1(Global.target) && Global.rulesetMode != 1))); + Call Subroutine(DeflectFailed); + If(Global.rulesetMode == 1); + Wait(0.016, Ignore Condition); + Loop If Condition Is True; + End; + Abort; + End; + If(Is Button Held(Global.target, Button(Secondary Fire))); + "If they don't have enough health, kill em" + If(Health(Global.target) <= 100); + Call Subroutine(DeflectFailed); + If(Global.rulesetMode == 1); + Wait(0.016, Ignore Condition); + Loop If Condition Is True; + End; + Abort; + End; + End; + If(Is Using Ability 2(Global.target)); + Set Status(Global.ballPlayer, Null, Stunned, 0.500); + Else; + Set Status(Global.ballPlayer, Null, Knocked Down, 0.500); + End; + If(Is Using Ability 1(Global.target)); + If(Global.target.stunCooldown == 0); + Set Status(Global.target, Null, Knocked Down, 1); + Global.target.stunCooldown = 0.500; + End; + Teleport(Global.target, Global.ballPosition); + End; + Global.target.currentUltPercent += 5; + Play Effect(All Players(All Teams), Explosion Sound, Color(White), Position Of(Global.target), 200); + Global.target.playerDeflects += 1; + Global.previousTargetedPlayer = Global.target; + Global.ballSpeed = Min(Global.maxBallSpeed, Global.ballSpeed * 1.050); + If(Global.ballSpeed > Global.target.maxBallSpeed); + Global.target.maxBallSpeed = Global.ballSpeed; + End; + Global.ballDirection = Facing Direction Of(Global.target) * (Global.rulesetMode == 2 ? Global.ballSpeed : 1); + Wait(0.001, Ignore Condition); + "Check if player is passing and if passing is enabled" + If(Is Button Held(Global.previousTargetedPlayer, Button(Secondary Fire)) && Global.passingEnabled); + Global.isPassingTeam1 = True; + If(!Global.invisiblePlayers); + Play Effect(All Players(All Teams), Ring Explosion, Color(Sky Blue), Position Of(Global.previousTargetedPlayer), 10); + End; + Play Effect(Global.previousTargetedPlayer, Moira Fade Disappear Sound, Color(White), Position Of(Global.previousTargetedPlayer), + 100); + Set Player Health(Global.previousTargetedPlayer, Global.passingDamage); + Global.target = Global.previousTargetedPlayer; + Else; + Global.isPassingTeam1 = False; + Heal(Global.previousTargetedPlayer, Null, Global.passingDamage); + Global.target = First Of(Sorted Array(Filtered Array(All Living Players(All Teams), + Current Array Element != Global.previousTargetedPlayer && Hero Of(Current Array Element) != Global.ballHero), + Angle Between Vectors(Facing Direction Of(Global.target), Direction Towards(Global.target, Position Of( + Current Array Element))))); + End; + Start Rule(BallCurve, Restart Rule); + } +} + +rule("Ball reaches player -TEAMS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Game Mode == Game Mode(Team Deathmatch); + Distance Between(Global.ballPosition, Eye Position(Global.target)) <= 1.900; + Global.ballIsOut == True; + } + + actions + { + If(!(Is Using Ability 2(Global.target) || (Is Using Ability 1(Global.target) && Global.rulesetMode != 1))); + Call Subroutine(DeflectFailed); + If(Global.rulesetMode == 1); + Wait(0.016, Ignore Condition); + Loop If Condition Is True; + End; + Abort; + End; + If(Is Button Held(Global.target, Button(Secondary Fire))); + "If they don't have enough health, kill em" + If(Health(Global.target) <= 100); + Call Subroutine(DeflectFailed); + If(Global.rulesetMode == 1); + Wait(0.016, Ignore Condition); + Loop If Condition Is True; + End; + Abort; + End; + End; + If(Is Using Ability 1(Global.target)); + If(Global.target.stunCooldown == 0); + Set Status(Global.target, Null, Knocked Down, 1); + Global.target.stunCooldown = 0.500; + End; + Teleport(Global.target, Global.ballPosition); + End; + Global.target.currentUltPercent += 5; + Play Effect(All Players(All Teams), Explosion Sound, Color(White), Position Of(Global.target), 200); + Global.target.playerDeflects += 1; + Global.previousTargetedPlayer = Global.target; + Global.ballSpeed = Min(500, Global.ballSpeed * 1.050); + If(Global.ballSpeed > Global.target.maxBallSpeed); + Global.target.maxBallSpeed = Global.ballSpeed; + End; + Global.ballDirection = Facing Direction Of(Global.target) * (Global.rulesetMode == 2 ? Global.ballSpeed : 1); + Wait(0.001, Ignore Condition); + "Check if player is passing and if passing is enabled" + If(Is Button Held(Global.previousTargetedPlayer, Button(Secondary Fire)) && Global.passingEnabled); + "if previousTargetedPlayer.isHoldingButton(Button.SECONDARY_FIRE):" + If(!Global.invisiblePlayers); + Play Effect(All Players(All Teams), Ring Explosion, Color(Sky Blue), Position Of(Global.previousTargetedPlayer), 10); + End; + Play Effect(Global.previousTargetedPlayer, Moira Fade Disappear Sound, Color(White), Position Of(Global.previousTargetedPlayer), + 100); + Set Player Health(Global.previousTargetedPlayer, Global.passingDamage); + Stop Assist(Global.passingAssistId); + "passingPlayer = null\r\nCheck which team is passing" + If(Team Of(Global.previousTargetedPlayer) == Team 1); + Global.isPassingTeam1 = True; + Else; + Global.isPassingTeam2 = True; + End; + "If the member is the only one left on their team, self pass" + If(Number Of Living Players(Team Of(Global.previousTargetedPlayer)) == 1); + "Check if using modern rules. Self passing is disabled in retro rules so it's basically a failed deflect." + If(Global.rulesetMode != 1); + Global.target = Global.previousTargetedPlayer; + Else; + Call Subroutine(DeflectFailed); + End; + "Pass to another teammate" + Else; + Global.passingPlayer = Global.previousTargetedPlayer; + Start Assist(Global.passingPlayer, All Players(All Teams), None); + Global.passingAssistId = Last Assist ID; + Global.target = First Of(Sorted Array(Remove From Array(All Living Players(Team Of(Global.previousTargetedPlayer)), + Global.previousTargetedPlayer), Angle Between Vectors(Facing Direction Of(Global.target), Direction Towards(Global.target, + Position Of(Current Array Element))))); + End; + Else; + "Only clear the passing player if this isn't that passing players ball" + If(Global.isPassingTeam1 == False || Global.isPassingTeam2 == False); + Stop Assist(Global.passingAssistId); + End; + Heal(Global.previousTargetedPlayer, Null, Global.passingDamage); + Global.isPassingTeam1 = False; + Global.isPassingTeam2 = False; + Global.target = First Of(Sorted Array(Remove From Array(All Living Players(Opposite Team Of(Team Of( + Global.previousTargetedPlayer))), Global.previousTargetedPlayer), Angle Between Vectors(Facing Direction Of(Global.target), + Direction Towards(Global.target, Position Of(Current Array Element))))); + End; + Start Rule(BallCurve, Restart Rule); + } +} + +rule("Subroutine BallCurve") +{ + event + { + Subroutine; + BallCurve; + } + + actions + { + If(Global.rulesetMode == 0); + Global.ballDirectionRate = 6; + Wait(0.050, Ignore Condition); + Global.ballDirectionRate = 1.750; + "Hey, what do you know, that comment I had here for months actually ended up correct when I readded retro!" + Else If(Global.rulesetMode == 1); + Loop If Condition Is True; + End; + } +} + +rule("End assist after a second - TEAMS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Game Mode == Game Mode(Team Deathmatch); + Global.passingPlayer != Null; + } + + actions + { + Wait Until(Global.previousTargetedPlayer != Global.passingPlayer, 10); + Wait(1, Ignore Condition); + Stop Assist(Global.passingAssistId); + Global.passingPlayer = Null; + } +} + +rule("Player Didn't Deflect - Kill") +{ + event + { + Subroutine; + DeflectFailed; + } + + actions + { + Heal(All Living Players(All Teams), Null, 200); + Global.isPassingTeam1 = False; + Global.isPassingTeam2 = False; + Set Status(Global.target, Global.previousTargetedPlayer, Stunned, 1); + Global.target.bouncePadCooldown = 0; + Global.previousTargetedPlayer.currentUltPercent += 15; + If(Global.ballHero && Global.previousTargetedPlayer == -1); + Global.previousTargetedPlayer = Global.ballPlayer; + End; + Kill(Global.target, Global.previousTargetedPlayer); + If(Global.ballHero && !Has Status(Global.ballPlayer, Frozen)); + Stop Facing(Global.ballPlayer); + Set Facing(Global.ballPlayer, Direction Towards(Eye Position(Global.ballPlayer), Position Of(Global.target)), To World); + End; + If(Global.improvedExplosions == True); + Call Subroutine(UpdatedDeathEffects); + Else; + Call Subroutine(CoolDeathEffects); + End; + If(Global.passingPlayer && Team Of(Global.target) != Team Of(Global.passingPlayer)); + "Please don't ask me why I need to do this. I don't know either." + Global.passingPlayerName = Global.passingPlayer; + Small Message(All Players(All Teams), Custom String("Passing assist from {0}!", Global.passingPlayerName)); + End; + Stop Assist(Global.passingAssistId); + Global.passingPlayer = Null; + Global.target.playerDeaths += 1; + Global.previousTargetedPlayer.playerKills += 1; + If(Global.endlessBall); + "Does this if statement look scary to you? Good. Tremble in fear at my might of writing unnecessarily complex if statements." + If((Current Game Mode == Game Mode(Deathmatch) && Count Of(Filtered Array(All Living Players(All Teams), Is Alive( + Current Array Element) && Hero Of(Current Array Element) != Global.ballHero)) != 1) || (Current Game Mode == Game Mode( + Team Deathmatch) && !(Number Of Living Players(Team 1) == 0 || Number Of Living Players(Team 2) == 0))); + Global.ballSpeed = Min(500, Global.ballSpeed * 1.050); + "Massive shoutout to DazNachbarzkind#2265 from the GDB EU Discord for making this intelligent targeting logic. You alone made this mode awesome." + Global.target = First Of(Sorted Array(Filtered Array(All Living Players(All Teams), + Current Array Element.hasMoved && Current Array Element != Global.ballPlayer), Angle Between Vectors(Global.ballDirection, + Direction Towards(Global.ballPosition, Position Of(Current Array Element))))); + Else; + Global.ballDeleteRequested = True; + End; + Else; + Global.ballDeleteRequested = True; + End; + } +} + +rule("CoolDeathEffects sub") +{ + event + { + Subroutine; + CoolDeathEffects; + } + + actions + { + Create Beam Effect(All Players(All Teams), Bad Beam, Global.previousTargetedPlayer, Global.target, Color(Sky Blue), + Visible To Position and Radius); + Global.deathBeam = Last Created Entity; + Global.deathSpherePos = Position Of(Global.target); + Global.deathSphereRad = 30; + Chase Global Variable Over Time(deathSphereRad, 0, 0.250, None); + Play Effect(All Players(All Teams), Ring Explosion Sound, Color(Sky Blue), Global.deathSpherePos, 40); + Create Effect(All Players(All Teams), Sphere, Color(Black), Global.deathSpherePos, Global.deathSphereRad, + Visible To Position and Radius); + Global.deathSphere = Last Created Entity; + Play Effect(All Players(All Teams), Good Explosion, Color(White), Global.deathSpherePos, 5); + Wait(0.250, Ignore Condition); + Destroy Effect(Global.deathSphere); + "playEffect(getAllPlayers(), DynamicEffect.RING_EXPLOSION, Color.RED, deathSpherePos, sphereSize * 1.5)\r\nplayEffect(getAllPlayers(), DynamicEffect.EXPLOSION_SOUND, Color.WHITE, deathSpherePos, 40)" + Destroy Effect(Global.deathBeam); + } +} + +rule("Updated Death Effects Sub") +{ + event + { + Subroutine; + UpdatedDeathEffects; + } + + actions + { + Global.deathSpherePos = Position Of(Global.target); + "Make sure it is final duel AND there are at least 3 or more players" + If(Current Game Mode == Game Mode(Deathmatch) && Number Of Living Players(All Teams) == 1 && Number Of Heroes(Global.playerHero, + All Teams) != 2 && Global.finalDuelNuke); + If(Altitude Of(Global.target) < 5); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Effect, Color(White), Vector(X Component Of( + Global.deathSpherePos), 0, Z Component Of(Global.deathSpherePos)), 0); + Else; + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Effect, Color(White), Global.deathSpherePos, 0); + End; + Else If(Current Game Mode == Game Mode(Team Deathmatch) && (Number Of Living Players(Team 1) == 0 || Number Of Living Players( + Team 2) == 0) && Number Of Heroes(Global.playerHero, All Teams) != 2 && Global.finalDuelNuke); + If(Altitude Of(Global.target) < 5); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Effect, Color(White), Vector(X Component Of( + Global.deathSpherePos), 0, Z Component Of(Global.deathSpherePos)), 0); + Else; + Play Effect(All Players(All Teams), Junkrat RIP Tire Explosion Effect, Color(White), Global.deathSpherePos, 0); + End; + End; + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Effect, Color(White), Global.deathSpherePos, 1); + If(Global.randomExplosionSounds); + "Pick a random explosion sound" + Global.randomExplosionPicker = Random Integer(0, 4); + If(Global.randomExplosionPicker == 0); + Play Effect(All Players(All Teams), Doomfist Meteor Strike Impact Sound, Color(White), Global.deathSpherePos, + Global.explosionSoundVolume); + Else If(Global.randomExplosionPicker == 1); + Play Effect(All Players(All Teams), Bastion Tank Cannon Explosion Sound, Color(White), Global.deathSpherePos, + Global.explosionSoundVolume); + Else If(Global.randomExplosionPicker == 2); + Play Effect(All Players(All Teams), Ashe Dynamite Explosion Sound, Color(White), Global.deathSpherePos, + Global.explosionSoundVolume); + Else If(Global.randomExplosionPicker == 3); + Play Effect(All Players(All Teams), Pharah Barrage Explosion Sound, Color(White), Global.deathSpherePos, + Global.explosionSoundVolume); + Else If(Global.randomExplosionPicker == 4); + Play Effect(All Players(All Teams), Junkrat Frag Launcher Explosion Sound, Color(White), Global.deathSpherePos, + Global.explosionSoundVolume); + End; + Else; + "playEffect(getAllPlayers(), DynamicEffect.DOOMFIST_METEOR_STRIKE_IMPACT_SOUND, Color.WHITE, deathSpherePos, explosionSoundVolume)" + Play Effect(All Players(All Teams), Junkrat Frag Launcher Explosion Sound, Color(White), Global.deathSpherePos, + Global.explosionSoundVolume); + End; + } +} + +rule("Final duel") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Game Mode == Game Mode(Deathmatch); + Is Game In Progress == True; + Global.roundInProgress != False; + Count Of(Filtered Array(All Living Players(All Teams), Current Array Element.hasMoved && Hero Of(Current Array Element) + != Global.ballHero)) == 2; + Global.isEnoughPlayersToStart == True; + Global.isInFinalDuel == False; + Global.endlessBall == False; + } + + actions + { + Global.ballSpawnCountdown = 5; + All Living Players(All Teams).isDashEnabled = False; + Skip If(Global.ballIsOut == False, 1); + Global.ballDeleteRequested = True; + Global.isInFinalDuel = True; + All Living Players(All Teams).bouncePadCooldown = 2; + Skip If(Number Of Heroes(Global.playerHero, All Teams) <= 2, 1); + Big Message(All Players(All Teams), Custom String("Final Duel!")); + Apply Impulse(All Living Players(All Teams), Down, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(All Living Players(All Teams), Up, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(All Living Players(All Teams), Backward, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(All Living Players(All Teams), Forward, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(All Living Players(All Teams), Right, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(All Living Players(All Teams), Left, 0.001, To World, Cancel Contrary Motion); + If(Current Map == Map(Workshop Island) || Current Map == Map(Workshop Island Night)); + Teleport(First Of(All Living Players(All Teams)), Global.circleCenter + Vector(-1, 0, 0) * (Global.SphereSize / 4)); + Teleport(All Living Players(All Teams)[1], Global.circleCenter + Vector(1, 0, 0) * (Global.SphereSize / 4)); + Else; + Teleport(First Of(All Living Players(All Teams)), Global.circleCenter + Vector(-1, 0, 0) * (Global.SphereSize / 1.500)); + Teleport(All Living Players(All Teams)[1], Global.circleCenter + Vector(1, 0, 0) * (Global.SphereSize / 1.500)); + End; + Set Status(All Living Players(All Teams), Null, Rooted, 2); + Wait(0.001, Ignore Condition); + Set Facing(First Of(All Living Players(All Teams)), Direction Towards(Position Of(First Of(All Living Players(All Teams))), + Global.circleCenter), To World); + Set Facing(All Living Players(All Teams)[1], Direction Towards(Position Of(All Living Players(All Teams)[1]), Global.circleCenter), + To World); + } +} + +rule("Final duel - TEAMS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Game Mode == Game Mode(Team Deathmatch); + Is Game In Progress == True; + Global.roundInProgress != False; + Count Of(Filtered Array(All Living Players(Team 1), Current Array Element.hasMoved)) == 1; + Count Of(Filtered Array(All Living Players(Team 2), Current Array Element.hasMoved)) == 1; + Global.isEnoughPlayersToStart == True; + Global.isInFinalDuel == False; + Global.endlessBall == False; + } + + actions + { + Global.ballSpawnCountdown = 5; + All Living Players(All Teams).isDashEnabled = False; + Skip If(Global.ballIsOut == False, 1); + Global.ballDeleteRequested = True; + Global.isInFinalDuel = True; + All Living Players(All Teams).bouncePadCooldown = 2; + Skip If(Number Of Heroes(Global.playerHero, All Teams) <= 2, 1); + Big Message(All Players(All Teams), Custom String("Final Duel!")); + Apply Impulse(All Living Players(All Teams), Down, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(All Living Players(All Teams), Up, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(All Living Players(All Teams), Backward, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(All Living Players(All Teams), Forward, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(All Living Players(All Teams), Right, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(All Living Players(All Teams), Left, 0.001, To World, Cancel Contrary Motion); + If(Current Map == Map(Workshop Island) || Current Map == Map(Workshop Island Night)); + Teleport(First Of(All Living Players(All Teams)), Global.circleCenter + Vector(-1, 0, 0) * (Global.SphereSize / 4)); + Teleport(All Living Players(All Teams)[1], Global.circleCenter + Vector(1, 0, 0) * (Global.SphereSize / 4)); + Else; + Teleport(First Of(All Living Players(All Teams)), Global.circleCenter + Vector(-1, 0, 0) * (Global.SphereSize / 1.500)); + Teleport(All Living Players(All Teams)[1], Global.circleCenter + Vector(1, 0, 0) * (Global.SphereSize / 1.500)); + End; + Set Status(All Living Players(All Teams), Null, Rooted, 2); + Wait(0.001, Ignore Condition); + Set Facing(First Of(All Living Players(All Teams)), Direction Towards(Position Of(First Of(All Living Players(All Teams))), + Global.circleCenter), To World); + Set Facing(All Living Players(All Teams)[1], Direction Towards(Position Of(All Living Players(All Teams)[1]), Global.circleCenter), + To World); + } +} + +rule("Create passing aura - TEAMS") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Current Game Mode == Game Mode(Team Deathmatch); + Is Button Held(Event Player, Button(Secondary Fire)) == True; + Global.passingEnabled != False; + Global.passingAuraToggle != False; + Global.invisiblePlayers == False; + } + + actions + { + Create Effect(Filtered Array(All Players(Team Of(Event Player)), Current Array Element != Event Player && Is Alive( + Current Array Element)), Bad Aura, Color(Sky Blue), Eye Position(Event Player), 1.500, Position and Radius); + Event Player.passingSignal = Last Created Entity; + Wait Until(!Is Button Held(Event Player, Button(Secondary Fire)) || Is Dead(Event Player), 60); + Destroy Effect(Event Player.passingSignal); + } +} + +rule("Check for last player surviving") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Game Mode == Game Mode(Deathmatch); + Is Game In Progress == True; + Count Of(Filtered Array(All Living Players(All Teams), Is Alive(Current Array Element) && Hero Of(Current Array Element) + != Global.ballHero)) == 1; + Global.isEnoughPlayersToStart == True; + } + + actions + { + Global.isInFinalDuel = False; + Modify Player Score(Filtered Array(All Living Players(All Teams), Hero Of(Current Array Element) != Global.ballHero), 1); + Wait(0.250, Ignore Condition); + If((Match Time == 0 || Global.tieBreakerActive) && Global.gameEndEnabled); + "If there is alredy a tiebreaker, then the tiebreaker has ended.\r\nif tieBreakerActive:\r\nbreak\r\n__end__()" + Global.highestScore = Score Of(Last Of(Sorted Array(All Players(All Teams), Score Of(Current Array Element)))); + "Check if there is more then 1 person with the highest score" + If(Count Of(Filtered Array(All Players(All Teams), Score Of(Current Array Element) == Global.highestScore)) > 1); + "There is more then 1, activate tie breaker" + Global.tieBreakerActive = True; + Else; + Global.tieBreakerActive = False; + End; + End; + Stop Chasing Global Variable(ballSpawnCountdown); + Stop Chasing Player Variable(All Players(All Teams), bouncePadCooldown); + Big Message(All Players(All Teams), Custom String("{0} has won the round!", Filtered Array(All Living Players(All Teams), Hero Of( + Current Array Element) != Global.ballHero))); + Wait(2, Ignore Condition); + Global.roundInProgress = False; + If(!Global.tieBreakerActive); + Resurrect(All Dead Players(All Teams)); + Else; + "Kill anyone alive who doesn't have the highest score." + Kill(Filtered Array(All Living Players(All Teams), Score Of(Current Array Element) != Global.highestScore), Null); + "During tiebreaker, only revive the people who have the same score as the highest score." + Resurrect(Filtered Array(All Dead Players(All Teams), Score Of(Current Array Element) == Global.highestScore)); + Wait(0.250, Ignore Condition); + Global.target = -1; + Big Message(All Players(All Teams), Custom String("Tiebreaker!")); + End; + Abort If(!Global.isEnoughPlayersToStart); + All Players(All Teams).bouncePadCooldown = Global.bouncePadCooldownLengthStart; + Global.currentRound += 1; + If(Global.currentRound - 1 < Global.maxRounds && Global.tournamentMode && Global.breaksEnabled && (Global.currentRound - 1) + % Global.breakFrequency == 0); + Call Subroutine(deleteBall); + Else; + Global.ballSpawnCountdown = 5; + End; + Wait(0.025, Ignore Condition); + Global.roundInProgress = True; + Wait(0.975, Ignore Condition); + Skip If(!Global.bouncepadDashingEnabled, 2); + All Players(All Teams).isDashEnabled = False; + Set Ability 1 Enabled(All Players(All Teams), False); + Chase Global Variable At Rate(ballSpawnCountdown, 0, 1, None); + Chase Player Variable At Rate(All Players(All Teams), bouncePadCooldown, 0, 1, None); + } +} + +rule("Team 1 Last Surviving - TEAMS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Game Mode == Game Mode(Team Deathmatch); + Is Game In Progress == True; + Number Of Living Players(Team 2) == 0; + Global.isEnoughPlayersToStart == True; + } + + actions + { + Global.isInFinalDuel = False; + Modify Team Score(Team 1, 1); + Wait(0.250, Ignore Condition); + If((Match Time == 0 || Global.tieBreakerActive) && Global.gameEndEnabled); + "If there is alredy a tiebreaker, then the tiebreaker has ended.\r\nif tieBreakerActive:\r\nbreak\r\n__end__()" + Global.highestScore = Score Of(Last Of(Sorted Array(All Players(All Teams), Score Of(Current Array Element)))); + "Check if there is more then 1 person with the highest score" + If(Team Score(Team 1) == Team Score(Team 2)); + "There is more then 1, activate tie breaker" + Global.tieBreakerActive = True; + Else; + Global.tieBreakerActive = False; + End; + End; + Stop Chasing Global Variable(ballSpawnCountdown); + Stop Chasing Player Variable(All Players(All Teams), bouncePadCooldown); + Big Message(All Players(All Teams), Custom String("{0} has won the round!", Team 1)); + Wait(2, Ignore Condition); + Global.roundInProgress = False; + If(!Global.tieBreakerActive); + Resurrect(All Dead Players(All Teams)); + Else; + "Kill anyone alive who doesn't have the highest score." + Kill(Filtered Array(All Living Players(All Teams), Score Of(Current Array Element) != Global.highestScore), Null); + "During tiebreaker, only revive the people who have the same score as the highest score." + Resurrect(Filtered Array(All Dead Players(All Teams), Score Of(Current Array Element) == Global.highestScore)); + Wait(0.250, Ignore Condition); + Global.target = -1; + Big Message(All Players(All Teams), Custom String("Tiebreaker!")); + End; + Heal(All Players(All Teams), Null, 200); + Abort If(!Global.isEnoughPlayersToStart); + Global.currentRound += 1; + All Players(All Teams).bouncePadCooldown = Global.bouncePadCooldownLengthStart; + Global.ballSpawnCountdown = 5; + Wait(0.025, Ignore Condition); + Global.roundInProgress = True; + Wait(0.975, Ignore Condition); + Skip If(!Global.bouncepadDashingEnabled, 2); + All Players(All Teams).isDashEnabled = False; + Set Ability 1 Enabled(All Players(All Teams), False); + Chase Global Variable At Rate(ballSpawnCountdown, 0, 1, None); + Chase Player Variable At Rate(All Players(All Teams), bouncePadCooldown, 0, 1, None); + } +} + +rule("Team 2 Last Surviving - TEAMS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Game Mode == Game Mode(Team Deathmatch); + Is Game In Progress == True; + Number Of Living Players(Team 1) == 0; + Global.isEnoughPlayersToStart == True; + } + + actions + { + Global.isInFinalDuel = False; + Modify Team Score(Team 2, 1); + Wait(0.250, Ignore Condition); + If((Match Time == 0 || Global.tieBreakerActive) && Global.gameEndEnabled); + "If there is alredy a tiebreaker, then the tiebreaker has ended.\r\nif tieBreakerActive:\r\nbreak\r\n__end__()" + Global.highestScore = Score Of(Last Of(Sorted Array(All Players(All Teams), Score Of(Current Array Element)))); + "Check if there is more then 1 person with the highest score" + If(Team Score(Team 1) == Team Score(Team 2)); + "There is more then 1, activate tie breaker" + Global.tieBreakerActive = True; + Else; + Global.tieBreakerActive = False; + End; + End; + Stop Chasing Global Variable(ballSpawnCountdown); + Stop Chasing Player Variable(All Players(All Teams), bouncePadCooldown); + Big Message(All Players(All Teams), Custom String("{0} has won the round!", Team 2)); + Wait(2, Ignore Condition); + Global.roundInProgress = False; + If(!Global.tieBreakerActive); + Resurrect(All Dead Players(All Teams)); + Else; + "Kill anyone alive who doesn't have the highest score." + Kill(Filtered Array(All Living Players(All Teams), Score Of(Current Array Element) != Global.highestScore), Null); + "During tiebreaker, only revive the people who have the same score as the highest score." + Resurrect(Filtered Array(All Dead Players(All Teams), Score Of(Current Array Element) == Global.highestScore)); + Wait(0.250, Ignore Condition); + Global.target = -1; + Big Message(All Players(All Teams), Custom String("Tiebreaker!")); + End; + Heal(All Players(All Teams), Null, 200); + Abort If(!Global.isEnoughPlayersToStart); + Global.currentRound += 1; + All Players(All Teams).bouncePadCooldown = Global.bouncePadCooldownLengthStart; + Global.ballSpawnCountdown = 5; + Wait(0.025, Ignore Condition); + Global.roundInProgress = True; + Wait(0.975, Ignore Condition); + Skip If(!Global.bouncepadDashingEnabled, 2); + All Players(All Teams).isDashEnabled = False; + Set Ability 1 Enabled(All Players(All Teams), False); + Chase Global Variable At Rate(ballSpawnCountdown, 0, 1, None); + Chase Player Variable At Rate(All Players(All Teams), bouncePadCooldown, 0, 1, None); + } +} + +rule("Player check") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Is Alive(Event Player) == True; + Custom String("{0}", Event Player) == Custom String("daboss"); + } + + actions + { + Kill(Event Player, Null); + Wait(1, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("All players dead failsafe") +{ + event + { + Ongoing - Global; + } + + conditions + { + Number Of Living Players(All Teams) == 0; + Is Game In Progress == True; + Global.tieBreakerActive == False; + } + + actions + { + Global.isInFinalDuel = False; + Skip If(Global.ballIsOut == False, 1); + Global.ballDeleteRequested = True; + Global.roundInProgress = False; + Stop Chasing Global Variable(ballSpawnCountdown); + Resurrect(All Dead Players(All Teams)); + Small Message(All Players(All Teams), Custom String("All players detected dead! Resetting game.")); + Stop Chasing Player Variable(All Players(All Teams), bouncePadCooldown); + All Players(All Teams).bouncePadCooldown = Global.bouncePadCooldownLengthStart; + Global.ballSpawnCountdown = 5; + Wait(1, Ignore Condition); + Loop If Condition Is True; + Wait(2, Ignore Condition); + Abort If(!Global.isEnoughPlayersToStart); + Chase Player Variable At Rate(All Players(All Teams), bouncePadCooldown, 0, 1, None); + Chase Global Variable At Rate(ballSpawnCountdown, 0, 1, None); + Global.roundInProgress = True; + Global.ballPosition = Vector(0, -1, 0); + } +} + +rule("dash slow") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Is Using Ability 1(Event Player) == True; + } + + actions + { + Event Player.dashNerf = True; + Event Player.moveSpeed = 0; + Chase Player Variable At Rate(Event Player, moveSpeed, 100, Max(Event Player.moveSpeed, 16) ^ 1.250, Destination and Rate); + While(Event Player.moveSpeed != 100); + Set Move Speed(Event Player, Event Player.moveSpeed); + If(Event Player.currentGravity == Global.gravity); + Set Gravity(Event Player, Event Player.moveSpeed); + End; + Wait(0.100, Ignore Condition); + End; + Set Move Speed(Event Player, 100); + If(Event Player.currentGravity == Global.gravity); + Set Gravity(Event Player, Global.gravity); + End; + Event Player.dashNerf = False; + } +} + +rule("Ball bounce off surface") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.ballIsOut == True; + Is In Line of Sight(Global.ballPosition, Global.ballPosition + Global.ballDirection * ( + Global.rulesetMode != 2 ? Global.ballSpeed : 1) * 0.033, Barriers Do Not Block LOS) == False; + Current Map != Map(Workshop Chamber); + } + + actions + { + "normal of the plane of the surface with which the ball collides, n" + Global.ballCollisionSurfaceNormal = Ray Cast Hit Normal(Global.ballPosition, + Global.ballPosition + Global.ballDirection * Global.ballSpeed * 0.066, Null, All Players(All Teams), False); + "reflected vector formula --- new v = v - 2 * (v•n)/(n•n) * n" + Global.ballDirection -= 2 * Global.ballDirection * Global.ballCollisionSurfaceNormal / Dot Product( + Global.ballCollisionSurfaceNormal, Global.ballCollisionSurfaceNormal) * Global.ballCollisionSurfaceNormal; + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Global.ballPosition, 1); + Wait(0.020, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Ball no down when y < -0.5") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.ballIsOut == True; + Y Component Of(Global.ballPosition) < -0.500; + Y Component Of(Global.ballDirection) < 0; + } + + actions + { + Global.ballDirection *= Vector(1, Global.rulesetMode == 2 ? -1 : 0, 1); + Play Effect(All Players(All Teams), Ring Explosion, Color(White), Global.ballPosition, 2); + } +} + +rule("RGB Ball Mode") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.ballTailColor == 2; + Global.ballIsOut != False; + } + + actions + { + Global.ballTail1 = Custom Color(Random Real(0, 255), Random Real(0, 255), Random Real(0, 255), 255); + Global.ballTail2 = Custom Color(Random Real(0, 255), Random Real(0, 255), Random Real(0, 255), 255); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Chamber x collision") +{ + event + { + Ongoing - Global; + } + + conditions + { + "This collision is the lazy way but its only for chamber so who cares" + Current Map == Map(Workshop Chamber); + Global.ballIsOut == True; + (X Component Of(Global.ballPosition) + 0.400 >= 20 || X Component Of(Global.ballPosition) - 0.400 <= -20) == True; + } + + actions + { + If((X Component Of(Global.ballPosition) + 0.400 >= 20 && X Component Of(Global.ballDirection) > 0) || (X Component Of( + Global.ballPosition) - 0.400 <= -20 && X Component Of(Global.ballDirection) < 0)); + Global.ballDirection = Vector(X Component Of(Global.ballDirection) * -1, Y Component Of(Global.ballDirection), Z Component Of( + Global.ballDirection)); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Global.ballPosition, 1); + End; + Wait(0.016, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Chamber y collision") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Workshop Chamber); + Global.ballIsOut == True; + (Y Component Of(Global.ballPosition) + 0.400 >= 40) - (Y Component Of(Global.ballPosition) - 0.400 <= 0) == True; + } + + actions + { + If((Y Component Of(Global.ballPosition) + 0.400 >= 40 && Y Component Of(Global.ballDirection) > 0) || (Y Component Of( + Global.ballPosition) - 0.400 <= 0 && Y Component Of(Global.ballDirection) < 0)); + Global.ballDirection = Vector(X Component Of(Global.ballDirection), Y Component Of(Global.ballDirection) * -1, Z Component Of( + Global.ballDirection)); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Global.ballPosition, 1); + End; + Wait(0.016, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Chamber z collision") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Map == Map(Workshop Chamber); + Global.ballIsOut == True; + (Z Component Of(Global.ballPosition) + 0.400 >= 20 || Z Component Of(Global.ballPosition) - 0.400 <= -20) == True; + } + + actions + { + If((Z Component Of(Global.ballPosition) + 0.400 >= 20 && Z Component Of(Global.ballDirection) > 0) || (Z Component Of( + Global.ballPosition) - 0.400 <= -20 && Z Component Of(Global.ballDirection) < 0)); + Global.ballDirection = Vector(X Component Of(Global.ballDirection), Y Component Of(Global.ballDirection), Z Component Of( + Global.ballDirection) * -1); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Global.ballPosition, 1); + End; + Wait(0.016, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Expanse y collision") +{ + event + { + Ongoing - Global; + } + + conditions + { + (Current Map == Map(Workshop Expanse) || Current Map == Map(Workshop Expanse Night)) == True; + Global.ballIsOut == True; + Y Component Of(Global.ballPosition) - 0.400 <= 0; + } + + actions + { + If(Y Component Of(Global.ballPosition) - 0.400 <= 0 && Y Component Of(Global.ballDirection) < 0); + Global.ballDirection = Vector(X Component Of(Global.ballDirection), Y Component Of(Global.ballDirection) * -1, Z Component Of( + Global.ballDirection)); + Play Effect(All Players(All Teams), Bad Explosion, Color(White), Global.ballPosition, 1); + End; + Wait(0.016, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("No Undermaps") +{ + event + { + Ongoing - Global; + } + + conditions + { + (Current Map == Map(Workshop Island) || Current Map == Map(Workshop Island Night)) == True; + Global.ballIsOut == True; + Y Component Of(Global.ballPosition) < -2.850; + Y Component Of(Global.ballDirection) < 0; + } + + actions + { + Global.ballDirection *= Vector(1, 0, 1); + Play Effect(All Players(All Teams), Ring Explosion, Color(White), Global.ballPosition, 2); + } +} + +rule("Team 1 Win - TEAMS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Game Mode == Game Mode(Team Deathmatch); + Global.allowMatchEnd == True; + Team Score(Team 1) == Global.scoreToWin; + } + + actions + { + Enable Built-In Game Mode Announcer; + Declare Team Victory(Team 1); + } +} + +rule("Team 2 Win - TEAMS") +{ + event + { + Ongoing - Global; + } + + conditions + { + Current Game Mode == Game Mode(Team Deathmatch); + Global.allowMatchEnd == True; + Team Score(Team 2) == Global.scoreToWin; + } + + actions + { + Enable Built-In Game Mode Announcer; + Declare Team Victory(Team 2); + } +} + +rule("Maximum amount of rounds reached") +{ + event + { + Ongoing - Global; + } + + conditions + { + Global.maxRoundsToggle != False; + Global.currentRound > Global.maxRounds; + } + + actions + { + Enable Built-In Game Mode Completion; + } +} + +rule("Toggle 3rd person") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Global.breakInProgress == False; + Is Button Held(Event Player, Button(Reload)) == True; + Is Alive(Event Player) == True; + Global.perspectiveMode == 0; + } + + actions + { + If(!Event Player.thirdPerson); + Event Player.thirdPerson = True; + Wait(0.010, Ignore Condition); + Start Camera(Event Player, Event Player + World Vector Of(Vector(-0.750, 0.250, -0.250), Event Player, Rotation) + + Up * 1.500 + Facing Direction Of(Event Player) * -2, Event Player + Facing Direction Of(Event Player) * 1000, 0); + Else; + If(Global.invisiblePlayers); + Start Camera(Event Player, Update Every Frame(Eye Position(Event Player)), Update Every Frame(Event Player + Facing Direction Of( + Event Player) * 1000), 0); + Else; + Stop Camera(Event Player); + End; + Event Player.thirdPerson = False; + } +} + +rule("Player dead 3rd person") +{ + event + { + Player Died; + All; + All; + } + + conditions + { + Event Player.thirdPerson != False; + } + + actions + { + Stop Camera(Event Player); + } +} + +rule("3rd person respawn") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Has Spawned(Event Player) == True; + Global.roundInProgress == False; + Event Player.thirdPerson != False; + } + + actions + { + Start Camera(Event Player, Event Player + World Vector Of(Vector(-0.750, 0.250, -0.250), Event Player, Rotation) + + Up * 1.500 + Facing Direction Of(Event Player) * -2, Event Player + Facing Direction Of(Event Player) * 1000, 0); + } +} + +rule("Player dead 1st person during invisible players") +{ + event + { + Player Died; + All; + All; + } + + conditions + { + Global.invisiblePlayers != False; + Event Player.thirdPerson == False; + } + + actions + { + Stop Camera(Event Player); + } +} + +rule("1st person respawn during invisible players") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Global.invisiblePlayers != False; + Has Spawned(Event Player) == True; + Global.roundInProgress == False; + Event Player.thirdPerson == False; + } + + actions + { + Start Camera(Event Player, Update Every Frame(Eye Position(Event Player)), Update Every Frame(Event Player + Facing Direction Of( + Event Player) * 1000), 0); + } +} + +rule("Measure Latency") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Global.roundInProgress == True; + } + + actions + { + If(!Event Player.latencyToggle || Is Communicating Any Emote(Event Player)); + Event Player.latency = 0; + Abort; + End; + Event Player.latency = Array(Direction From Angles(Horizontal Facing Angle Of(Event Player), Vertical Facing Angle Of(Event Player) + + (Vertical Facing Angle Of(Event Player) < 0) - 0.500), Total Time Elapsed); + Start Facing(Event Player, First Of(Event Player.latency), 100000, To Player, None); + Wait Until(First Of(Event Player.latency) == Update Every Frame(Facing Direction Of(Event Player)), 99999); + Stop Facing(Event Player); + Event Player.latency = (Total Time Elapsed - Last Of(Event Player.latency)) * 0.500 * Workshop Setting Real(Custom String( + "Visual Settings"), Custom String("Client Prediction Amount"), 1, 0, 1, 4); + } +} + +rule("Toggle Latency") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Is Button Held(Event Player, Button(Ultimate)) == True; + Global.rulesetMode != 2; + } + + actions + { + If(Event Player.latencyToggle); + Event Player.latencyToggle = False; + Small Message(Event Player, Custom String("Lag compensation disabled for next round")); + Else; + Event Player.latencyToggle = True; + Small Message(Event Player, Custom String("Lag compensation enabled for next round")); + End; + Wait(0.500, Ignore Condition); + } +} + +rule("No cheating during invisible players - TEAMS") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Current Game Mode == Game Mode(Team Deathmatch); + Global.invisTeamsAntiCheat != False; + Global.invisiblePlayers != False; + Global.roundInProgress != False; + Is Communicating Any(Event Player) == True; + } + + actions + { + Event Player.emoteCheatCount += 1; + If(Event Player.emoteCheatCount == 1); + Small Message(Event Player, Custom String("Please don't cheat by emoting :(")); + Else If(Event Player.emoteCheatCount == 2); + Set Status(Event Player, Null, Stunned, 1); + Small Message(Event Player, Custom String("No cheating >:(")); + Wait Until(Is Alive(Event Player), 9999); + Wait(2.500, Ignore Condition); + Small Message(Event Player, Custom String("Don't do it again or I get really mad")); + Else If(Event Player.emoteCheatCount == 3); + Set Status(Event Player, Null, Asleep, 5); + Small Message(Event Player, Custom String("No cheating >:(")); + Wait Until(Is Alive(Event Player), 9999); + Wait(2.500, Ignore Condition); + Small Message(Event Player, Custom String("One more time and I get super mad >:(")); + Else; + Big Message(All Players(All Teams), Custom String("{0} keeps trying to cheat by emoting!", Event Player)); + Kill(Event Player, Null); + If(Global.ballIsOut && Event Player == Global.target); + Global.ballDeleteRequested = True; + End; + Wait Until(Is Alive(Event Player), 9999); + Wait(1.500, Ignore Condition); + Small Message(Event Player, Custom String("What did I say?")); + } +} + +rule("Map restrictions - put out center") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Distance Between(Position Of(Event Player), Global.circleCenter) < Global.CenterOffLimitsSize + 0.500; + } + + actions + { + Apply Impulse(Event Player, Direction Towards(Global.circleCenter, Event Player), 10, To World, Cancel Contrary Motion); + Apply Impulse(Event Player, Up, 1.500, To World, Incorporate Contrary Motion); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Map restrictions - player dashes too far out of bounds") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Distance Between(Position Of(Event Player), Vector(X Component Of(Global.circleCenter), Y Component Of(Position Of(Event Player)), + Z Component Of(Global.circleCenter))) > Global.SphereSize + 5; + "Workshop Island Fix" + disabled (Current Map != Map(Workshop Island) && Current Map != Map(Workshop Island Night)) == True; + } + + actions + { + Set Status(Event Player, Null, Knocked Down, 2.500); + disabled Teleport(Event Player, Global.circleCenter + Vector(Random Integer(-15, 15), 8, Random Integer(-15, 15))); + Apply Impulse(Event Player, Vector(X Component Of(Direction Towards(Position Of(Event Player), Global.circleCenter)), 0, + Z Component Of(Direction Towards(Position Of(Event Player), Global.circleCenter))), 20, To World, Cancel Contrary Motion); + Apply Impulse(Event Player, Up, 3, To World, Cancel Contrary Motion); + Big Message(Event Player, Custom String("Do not dash out of the arena!")); + } +} + +rule("Map restrictions - push to circle") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Distance Between(Position Of(Event Player), Vector(X Component Of(Global.circleCenter), Y Component Of(Position Of(Event Player)), + Z Component Of(Global.circleCenter))) > Global.SphereSize - 1.500; + "Workshop Island Fix" + Current Map != Map(Workshop Island); + Current Map != Map(Workshop Island Night); + } + + actions + { + Apply Impulse(Event Player, Vector(X Component Of(Direction Towards(Position Of(Event Player), Global.circleCenter)), 0, + Z Component Of(Direction Towards(Position Of(Event Player), Global.circleCenter))), 6, To World, Cancel Contrary Motion); + Apply Impulse(Event Player, Up, 3, To World, Incorporate Contrary Motion); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Map restrictions - player falls off Workshop Island") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + (Current Map == Map(Workshop Island) || Current Map == Map(Workshop Island Night)) == True; + Y Component Of(Position Of(Event Player)) < -0.500; + } + + actions + { + "A MAN HAS FALLEN INTO THE LAKE IN WORKSHOP ISLAND! START THE NEW RESCUE RULE! HEY! BUILD THE NEW WORSHOP RULE, AND OFF TO THE RESCUE! PREPARE THE CONDITION, TELEPORT THE PLAYER, AND MAKE THE RESCUE! THE NEW 2.3.0 UPDATE FROM OVERWATCH WORKSHOP!" + If(!Is Alive(Event Player)); + Teleport(Event Player, Global.circleCenter + Vector(Random Integer(-10, 10), 8, Random Integer(-10, 10))); + If(Event Player == Global.target); + If(Global.ballIsOut); + End; + End; + End; + Wait(0.500, Ignore Condition); + Loop If Condition Is True; + Global.ballDeleteRequested = True; + } +} + +rule("Map restrictions - water surface 1") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Y Component Of(Position Of(Event Player)) < -0.200; + Y Component Of(Position Of(Event Player)) >= -0.350; + Y Component Of(Velocity Of(Event Player)) < 0; + Is Alive(Event Player) == True; + Is Using Ability 1(Event Player) == False; + "Workshop Island Fix" + (Current Map == Map(Workshop Island) || Current Map == Map(Workshop Island Night)) == True; + } + + actions + { + Abort If(X Component Of(Position Of(Event Player)) < 20.250 && X Component Of(Position Of(Event Player)) + > -20.250 && Z Component Of(Position Of(Event Player)) < 20.250 && Z Component Of(Position Of(Event Player)) > -20.250); + Event Player.currentGravity = 0; + Set Gravity(Event Player, 0); + Apply Impulse(Event Player, Down, 0.001, To World, Cancel Contrary Motion); + Apply Impulse(Event Player, Up, 0.001, To World, Cancel Contrary Motion); + Wait(0.100, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Map restrictions - water surface 2") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Y Component Of(Position Of(Event Player)) < -0.350; + Y Component Of(Position Of(Event Player)) >= -1.500; + (Y Component Of(Velocity Of(Event Player)) > 0) == False; + Is Alive(Event Player) == True; + Is Using Ability 1(Event Player) == False; + "Workshop Island Fix" + (Current Map == Map(Workshop Island) || Current Map == Map(Workshop Island Night)) == True; + } + + actions + { + Abort If(X Component Of(Position Of(Event Player)) < 20.250 && X Component Of(Position Of(Event Player)) + > -20.250 && Z Component Of(Position Of(Event Player)) < 20.250 && Z Component Of(Position Of(Event Player)) > -20.250); + Apply Impulse(Event Player, Up, 5, To World, Cancel Contrary Motion); + Wait(0.250, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Map restrictions - water") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Y Component Of(Position Of(Event Player)) < -1.500; + Is Alive(Event Player) == True; + "Workshop Island Fix" + (Current Map == Map(Workshop Island) || Current Map == Map(Workshop Island Night)) == True; + } + + actions + { + If(X Component Of(Position Of(Event Player)) < 35 || X Component Of(Position Of(Event Player)) > -35 || Z Component Of(Position Of( + Event Player)) < 35 || Z Component Of(Position Of(Event Player)) > -35); + "Prevents people from going under the ledge on Workshop Island, which caused ball to go into floor. Used to be an annoying stunkill" + Apply Impulse(Event Player, Up, 2, To World, Cancel Contrary Motion XYZ); + Apply Impulse(Event Player, Direction Towards(Event Player, Global.circleCenter), 2, To World, Incorporate Contrary Motion); + End; + If(X Component Of(Position Of(Event Player)) > 35 || X Component Of(Position Of(Event Player)) < -35 || Z Component Of(Position Of( + Event Player)) > 35 || Z Component Of(Position Of(Event Player)) < -35); + Apply Impulse(Event Player, Direction Towards(Event Player, Global.circleCenter), 3, To World, Incorporate Contrary Motion); + Apply Impulse(Event Player, Up, 0.300, To World, Cancel Contrary Motion); + End; + Wait(0.008, Ignore Condition); + Loop If Condition Is True; + } +} + +rule("Map restrictions - water leave") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Y Component Of(Position Of(Event Player)) >= -0.200; + Is Alive(Event Player) == True; + "Workshop Island Fix" + (Current Map == Map(Workshop Island) || Current Map == Map(Workshop Island Night)) == True; + } + + actions + { + Set Gravity(Event Player, Global.gravity); + Event Player.currentGravity = Global.gravity; + } +} + +rule("Map restrictions - island enter") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + X Component Of(Position Of(Event Player)) < 20.250; + X Component Of(Position Of(Event Player)) > -20.250; + Z Component Of(Position Of(Event Player)) < 20.250; + Z Component Of(Position Of(Event Player)) > -20.250; + Is Alive(Event Player) == True; + "Workshop Island Fix" + (Current Map == Map(Workshop Island) || Current Map == Map(Workshop Island Night)) == True; + } + + actions + { + Event Player.currentGravity = Global.gravity; + Set Gravity(Event Player, Global.gravity); + } +} + +rule("Init Gravity") +{ + event + { + Ongoing - Global; + } + + actions + { + Global.gravity = 100; + } +} + +rule("Init currentGravity") +{ + event + { + Ongoing - Each Player; + All; + All; + } + + conditions + { + Is Game In Progress == True; + } + + actions + { + Event Player.currentGravity = Global.gravity; + Set Gravity(Event Player, Event Player.currentGravity); + } +} \ No newline at end of file