Back to home

Genji Dash Trainer

J10CF
click to copy
This game is archived.
If you with to unarchive it, click the "restore" button in the options menu.

Category:
Training / Drills / Tools

Author:
Provoxin

Rating:
24

Version:
1.7.1

Posted:
10 months ago

Last updated:
2 days ago

Tags:
genji dash trainer practice ghost

Share this workshop!

Options

Instructions

Practice your dashes! Add 2 bots to Red Team, the smaller the hitbox the harder the game is! First dash at the middle target, then to the one with a skull over it as fast as you can. Everything else is automated!

Features

  • Adjustable difficulty shown in top left. Based on time you have to aim between dashes. (Press Forward and Backward keys to change)
  • Shows Successes / Failures and success rate percentage in the top right
  • Shows time taken to aim on last successful attempt in top left ('Success Time')
  • Target bot is invincible until the center bot is killed

Bonus Features

  • Press Interact to toggle over-the-shoulder 3rd person
  • Press Ultimate to feel like Necros ;) (toggle)

Please send any suggestions, questions, bug reports, etc to Provoxin#5368 on Discord.

variables
{
	player:
		0: angle
		1: necrosMode
		2: timeSinceFirstDash
		3: dashes
		5: fails
		11: lastTime
		14: overTheShoulder
		18: successes
		19: maxTime
		22: warningMessage
}

subroutines
{
	0: reset
	1: resetNoWait
}

rule("sub reset")
{
	event
	{
		Subroutine;
		reset;
	}

	actions
	{
		Teleport(Event Player, Vector(-18.450, 40.400, -86.900));
		Set Facing(Event Player, Direction Towards(Vector(-18.450, 40.400, -86.900), Vector(-23.875, 40.400, -57.775)), To World);
		Start Facing(Event Player, Direction Towards(Vector(-18.450, 40.400, -86.900), Vector(-23.875, 40.400, -57.775)), 10000, To World,
			Direction and Turn Rate);
		Wait(0.200, Ignore Condition);
		Set Player Variable(Event Player, angle, Multiply(Random Real(0, 1), 6.283));
		Teleport(Players In Slot(0, Team 2), World Vector Of(Vector(0, 0, 15), Event Player, Rotation And Translation));
		Stop Facing(Event Player);
		Wait(0.016, Ignore Condition);
		Teleport(Players In Slot(1, Team 2), World Vector Of(Vector(Multiply(Cosine From Radians(Player Variable(Event Player, angle)),
			15), 0, Multiply(Sine From Radians(Player Variable(Event Player, angle)), 15)), Players In Slot(0, Team 2),
			Rotation And Translation));
		Set Ability 1 Enabled(Event Player, True);
	}
}

rule("sub resetNoWait")
{
	event
	{
		Subroutine;
		resetNoWait;
	}

	actions
	{
		Teleport(Event Player, Vector(-18.450, 40.400, -86.900));
		Set Facing(Event Player, Direction Towards(Vector(-18.450, 40.400, -86.900), Vector(-23.875, 40.400, -57.775)), To World);
		Start Facing(Event Player, Direction Towards(Vector(-18.450, 40.400, -86.900), Vector(-23.875, 40.400, -57.775)), 10000, To World,
			Direction and Turn Rate);
		Set Player Variable(Event Player, angle, Multiply(Random Real(0, 1), 6.283));
		Teleport(Players In Slot(0, Team 2), World Vector Of(Vector(0, 0, 15), Event Player, Rotation And Translation));
		Stop Facing(Event Player);
		Wait(0.016, Ignore Condition);
		Teleport(Players In Slot(1, Team 2), World Vector Of(Vector(Multiply(Cosine From Radians(Player Variable(Event Player, angle)),
			15), 0, Multiply(Sine From Radians(Player Variable(Event Player, angle)), 15)), Players In Slot(0, Team 2),
			Rotation And Translation));
		Set Ability 1 Enabled(Event Player, True);
	}
}

rule("init global")
{
	event
	{
		Ongoing - Global;
	}

	actions
	{
		Pause Match Time;
		Set Match Time(0);
		Disable Built-In Game Mode Respawning(All Players(Team 2));
		Create Dummy Bot(Hero(Zenyatta), Team 2, 0, Vector(0, 10000, 0), Vector(0, 0, 0));
		Create Dummy Bot(Hero(Ana), Team 2, 1, Vector(0, 10000, 0), Vector(0, 0, 0));
	}
}

rule("init player")
{
	event
	{
		Ongoing - Each Player;
		Team 1;
		All;
	}

	actions
	{
		Set Player Variable(Event Player, maxTime, 0.500);
		Set Move Speed(Event Player, 0);
		Set Status(Event Player, Null, Phased Out, 9999);
		Create HUD Text(Event Player, String("{0}: {1}", String("{0} {1}", String("Max", Null, Null, Null), String("Time", Null, Null,
			Null), Null), String("{0} sec", Player Variable(Event Player, maxTime), Null, Null), Null), String("{0} - {1}", String(
			"Forward", Null, Null, Null), String("More", Null, Null, Null), Null), String("{0} - {1}", String("Backward", Null, Null,
			Null), String("Less", Null, Null, Null), Null), Left, 0, Blue, White, White, String, Default Visibility);
		Create HUD Text(Event Player, Null, Null, String("{0} {1} {2}", String("{0} / {1}", String("Success", Null, Null, Null), String(
			"Failed", Null, Null, Null), Null), String("{0}:", String("", Null, Null, Null), Null, Null), String("{0} / {1}",
			Player Variable(Event Player, successes), Player Variable(Event Player, fails), Null)), Right, 0, White, White, White, String,
			Default Visibility);
		Create HUD Text(Event Player, Null, Null, String("{0}: {1}", String("{0} {1}", String("Success", Null, Null, Null), String(
			"Average", Null, Null, Null), Null), String("{0}%", Multiply(Divide(Player Variable(Event Player, successes), Add(
			Player Variable(Event Player, successes), Player Variable(Event Player, fails))), 100), Null, Null), Null), Right, 1, White,
			White, White, String, Default Visibility);
		Create HUD Text(Event Player, Null, Null, String("{0}: {1}", String("{0} {1}", String("Success", Null, Null, Null), String("Time",
			Null, Null, Null), Null), Player Variable(Event Player, lastTime), Null), Left, 1, White, White, White, String,
			Default Visibility);
	}
}

rule("init bots")
{
	event
	{
		Ongoing - Each Player;
		Team 2;
		All;
	}

	actions
	{
		Start Facing(Event Player, Direction Towards(Eye Position(Event Player), Eye Position(Players In Slot(0, Team 1))), 10000,
			To World, Direction and Turn Rate);
	}
}

rule("set match time to time elapsed")
{
	event
	{
		Ongoing - Global;
	}

	actions
	{
		Wait(1, Ignore Condition);
		Set Match Time(Add(Match Time, 1));
		Loop;
	}
}

rule("force instakill")
{
	event
	{
		Player Took Damage;
		Team 2;
		All;
	}

	actions
	{
		Kill(Event Player, Attacker);
	}
}

rule("teleport to arena after spawning")
{
	event
	{
		Ongoing - Each Player;
		Team 1;
		All;
	}

	conditions
	{
		Has Spawned(Event Player) == True;
	}

	actions
	{
		Call Subroutine(reset);
		Create Icon(Filtered Array(Filtered Array(Event Player, Compare(Is In Spawn Room(Players In Slot(1, Team 2)), ==, False)), Compare(
			Is Alive(Players In Slot(1, Team 2)), ==, True)), Players In Slot(1, Team 2), Skull, Visible To and Position, Red, True);
	}
}

rule("respawn when all dead or on fail")
{
	event
	{
		Ongoing - Each Player;
		Team 1;
		All;
	}

	conditions
	{
		Count Of(All Players(Team 2)) == 2;
		Or(Is True For All(All Players(Team 2), Compare(Is Dead(Current Array Element), ==, True)), Compare(Player Variable(Event Player,
			dashes), >, 1)) == True;
	}

	actions
	{
		Skip If(Compare(Player Variable(Event Player, dashes), <=, 1), 8);
		Small Message(Event Player, String("Failed", Null, Null, Null));
		Skip If(Compare(Player Variable(Event Player, necrosMode), ==, True), 1);
		Modify Player Variable(Event Player, fails, Add, 1);
		Start Facing(Event Player, Vector Towards(Eye Position(Event Player), Vector(X Component Of(Position Of(Players In Slot(1,
			Team 2))), Y Component Of(Eye Position(Event Player)), Z Component Of(Position Of(Players In Slot(1, Team 2))))), 720,
			To World, Direction and Turn Rate);
		Wait(0.400, Ignore Condition);
		Stop Facing(Event Player);
		Respawn(All Players(Team 2));
		Skip(6);
		Small Message(Event Player, String("Success", Null, Null, Null));
		Skip If(Compare(Player Variable(Event Player, necrosMode), ==, True), 1);
		Modify Player Variable(Event Player, successes, Add, 1);
		Set Ability 1 Enabled(Event Player, False);
		Wait(0.125, Ignore Condition);
		Respawn(All Players(Team 2));
		Teleport(Event Player, Vector(-18.450, 40.400, -86.900));
		Set Facing(Event Player, Direction Towards(Vector(-18.450, 40.400, -86.900), Vector(-23.875, 40.400, -57.775)), To World);
		Start Facing(Event Player, Direction Towards(Vector(-18.450, 40.400, -86.900), Vector(-23.875, 40.400, -57.775)), 10000, To World,
			Direction and Turn Rate);
		Wait(0.200, Ignore Condition);
		Set Player Variable(Event Player, angle, Multiply(Random Real(0, 1), 6.283));
		Teleport(Players In Slot(0, Team 2), World Vector Of(Vector(0, 0, 15), Event Player, Rotation And Translation));
		Stop Facing(Event Player);
		Wait(0.016, Ignore Condition);
		Teleport(Players In Slot(1, Team 2), World Vector Of(Vector(Multiply(Cosine From Radians(Player Variable(Event Player, angle)),
			15), 0, Multiply(Sine From Radians(Player Variable(Event Player, angle)), 15)), Players In Slot(0, Team 2),
			Rotation And Translation));
		Create Icon(All Players(Team 1), Players In Slot(1, Team 2), Skull, Position, Red, True);
		Set Player Variable(Event Player, dashes, 0);
		Set Ability 1 Enabled(Event Player, True);
	}
}

rule("fail if taking too long to dash")
{
	event
	{
		Ongoing - Each Player;
		Team 1;
		All;
	}

	conditions
	{
		Player Variable(Event Player, dashes) == 1;
	}

	actions
	{
		Wait(Add(Player Variable(Event Player, maxTime), 0.700), Abort When False);
		Modify Player Variable(Event Player, dashes, Add, 1);
		Set Ability 1 Enabled(Event Player, False);
	}
}

rule("count dashes")
{
	event
	{
		Ongoing - Each Player;
		Team 1;
		All;
	}

	conditions
	{
		Is Using Ability 1(Event Player) == True;
	}

	actions
	{
		Skip If(Compare(Player Variable(Event Player, dashes), ==, 0), 1);
		Wait(0.400, Ignore Condition);
		Modify Player Variable(Event Player, dashes, Add, 1);
	}
}

rule("count dashes failsafe")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Is Using Ability 1(Event Player) == True;
	}

	actions
	{
		Wait(0.800, Abort When False);
		Modify Player Variable(Event Player, dashes, Add, 1);
	}
}

rule("start tracking time between dashes")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Player Variable(Event Player, dashes) == 1;
	}

	actions
	{
		Chase Player Variable At Rate(Event Player, timeSinceFirstDash, 100000, 1, None);
	}
}

rule("stop tracking time between dashes & store time if successful")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Or(Is True For All(All Players(Team 2), Compare(Is Dead(Current Array Element), ==, True)), Compare(Player Variable(Event Player,
			dashes), >, 1)) == True;
	}

	actions
	{
		Skip If(Compare(Player Variable(Event Player, dashes), >, 1), 1);
		Set Player Variable(Event Player, lastTime, Subtract(Player Variable(Event Player, timeSinceFirstDash), 0.700));
		Skip If(Compare(Player Variable(Event Player, lastTime), >=, 0), 1);
		Set Player Variable(Event Player, lastTime, 0.001);
		Stop Chasing Player Variable(Event Player, timeSinceFirstDash);
		Set Player Variable(Event Player, timeSinceFirstDash, 0);
	}
}

rule("set target 2 invincible true")
{
	event
	{
		Ongoing - Each Player;
		Team 2;
		All;
	}

	conditions
	{
		Is Dead(Players In Slot(0, Team 2)) == False;
	}

	actions
	{
		Set Status(Players In Slot(1, Team 2), Null, Invincible, 10000);
	}
}

rule("set target 2 invincible false")
{
	event
	{
		Ongoing - Each Player;
		Team 2;
		All;
	}

	conditions
	{
		Is Dead(Players In Slot(0, Team 2)) == True;
	}

	actions
	{
		Clear Status(Players In Slot(1, Team 2), Invincible);
	}
}

rule("Forward / Backward to change max time")
{
	event
	{
		Ongoing - Each Player;
		Team 1;
		All;
	}

	conditions
	{
		Throttle Of(Event Player) != Vector(0, 0, 0);
	}

	actions
	{
		Skip If(Compare(Throttle Of(Event Player), !=, Forward), 1);
		Modify Player Variable(Event Player, maxTime, Add, 0.050);
		Skip If(Or(Compare(Throttle Of(Event Player), !=, Backward), Compare(Player Variable(Event Player, maxTime), <=, 0)), 1);
		Modify Player Variable(Event Player, maxTime, Subtract, 0.050);
		Wait(0.250, Ignore Condition);
		Loop If Condition Is True;
	}
}

rule("reset bots or player if they fall off roof")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Vertical Speed Of(Event Player) <= -5;
		Y Component Of(Position Of(Event Player)) <= 36;
	}

	actions
	{
		Set Player Variable(Event Player, dashes, 0);
		Stop Chasing Player Variable(Event Player, timeSinceFirstDash);
		Set Player Variable(Event Player, timeSinceFirstDash, 0);
		Skip If(Compare(Team Of(Event Player), ==, Team 2), 5);
		Kill(Event Player, Null);
		Respawn(Event Player);
		Call Subroutine(resetNoWait);
		Set Status(Event Player, Null, Phased Out, 9999);
		Abort;
		Kill(All Players(Team 2), Null);
	}
}

rule("toggle over the shoulder cam")
{
	event
	{
		Ongoing - Each Player;
		Team 1;
		All;
	}

	conditions
	{
		Is Button Held(Event Player, Interact) == True;
	}

	actions
	{
		Skip If(Compare(Player Variable(Event Player, overTheShoulder), ==, True), 2);
		Set Player Variable(Event Player, overTheShoulder, True);
		Abort;
		Stop Camera(Event Player);
		Set Player Variable(Event Player, overTheShoulder, False);
	}
}

rule("over the shoulder cam")
{
	event
	{
		Ongoing - Each Player;
		Team 1;
		All;
	}

	conditions
	{
		Player Variable(Event Player, overTheShoulder) == True;
	}

	actions
	{
		Start Camera(Event Player, Add(World Vector Of(Vector(-0.150, 1.500, 0.700), Event Player, Rotation And Translation), Multiply(
			Facing Direction Of(Event Player), -1)), Multiply(Facing Direction Of(Event Player), 1000), 50);
	}
}

rule("toggle autoaim")
{
	event
	{
		Ongoing - Each Player;
		Team 1;
		All;
	}

	conditions
	{
		Match Time >= 10;
		Is Button Held(Event Player, Ultimate) == True;
	}

	actions
	{
		Skip If(Compare(Player Variable(Event Player, necrosMode), ==, True), 3);
		Set Player Variable(Event Player, necrosMode, True);
		Small Message(Event Player, String("{0} {1}", String("Hack", Null, Null, Null), String("On", Null, Null, Null), Null));
		Abort;
		Set Player Variable(Event Player, necrosMode, False);
		Small Message(Event Player, String("{0} {1}", String("Hack", Null, Null, Null), String("Off", Null, Null, Null), Null));
	}
}

rule("autoaim")
{
	event
	{
		Ongoing - Each Player;
		Team 1;
		All;
	}

	conditions
	{
		Player Variable(Event Player, necrosMode) == True;
		Player Variable(Event Player, dashes) == 1;
	}

	actions
	{
		Wait(0.268, Ignore Condition);
		Start Facing(Event Player, Vector Towards(Eye Position(Event Player), Eye Position(Players In Slot(1, Team 2))), Raise To Power(10,
			100), To World, Direction and Turn Rate);
		Wait(0.032, Ignore Condition);
		Press Button(Event Player, Ability 1);
		Wait(0.032, Ignore Condition);
		Stop Facing(Event Player);
	}
}

disabled rule("create add ai warning")
{
	event
	{
		Ongoing - Each Player;
		Team 1;
		All;
	}

	conditions
	{
		Count Of(All Players(Team 2)) != 2;
	}

	actions
	{
		Destroy All HUD Text;
		Set Invisible(All Players(Team 2), All);
		Set Status(All Players(Team 2), Null, Phased Out, 10000);
		Wait(0.016, Ignore Condition);
		Create HUD Text(Event Player, String("{0} {1}", String("{0} {1} {2}", String("Connect", Null, Null, Null), Subtract(2, Count Of(
			All Players(Team 2))), String("Participants", Null, Null, Null)), String("{0} and {1}", String("{0} {1} {2}", String("On",
			Null, Null, Null), String("Team", Null, Null, Null), 2), String("Try Again", Null, Null, Null), Null), Null), Null, Null, Top,
			0, Red, White, White, String, Default Visibility);
		Set Player Variable(Event Player, warningMessage, Last Text ID);
		Set Ability 1 Enabled(Event Player, False);
		Disallow Button(Event Player, Jump);
		Disallow Button(Event Player, Crouch);
	}
}

disabled rule("create restart warning")
{
	event
	{
		Ongoing - Each Player;
		Team 1;
		All;
	}

	conditions
	{
		Player Variable(Event Player, warningMessage) != Null;
		Count Of(All Players(Team 2)) == 2;
	}

	actions
	{
		Destroy HUD Text(Player Variable(Event Player, warningMessage));
		Create HUD Text(Event Player, String("{0} and {1}", String("Exit", Null, Null, Null), String("{0} {1}", String("Start", Null, Null,
			Null), String("Game", Null, Null, Null), Null), Null), Null, Null, Top, 0, Red, White, White, String, Default Visibility);
		Set Invisible(All Players(Team 2), All);
		Set Status(All Players(Team 2), Null, Stunned, 10000);
		Set Status(All Players(Team 2), Null, Phased Out, 10000);
	}
}

Changelog

2 days ago 1.7.1

Fixed bots not being stunned by replacing with dummy bots. Behind the scenes, the gamemode is currently pretty scuffed, but I might work on making it better in the future.

J10CF
click to copy
9 months ago 1.6.5

Added Snippet to Workshop page, normalized capitalization of rules

D3FVK
click to copy
10 months ago 1.6.5

Adjustments -

  • When there are not 2 bots or the game must be restarted, bots are turned invisible and phased out

  • There is now a separate message displayed to restart the game when 2 bots are added

Behind The Scenes -

  • Added a rule for the creation of a HUD text which tells the player to restart the game when there are 2 bots

GT62P
click to copy
10 months ago 1.6.3

New Features -

  • Match time is now time elapsed

  • A warning is now displayed if there are not 2 bots, telling the player to add bots and restart the game

Fixes -

  • Fixed another instance of the player being able to mess up bot spawns in some circumstances

  • Teleporting back to the arena after dying is now smoother

  • Fails and successes will no longer track if there are not 2 bots

Behind The Scenes -

  • Merged initialization rules and renamed

  • Merged tele on death and tele on spawn

7GKVA
click to copy
10 months ago 1.4.4

  • Fixed a bug where if the player fell off the stage, Success Time would not be reset to zero, and would carry into the next attempt

  • Changed the name of some rules to make it more clear what they do

3V3DR
click to copy
10 months ago 1.4.3

  • Fixed Success Time sometimes being below 0

  • Fixed the player being able to mess up bot spawns in some circumstances

S4ZD6
click to copy
10 months ago 1.4.1

This revision contains no notes

J5D4W
click to copy