Description: "This mode is based on Player Destruction from Team Fortress 2. You must collect the enemy team's orbs by killing them. You must then deposit those orbs in the beam. The beam spawns periodically. Team leaders have the most resources out of the team and are visible everywhere. First team to reach the goal score wins. Created by Block#12425. Version 1.2.7. Code: ZKBQY"
}
lobby
{
Max Spectators: 6
Return To Lobby: Never
Team Balancing: After A Game
}
modes
{
Team Deathmatch
{
enabled maps
{
Lijiang Control Center
Lijiang Control Center Lunar New Year
Lijiang Garden
Lijiang Garden Lunar New Year
Lijiang Night Market
Lijiang Night Market Lunar New Year
Nepal Sanctum
Nepal Shrine
Nepal Village
Oasis City Center
Oasis Gardens
Oasis University
}
}
General
{
Mercy Resurrect Counteracts Kills: Off
Score To Win: 1
Spawn Health Packs: Enabled
}
}
}
variables
{
global:
0: beamPositionStart
1: goalScore
2: isBeamActive
3: orbRadius
4: ringPositionEnd
5: beamRadius
6: collectPhaseTime
7: roundsLeft
8: depositPhaseTime
9: phaseCheck
10: team1Leader
11: team2Leader
12: team1OrbsArray
13: team2OrbsArray
14: team1OrbPositions
15: team2OrbPositions
16: team1OrbValues
17: i
18: beamMovementRate
19: team2OrbValues
20: ringPositionStart
21: team2Spawn
22: team1Spawn
23: j
24: chasedVariable
25: beamPositionEnd
26: spawnProtectionTime
27: initialAssemblyTime
28: hiddenLocation
29: stringSubtitle
31: stringProject
33: stringProjectLink
34: stringCode
35: stringCreator
36: stringVersion
37: stringDepositOrbs
38: stringCollectOrbs
39: stringYouAreTeamLeader
40: stringTeamLeader
41: stringYourTeamPossessive
42: stringEnemyTeamPossessive
43: stringTotalOrbs
44: stringCollected
45: stringOrbs
46: stringDepositedOrb
47: stringYouWereHealed
48: stringKilledTeamLeader
49: stringRoundsLeft
50: stringGoalScore
51: stringRespawnDisabled
52: stringFinalRound
53: stringSpawnProtectionOff
54: stringBeamStart
55: stringBeamEnd
player:
0: spawnProtected
1: closestOrb
2: previousOrbValue
3: valueOfOrb
4: respawnDisabled
8: tempIndexValue
12: isBeingRevived
13: deathPosition
14: playerBeingRevived
15: hasSpawnedOnce
}
subroutines
{
0: matchSetup
1: hudSetup
2: goalScoreSetup
3: orbSetup
4: spawnSetup1
5: spawnSetup2
6: depositOrb
7: mapSetupOasisUniversity
8: mapSetupOasisGarden
9: mapSetupOasisCityCenter
10: mapSetupNepalSanctum
11: mapSetupNepalShrine
12: mapSetupNepalVillage
13: mapSetupLijiangControlCenter
14: mapSetupLijiangGarden
15: mapSetupLijiangNightMarket
}
disabled rule("PLAYER DESTRUCTION. Version 1.2.6. Created by Block#12425. Additional credits found on project site below.")
"After that this if else test will determine how many players exist in the match after the wait. It will then set the goal score depending on the number of players."
If(Count Of(All Players(All Teams)) < 4);
Global.goalScore = 8;
Else If(Count Of(All Players(All Teams)) < 6);
Global.goalScore = 16;
Else If(Count Of(All Players(All Teams)) < 8);
Global.goalScore = 24;
Else If(Count Of(All Players(All Teams)) < 10);
Global.goalScore = 32;
Else If(Count Of(All Players(All Teams)) < 12);
Global.goalScore = 40;
Else;
Global.goalScore = 48;
End;
"DEBUG PURPOSES ONLY. Disable for normal play."
disabled Global.goalScore = 1;
}
}
rule("Block#12425 - Orb Setup")
{
event
{
Subroutine;
orbSetup;
}
actions
{
"These actions create 6 orb effects for team 1 and 6 orb effects for team 2."
Create Effect(All Players(All Teams), Orb, Color(Team 1), Global.team1OrbPositions[0], 0.300, Visible To Position and Radius);
Create Effect(All Players(All Teams), Orb, Color(Team 1), Global.team1OrbPositions[1], 0.300, Visible To Position and Radius);
Create Effect(All Players(All Teams), Orb, Color(Team 1), Global.team1OrbPositions[2], 0.300, Visible To Position and Radius);
Create Effect(All Players(All Teams), Orb, Color(Team 1), Global.team1OrbPositions[3], 0.300, Visible To Position and Radius);
Create Effect(All Players(All Teams), Orb, Color(Team 1), Global.team1OrbPositions[4], 0.300, Visible To Position and Radius);
Create Effect(All Players(All Teams), Orb, Color(Team 1), Global.team1OrbPositions[5], 0.300, Visible To Position and Radius);
Create Effect(All Players(All Teams), Orb, Color(Team 2), Global.team2OrbPositions[0], 0.300, Visible To Position and Radius);
Create Effect(All Players(All Teams), Orb, Color(Team 2), Global.team2OrbPositions[1], 0.300, Visible To Position and Radius);
Create Effect(All Players(All Teams), Orb, Color(Team 2), Global.team2OrbPositions[2], 0.300, Visible To Position and Radius);
Create Effect(All Players(All Teams), Orb, Color(Team 2), Global.team2OrbPositions[3], 0.300, Visible To Position and Radius);
Create Effect(All Players(All Teams), Orb, Color(Team 2), Global.team2OrbPositions[4], 0.300, Visible To Position and Radius);
Create Effect(All Players(All Teams), Orb, Color(Team 2), Global.team2OrbPositions[5], 0.300, Visible To Position and Radius);
"These next actions set the default orb positions for both team 1 and team 2."
"This sets the ring position (at times the start position is not the same as the ring position, as the beam should move in a line parallel to the ground, but the ground can be uneven and the rings need to match that)."
"This calculates the beam movement speed based on the deposit phase time and the distance the beam needs to cover. This ensures that the beam always hits the end position at 0 seconds left."
Global.stringRespawnDisabled = Custom String("Please wait 5 seconds for respawn");
}
}
disabled rule("------ Player Setup ------")
{
event
{
Ongoing - Global;
}
}
rule("Block#12425 - Spawn Player (Team 1)")
{
event
{
Ongoing - Each Player;
Team 1;
All;
}
conditions
{
Has Spawned(Event Player) == True;
Is Alive(Event Player) == True;
Is Game In Progress == True;
Event Player.spawnProtected == True;
}
actions
{
"Teleports the player to the respective team spawn."
Teleport(Event Player, Global.team1Spawn);
Wait(0.120, Ignore Condition);
"Now the spawn subroutine is called, which is split into two parts. Part 2 is also used for the Mercy ressurection."
Call Subroutine(spawnSetup1);
"If the spawn isn't interrupted by a Mercy ressurection, then part 2 of the spawn setup is run."
Wait(Global.spawnProtectionTime, Abort When False);
Call Subroutine(spawnSetup2);
}
}
rule("Block#12425 - Spawn Player (Team 2)")
{
event
{
Ongoing - Each Player;
Team 2;
All;
}
conditions
{
Has Spawned(Event Player) == True;
Is Alive(Event Player) == True;
Is Game In Progress == True;
Event Player.spawnProtected == True;
}
actions
{
"See Team 1 Spawn."
Teleport(Event Player, Global.team2Spawn);
Wait(0.120, Ignore Condition);
Call Subroutine(spawnSetup1);
Wait(Global.spawnProtectionTime, Abort When False);
Call Subroutine(spawnSetup2);
}
}
rule("Block#12425 - Spawn Setup Part 1 Subroutine")
{
event
{
Subroutine;
spawnSetup1;
}
actions
{
"Sets the player facing towards the start position of the beam."
Set Facing(Event Player, Direction Towards(Position Of(Event Player), Global.beamPositionStart), To World);
"Sets up spawn protection."
Set Status(Event Player, Null, Invincible, 9999);
Set Status(Event Player, Null, Phased Out, 9999);
Set Invisible(Event Player, Enemies);
}
}
rule("Block#12425 - Spawn Setup Part 2 Subroutine")
{
event
{
Subroutine;
spawnSetup2;
}
actions
{
"Removes spawn protection."
Clear Status(Event Player, Invincible);
Clear Status(Event Player, Phased Out);
Set Invisible(Event Player, None);
Small Message(Event Player, Global.stringSpawnProtectionOff);
Event Player.spawnProtected = False;
}
}
rule("Block#12425 - Player Joined Setup")
{
event
{
Player Joined Match;
All;
All;
}
actions
{
"Intializes the proper player variables upon player joined."
Event Player.isBeingRevived = False;
Event Player.spawnProtected = True;
Event Player.respawnDisabled = False;
}
}
rule("Block#12425 - Player Died Self-Intiated Respawn Setup")
{
event
{
Player Died;
All;
All;
}
conditions
{
Is Game In Progress == True;
Is Alive(Event Player) == False;
}
actions
{
"This rule sets up the player for respawn."
Event Player.spawnProtected = True;
Event Player.respawnDisabled = True;
"This disallow action forces the player to wait for 5 seconds before they can respawn again. This allows the game to have a high respawn time for character select while forcing a specified respawn time required for TDM."
Disallow Button(Event Player, Button(Jump));
Wait(5, Abort When False);
Allow Button(Event Player, Button(Jump));
Event Player.respawnDisabled = False;
}
}
rule("Block#12425 - Jump Key Check")
{
event
{
Ongoing - Each Player;
All;
All;
}
conditions
{
Is Game In Progress == True;
Is Alive(Event Player) == True;
Has Spawned(Event Player) == True;
}
actions
{
"In case the jump key didn't get enabled from the other rules."
Allow Button(Event Player, Button(Jump));
Event Player.respawnDisabled = False;
}
}
rule("Block#12425 - Respawn Disabled Small Message")
{
event
{
Ongoing - Each Player;
All;
All;
}
conditions
{
Is Game In Progress == True;
Is Alive(Event Player) == False;
Event Player.respawnDisabled == True;
Is Button Held(Event Player, Button(Jump)) == True;
}
actions
{
Small Message(Event Player, Global.stringRespawnDisabled);
}
}
disabled rule("------ Game Cycles ------")
{
event
{
Ongoing - Global;
}
}
rule("Block#12425 - First Round")
{
event
{
Ongoing - Global;
}
conditions
{
Is Game In Progress == True;
}
actions
{
"This rule is for the first round. Not as many actions are ran, because it isn't needed."
Global.isBeamActive = False;
Set Match Time(Global.collectPhaseTime);
Disable Built-In Game Mode Music;
}
}
rule("Block#12425 - Collect Orb Phase")
{
event
{
Ongoing - Global;
}
conditions
{
Is Game In Progress == True;
Global.phaseCheck == True;
Match Time <= 0;
}
actions
{
"Beam is disabled."
Global.isBeamActive = False;
"If that was the last round, the match time set is skipped so the game ends."
Skip If(Global.roundsLeft == 1, 1);
Set Match Time(Global.collectPhaseTime);
"Beam disappears with some effects."
Play Effect(All Players(All Teams), Debuff Impact Sound, Color(White), Global.ringPositionEnd, 200);
Play Effect(All Players(All Teams), Ring Explosion, Color(Turquoise), Global.ringPositionEnd + Vector(0, 0.200, 0),
Global.beamRadius * 3);
"Beam position is no longer chased."
Stop Chasing Global Variable(chasedVariable);
"Round is subtracted by one."
Global.roundsLeft -= 1;
"The current beam position is set to under the map so filtered arrays aren't needed."
Global.chasedVariable = Global.hiddenLocation;
Big Message(All Players(All Teams), Global.stringCollectOrbs);
Wait(0.250, Ignore Condition);
"This phaseCheck variable ensures that the deposit phase isn't ran immediately afterwards."
Global.phaseCheck = False;
}
}
rule("Block#12425 - Deposit Orb Phase")
{
event
{
Ongoing - Global;
}
conditions
{
Is Game In Progress == True;
Global.phaseCheck == False;
Match Time <= 0;
}
actions
{
"Beam is turned on."
Global.isBeamActive = True;
"Beam is teleported to the start position."
Global.chasedVariable = Global.beamPositionStart;
"Time is set."
Set Match Time(Global.depositPhaseTime);
"Now the beam position is chased again."
Chase Global Variable At Rate(chasedVariable, Global.beamPositionEnd, Global.beamMovementRate, Destination and Rate);
"When the beam spawns, the effects are created to indicate its presence."
Play Effect(All Players(All Teams), Ring Explosion Sound, Color(White), Global.ringPositionStart, 200);
Play Effect(All Players(All Teams), Ring Explosion, Color(Turquoise), Global.ringPositionStart + Vector(0, 0.200, 0),
Global.beamRadius * 3);
Big Message(All Players(All Teams), Global.stringDepositOrbs);
Wait(0.250, Ignore Condition);
"This ensures the collect phase isn't ran after this is executed."
"The temporal index value of the orb is also stored."
Event Player.tempIndexValue = Index Of Array Value(Global.team1OrbPositions, Event Player.closestOrb);
"Now, the orb value of the orb being collected is being added to the player's total orb count. Since this is checking for a friendly orb pickup, 1 point is subtracted so that teammates cannot farm their own orbs."
"This checks if the orb collected caused the players orb count to reduce instead of increasing. This bug occurs since multiple players can simutaneously pick up the same orb and only one gets the value."
rule("Block#12425 - Deposit Orb in Beam (Team 1)")
{
event
{
Ongoing - Each Player;
Team 1;
All;
}
conditions
{
Is Alive(Event Player) == True;
Global.isBeamActive == True;
Y Component Of(Position Of(Event Player)) >= Y Component Of(Global.chasedVariable);
Global.team1OrbsArray[Slot Of(Event Player)] > 0;
Distance Between(Vector(X Component Of(Global.chasedVariable), Y Component Of(Position Of(Event Player)), Z Component Of(
Global.chasedVariable)), Position Of(Event Player)) <= Global.beamRadius;
}
actions
{
"Now, when a player is in the beam with more than one orb, 1 orb is deposited from the players total (after 1 seconds of standing consistently in the beam.)"
Is True For All(Global.team2OrbsArray, Global.team2OrbsArray[Slot Of(Event Player)] >= Current Array Element) == True;
}
actions
{
"See Team 1 Leader Creation."
Global.team2Leader = Event Player;
Small Message(Event Player, Global.stringYouAreTeamLeader);
}
}
disabled rule("------ Orbs Checks ------")
{
event
{
Ongoing - Global;
}
}
rule("Block#12425 - Player Left Match Orb Check")
{
event
{
Player Left Match;
All;
All;
}
conditions
{
Is Game In Progress == True;
}
actions
{
"If a player left the match, an orb value reset must occur for said player. However, the game doesn't know which player. These two for loops will check to see if the player exists in the certain slot."
For Global Variable(i, 0, Count Of(Global.team1OrbsArray), 1);
If(Entity Exists(Players In Slot(Global.i, Team 1)) == False);
"And if the player doesn't, that orb count is set to 0. In other words, one of these will be the player that disconnected, and their value is set to 0."
Global.team1OrbsArray[Global.i] = 0;
End;
End;
For Global Variable(i, 0, Count Of(Global.team2OrbsArray), 1);
If(Entity Exists(Players In Slot(Global.i, Team 2)) == False);
Global.team2OrbsArray[Global.i] = 0;
End;
End;
}
}
rule("Block#12425 - Player Joined Match Orb Check")
{
event
{
Player Joined Match;
All;
All;
}
conditions
{
Is Game In Progress == True;
}
actions
{
"Just like the rule above, if a player joins the match, it also double checks if there are excess orb count stored in the arrays."
For Global Variable(j, 0, Count Of(Global.team1OrbsArray), 1);
If(Entity Exists(Players In Slot(Global.j, Team 1)) == False);
Global.team1OrbsArray[Global.j] = 0;
End;
End;
For Global Variable(j, 0, Count Of(Global.team2OrbsArray), 1);
If(Entity Exists(Players In Slot(Global.j, Team 2)) == False);
"If the orb is not at the hidden location, that means it is being used on the map. This checks if all orbs are being used. In gameplay, the max a player can see is 5 orbs for each team, so a six orb exists to help transition the orb reset."
Is True For All(Global.team1OrbPositions, Current Array Element != Global.hiddenLocation) == True;
}
actions
{
"If a sixth orb is created, the oldest orb that is present on the map is reset."
Modify Global Variable(team1OrbPositions, Append To Array, Global.hiddenLocation);
Modify Global Variable(team1OrbPositions, Remove From Array By Index, 0);
Modify Global Variable(team1OrbValues, Append To Array, 0);
Modify Global Variable(team1OrbValues, Remove From Array By Index, 0);
"If it failed, this wait time is long enough to ensure that it didn't falsely detect that it failed. If it succeeded, then this wait action will be cancelled."
"If either team reaches the goal score, the game mode completion is enabled. Since the winning score is hardcoded as 1 in the custom game settings, this will end the game."
Enable Built-In Game Mode Completion;
}
}
rule("Block#12425 - All Rounds Completed")
{
event
{
Ongoing - Global;
}
conditions
{
Global.roundsLeft == 0;
Is Game In Progress == True;
}
actions
{
"If all rounds are over, this is enabled so that the time can end the game."