From b3a9048344b569a0e98c3f1af49da7f2a359f724 Mon Sep 17 00:00:00 2001
From: Luna R
Date: Sat, 5 Feb 2022 19:56:36 +0000
Subject: [PATCH 01/11] add script to trim trailing whitespace from all files
---
src/ai.ow | 100 ++++--
src/ai.owh | 553 +++++++++++++++++++++---------
tools/trim_trailing_whitespace.sh | 6 +
3 files changed, 480 insertions(+), 179 deletions(-)
create mode 100755 tools/trim_trailing_whitespace.sh
diff --git a/src/ai.ow b/src/ai.ow
index f41a6e5..11a8940 100644
--- a/src/ai.ow
+++ b/src/ai.ow
@@ -52,12 +52,18 @@ rule("AI Aim Calculation Loop")
actions
{
- // Distance between the ray cast of the bot's facing direction and the position of the Player
- Event Player.ai_RetCastDistance = Distance Between(
- Ray Cast Hit Position(
+ // Distance between the ray cast of the bot's facing direction and the
+ // position of the Player
+ Event Player.ai_RetCastDistance = Distance Between
+ (
+ Ray Cast Hit Position
+ (
Eye Position(Event Player),
Eye Position(Event Player) + Facing Direction Of(Event Player)
- * Distance Between(Event Player, Players In Slot(Slot Of(Event Player), Team 1)),
+ * Distance Between
+ (
+ Event Player, Players In Slot(Slot Of(Event Player), Team 1)
+ ),
All Players(Team 1),
Event Player,
True
@@ -112,7 +118,8 @@ rule("AI Aim Flick")
Event Player.ai_AIEnabled == True;
Event Player.ai_CnAim == True;
Players In Slot(Slot Of(Event Player), Team 1).p_Difficulty >= 3;
- Event Player.ai_RetCastDistance > 3 - Players In Slot(Slot Of(Event Player), Team 1).p_Difficulty * 0.250;
+ Event Player.ai_RetCastDistance > 3
+ - Players In Slot(Slot Of(Event Player), Team 1).p_Difficulty * 0.250;
}
actions
@@ -139,7 +146,8 @@ rule("AI Attack Melee")
Event Player.ai_AIEnabled == True;
Event Player.ai_CnAttack == True;
Is Alive(Event Player) == True;
- Distance Between(Event Player, Players In Slot(Slot Of(Event Player), Team 1)) < 2.500;
+ Distance Between
+ (Event Player, Players In Slot(Slot Of(Event Player), Team 1)) < 2.500;
Event Player.ai_RetCastDistance <= 2;
Health(Players In Slot(Slot Of(Event Player), Team 1)) <= 30;
Health(Players In Slot(Slot Of(Event Player), Team 1)) > 0;
@@ -414,7 +422,8 @@ rule("AI Movement WASD Strafe On Dmg")
Event Player.bot_MoveWASDEnabled == True;
Event Player.ai_HeroInitialized == True;
Is Alive(Event Player) == True;
- Distance Between(Event Player, Players In Slot(Slot Of(Event Player), Team 1))
+ Distance Between
+ (Event Player, Players In Slot(Slot Of(Event Player), Team 1))
> Event Player.ai_OptimalDistance + Event Player.ai_StrafeDistanceMod;
Event Damage > 25;
}
@@ -423,7 +432,8 @@ rule("AI Movement WASD Strafe On Dmg")
{
If(Random Real(0, 1) < 0.100 + Event Player.ai_ChanceMod);
Call Subroutine(aiSub_ReactionDelay);
- Event Player.bot_ThrottleDir = Random Value In Array(Global.c_MoveDir_Strafe);
+ Event Player.bot_ThrottleDir
+ = Random Value In Array(Global.c_MoveDir_Strafe);
Start Rule(botSub_MoveWASD, Restart Rule);
End;
}
@@ -444,18 +454,45 @@ rule("AI Movement WASD Move Closer")
Event Player.bot_MoveWASDEnabled == True;
Event Player.ai_HeroInitialized == True;
Is Alive(Event Player) == True;
- Distance Between(Event Player, Vector(X Component Of(Position Of(Players In Slot(Slot Of(Event Player), Team 1))), 0,
- Z Component Of(Position Of(Players In Slot(Slot Of(Event Player), Team 1))))) >= Event Player.ai_OptimalDistance;
+ Distance Between
+ (
+ Event Player,
+ Vector
+ (
+ X Component Of
+ (Position Of(Players In Slot(Slot Of(Event Player), Team 1))),
+ 0,
+ Z Component Of
+ (Position Of(Players In Slot(Slot Of(Event Player), Team 1)))
+ )
+ )
+ >= Event Player.ai_OptimalDistance;
}
actions
{
- If(Distance Between(Event Player, Players In Slot(Slot Of(Event Player), Team 1))
- > Event Player.ai_OptimalDistance + Event Player.ai_StrafeDistanceMod);
- Event Player.bot_ThrottleDir = Random Value In Array(Remove From Array(Global.c_MoveDir_Forward, Array(Left, Right,
- Event Player.bot_ThrottleDir)));
+ If
+ (
+ Distance Between
+ (Event Player, Players In Slot(Slot Of(Event Player), Team 1))
+ > Event Player.ai_OptimalDistance + Event Player.ai_StrafeDistanceMod
+ );
+ Event Player.bot_ThrottleDir
+ = Random Value In Array
+ (
+ Remove From Array
+ (
+ Global.c_MoveDir_Forward,
+ Array(Left, Right, Event Player.bot_ThrottleDir)
+ )
+ );
Else;
- Event Player.bot_ThrottleDir = Random Value In Array(Remove From Array(Global.c_MoveDir_Forward, Event Player.bot_ThrottleDir));
+ Event Player.bot_ThrottleDir
+ = Random Value In Array
+ (
+ Remove From Array
+ (Global.c_MoveDir_Forward, Event Player.bot_ThrottleDir)
+ );
End;
Call Subroutine(botSub_MoveWASD);
Loop If Condition Is True;
@@ -477,13 +514,29 @@ rule("AI Movement WASD Move Farther")
Event Player.bot_MoveWASDEnabled == True;
Event Player.ai_HeroInitialized == True;
Is Alive(Event Player) == True;
- Distance Between(Event Player, Vector(X Component Of(Position Of(Players In Slot(Slot Of(Event Player), Team 1))), 0,
- Z Component Of(Position Of(Players In Slot(Slot Of(Event Player), Team 1))))) < Event Player.ai_OptimalDistance;
+ Distance Between
+ (
+ Event Player,
+ Vector
+ (
+ X Component Of
+ (Position Of(Players In Slot(Slot Of(Event Player), Team 1))),
+ 0,
+ Z Component Of
+ (Position Of(Players In Slot(Slot Of(Event Player), Team 1)))
+ )
+ )
+ < Event Player.ai_OptimalDistance;
}
actions
{
- Event Player.bot_ThrottleDir = Random Value In Array(Remove From Array(Global.c_MoveDir_Backward, Event Player.bot_ThrottleDir));
+ Event Player.bot_ThrottleDir
+ = Random Value In Array
+ (
+ Remove From Array
+ (Global.c_MoveDir_Backward, Event Player.bot_ThrottleDir)
+ );
Call Subroutine(botSub_MoveWASD);
Loop If Condition Is True;
}
@@ -502,8 +555,15 @@ rule("AI Optimal Distance Default Resize")
{
Event Player.ai_AIEnabled == True;
Is Alive(Event Player) == True;
- Distance Between(Event Player, Players In Slot(Slot Of(Event Player), Team 1).p_HomeVector) >= Players In Slot(Slot Of(
- Event Player), Team 1).p_EnemyDistanceMax - 2.500;
+
+ Distance Between
+ (
+ Event Player,
+ Players In Slot(Slot Of(Event Player), Team 1).p_HomeVector
+ )
+ >=
+ Players In Slot(Slot Of(Event Player), Team 1).p_EnemyDistanceMax
+ - 2.500;
}
actions
diff --git a/src/ai.owh b/src/ai.owh
index 74e4080..1598789 100644
--- a/src/ai.owh
+++ b/src/ai.owh
@@ -11,7 +11,8 @@ rule("aiSub_EnableAI")
Call Subroutine(allSub_WaitForFrame);
Clear Status(Players In Slot(Slot Of(Event Player), Team 2), Unkillable);
Players In Slot(Slot Of(Event Player), Team 2).bot_MoveWASDEnabled = True;
- Players In Slot(Slot Of(Event Player), Team 2).bot_MoveCrouchEnabled = True;
+ Players In Slot(
+ Slot Of(Event Player), Team 2).bot_MoveCrouchEnabled = True;
Players In Slot(Slot Of(Event Player), Team 2).bot_MoveJumpEnabled = True;
Players In Slot(Slot Of(Event Player), Team 2).ai_AIEnabled = True;
Call Subroutine(aiSub_FacingReset);
@@ -28,8 +29,12 @@ rule("aiSub_ReactionDelay")
actions
{
- Wait(Random Real(Players In Slot(Slot Of(Event Player), Team 2).ai_ReactionTime / 4, Players In Slot(Slot Of(Event Player), Team 2)
- .ai_ReactionTime), Ignore Condition);
+ Wait(
+ Random Real(
+ Players In Slot(Slot Of(Event Player), Team 2).ai_ReactionTime / 4,
+ Players In Slot(Slot Of(Event Player), Team 2).ai_ReactionTime),
+ Ignore Condition
+ );
}
}
@@ -43,15 +48,24 @@ rule("aiSub_ButtonsReset")
actions
{
- Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2), Button(Primary Fire));
- Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2), Button(Secondary Fire));
- Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2), Button(Ability 1));
- Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2), Button(Ability 2));
- Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2), Button(Ultimate));
- Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2), Button(Jump));
- Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2), Button(Crouch));
- Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2), Button(Melee));
- Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2), Button(Reload));
+ Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2),
+ Button(Primary Fire));
+ Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2),
+ Button(Secondary Fire));
+ Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2),
+ Button(Ability 1));
+ Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2),
+ Button(Ability 2));
+ Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2),
+ Button(Ultimate));
+ Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2),
+ Button(Jump));
+ Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2),
+ Button(Crouch));
+ Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2),
+ Button(Melee));
+ Stop Holding Button(Players In Slot(Slot Of(Event Player), Team 2),
+ Button(Reload));
Wait(1 / 60, Ignore Condition);
}
}
@@ -87,13 +101,18 @@ rule("aiSub_FacingStart")
Direction From Angles(
Horizontal Angle Towards(
Players In Slot(Slot Of(Event Player), Team 2),
- Eye Position(Players In Slot(Slot Of(Event Player), Team 1)) - Vector(0, 0.250, 0)
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 1))
+ - Vector(0, 0.250, 0)
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModX,
Vertical Angle From Direction(
Direction Towards(
- Eye Position(Players In Slot(Slot Of(Event Player), Team 2)),
- Eye Position(Players In Slot(Slot Of(Event Player), Team 1)) - Vector(0, 0.250, 0)
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 1))
+ - Vector(0, 0.250, 0)
)
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModY
@@ -104,20 +123,25 @@ rule("aiSub_FacingStart")
);
// Head
- Else If(Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 1);
- Start Facing(
+ Else If(
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 1);
+
+ Start Facing(
Players In Slot(Slot Of(Event Player), Team 2),
Direction From Angles(
Horizontal Angle Towards(
Players In Slot(Slot Of(Event Player), Team 2),
- Eye Position(Players In Slot(Slot Of(Event Player), Team 1))
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModX,
Vertical Angle From Direction(
Direction Towards(
- Eye Position(Players In Slot(Slot Of(Event Player), Team 2)),
- Eye Position(Players In Slot(Slot Of(Event Player), Team 1))
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModY
@@ -128,7 +152,8 @@ rule("aiSub_FacingStart")
);
// Position
- Else If(Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 2);
+ Else If(
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 2);
Start Facing(
Players In Slot(Slot Of(Event Player), Team 2),
Direction From Angles(
@@ -140,8 +165,10 @@ rule("aiSub_FacingStart")
Vertical Angle From Direction(
Direction Towards(
- Eye Position(Players In Slot(Slot Of(Event Player), Team 2)),
- Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModY
@@ -152,22 +179,28 @@ rule("aiSub_FacingStart")
);
// Relative
- Else If(Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 3);
+ Else If(
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 3);
+
Start Facing(
Players In Slot(Slot Of(Event Player), Team 2),
Direction From Angles(
Horizontal Angle Towards(
Players In Slot(Slot Of(Event Player), Team 2),
Position Of(Players In Slot(Slot Of(Event Player), Team 1))
- + Players In Slot(Slot Of(Event Player), Team 2).ai_FacingRelPosMod
+ + Players In Slot(
+ Slot Of(Event Player), Team 2).ai_FacingRelPosMod
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModX,
Vertical Angle From Direction(
Direction Towards(
- Eye Position(Players In Slot(Slot Of(Event Player), Team 2)),
- Position Of(Players In Slot(Slot Of(Event Player), Team 1))
- + Players In Slot(Slot Of(Event Player), Team 2).ai_FacingRelPosMod
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
+ + Players In Slot(
+ Slot Of(Event Player), Team 2).ai_FacingRelPosMod
)
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModY
@@ -182,10 +215,12 @@ rule("aiSub_FacingStart")
// Projectile
//
// Uses the horizontal angle towards the vector resulting from:
- // ((world vector of (speed * direction)) * (distance / projectile velocity)) + position of player
- // Basically taking the vector of "where the player will be in one second given current speed" and
- // scaling it based on distance from bot and projectile speed,
- // then adding the position of the player to offset it from (0, 0, 0)
+ // ((world vector of (speed * direction))
+ // * (distance / projectile velocity)) + position of player
+ // Basically taking the vector of "where the player will be in one
+ // second given current speed" and scaling it based on distance
+ // from bot and projectile speed, then adding the position of the
+ // player to offset it from (0, 0, 0)
//
Else If(Players In Slot(Slot Of(Event Player), Team 2).ai_AimType == 1);
@@ -198,25 +233,33 @@ rule("aiSub_FacingStart")
Players In Slot(Slot Of(Event Player), Team 2),
World Vector Of(
Speed Of(Players In Slot(Slot Of(Event Player), Team 1))
- * Throttle Of(Players In Slot(Slot Of(Event Player), Team 1)),
+ * Throttle Of(
+ Players In Slot(Slot Of(Event Player), Team 1)),
Players In Slot(Slot Of(Event Player), Team 1),
Rotation
)
* (
Distance Between(
- Position Of(Players In Slot(Slot Of(Event Player), Team 2)),
- Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
- / Players In Slot(Slot Of(Event Player), Team 2).ai_ProjectileSpeed
+ / Players In Slot(
+ Slot Of(Event Player), Team 2).ai_ProjectileSpeed
)
- + Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ + Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModX,
Vertical Angle From Direction(
Direction Towards(
- Eye Position(Players In Slot(Slot Of(Event Player), Team 2)),
- Eye Position(Players In Slot(Slot Of(Event Player), Team 1)) - Vector(0, 0.250, 0)
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 1))
+ - Vector(0, 0.250, 0)
)
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModY
@@ -227,7 +270,9 @@ rule("aiSub_FacingStart")
);
// Head
- Else If(Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 1);
+ Else If(
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 1);
+
Start Facing(
Players In Slot(Slot Of(Event Player), Team 2),
Direction From Angles(
@@ -235,25 +280,32 @@ rule("aiSub_FacingStart")
Players In Slot(Slot Of(Event Player), Team 2),
World Vector Of(
Speed Of(Players In Slot(Slot Of(Event Player), Team 1))
- * Throttle Of(Players In Slot(Slot Of(Event Player), Team 1)),
+ * Throttle Of(
+ Players In Slot(Slot Of(Event Player), Team 1)),
Players In Slot(Slot Of(Event Player), Team 1),
Rotation
)
* (
Distance Between(
- Position Of(Players In Slot(Slot Of(Event Player), Team 2)),
- Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
- / Players In Slot(Slot Of(Event Player), Team 2).ai_ProjectileSpeed
+ / Players In Slot(
+ Slot Of(Event Player), Team 2).ai_ProjectileSpeed
)
- + Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ + Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModX,
Vertical Angle From Direction(
Direction Towards(
- Eye Position(Players In Slot(Slot Of(Event Player), Team 2)),
- Eye Position(Players In Slot(Slot Of(Event Player), Team 1))
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModY
@@ -264,7 +316,9 @@ rule("aiSub_FacingStart")
);
// Position
- Else If(Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 2);
+ Else If(
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 2);
+
Start Facing(
Players In Slot(Slot Of(Event Player), Team 2),
Direction From Angles(
@@ -272,25 +326,32 @@ rule("aiSub_FacingStart")
Players In Slot(Slot Of(Event Player), Team 2),
World Vector Of(
Speed Of(Players In Slot(Slot Of(Event Player), Team 1))
- * Throttle Of(Players In Slot(Slot Of(Event Player), Team 1)),
+ * Throttle Of(
+ Players In Slot(Slot Of(Event Player), Team 1)),
Players In Slot(Slot Of(Event Player), Team 1),
Rotation
)
* (
Distance Between(
- Position Of(Players In Slot(Slot Of(Event Player), Team 2)),
- Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
- / Players In Slot(Slot Of(Event Player), Team 2).ai_ProjectileSpeed
+ / Players In Slot(
+ Slot Of(Event Player), Team 2).ai_ProjectileSpeed
)
- + Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ + Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModX,
Vertical Angle From Direction(
Direction Towards(
- Eye Position(Players In Slot(Slot Of(Event Player), Team 2)),
- Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModY
@@ -301,7 +362,9 @@ rule("aiSub_FacingStart")
);
// Relative
- Else If(Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 3);
+ Else If(
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 3);
+
Start Facing(
Players In Slot(Slot Of(Event Player), Team 2),
Direction From Angles(
@@ -309,27 +372,36 @@ rule("aiSub_FacingStart")
Players In Slot(Slot Of(Event Player), Team 2),
World Vector Of(
Speed Of(Players In Slot(Slot Of(Event Player), Team 1))
- * Throttle Of(Players In Slot(Slot Of(Event Player), Team 1)),
+ * Throttle Of(
+ Players In Slot(Slot Of(Event Player), Team 1)),
Players In Slot(Slot Of(Event Player), Team 1),
Rotation
)
* (
Distance Between(
- Position Of(Players In Slot(Slot Of(Event Player), Team 2)),
- Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
- / Players In Slot(Slot Of(Event Player), Team 2).ai_ProjectileSpeed
+ / Players In Slot(
+ Slot Of(Event Player), Team 2).ai_ProjectileSpeed
)
- + Position Of(Players In Slot(Slot Of(Event Player), Team 1))
- + Players In Slot(Slot Of(Event Player), Team 2).ai_FacingRelPosMod
+ + Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
+ + Players In Slot(
+ Slot Of(Event Player), Team 2).ai_FacingRelPosMod
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModX,
Vertical Angle From Direction(
Direction Towards(
- Eye Position(Players In Slot(Slot Of(Event Player), Team 2)),
- Position Of(Players In Slot(Slot Of(Event Player), Team 1))
- + Players In Slot(Slot Of(Event Player), Team 2).ai_FacingRelPosMod
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
+ + Players In Slot(
+ Slot Of(Event Player), Team 2).ai_FacingRelPosMod
)
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModY
@@ -354,36 +426,48 @@ rule("aiSub_FacingStart")
Players In Slot(Slot Of(Event Player), Team 2),
World Vector Of(
Speed Of(Players In Slot(Slot Of(Event Player), Team 1))
- * Throttle Of(Players In Slot(Slot Of(Event Player), Team 1)),
+ * Throttle Of(
+ Players In Slot(Slot Of(Event Player), Team 1)),
Players In Slot(Slot Of(Event Player), Team 1),
Rotation
)
* (
Distance Between(
- Position Of(Players In Slot(Slot Of(Event Player), Team 2)),
- Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
- / Players In Slot(Slot Of(Event Player), Team 2).ai_ProjectileSpeed
+ / Players In Slot(
+ Slot Of(Event Player), Team 2).ai_ProjectileSpeed
)
- + Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ + Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModX,
Vertical Angle From Direction(
Direction Towards(
- Eye Position(Players In Slot(Slot Of(Event Player), Team 2)),
- Eye Position(Players In Slot(Slot Of(Event Player), Team 1)) - Vector(0, 0.250, 0)
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 1))
+ - Vector(0, 0.250, 0)
)
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModY
+ Arcsine In Degrees(
-15.800 * (
Distance Between(
- Eye Position(Players In Slot(Slot Of(Event Player), Team 2)),
- Eye Position(Players In Slot(Slot Of(Event Player), Team 1)) - Vector(0, 0.250, 0)
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 1))
+ - Vector(0, 0.250, 0)
)
)
- / Players In Slot(Slot Of(Event Player), Team 2).ai_ProjectileSpeed ^ 2
+ / Players In Slot(
+ Slot Of(Event Player), Team 2).ai_ProjectileSpeed ^ 2
) / 2
),
Players In Slot(Slot Of(Event Player), Team 2).ai_AimTurnRate,
@@ -392,7 +476,9 @@ rule("aiSub_FacingStart")
);
// Head
- Else If(Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 1);
+ Else If(
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 1);
+
Start Facing(
Players In Slot(Slot Of(Event Player), Team 2),
Direction From Angles(
@@ -400,36 +486,46 @@ rule("aiSub_FacingStart")
Players In Slot(Slot Of(Event Player), Team 2),
World Vector Of(
Speed Of(Players In Slot(Slot Of(Event Player), Team 1))
- * Throttle Of(Players In Slot(Slot Of(Event Player), Team 1)),
+ * Throttle Of(
+ Players In Slot(Slot Of(Event Player), Team 1)),
Players In Slot(Slot Of(Event Player), Team 1),
Rotation
)
* (
Distance Between(
- Position Of(Players In Slot(Slot Of(Event Player), Team 2)),
- Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
- / Players In Slot(Slot Of(Event Player), Team 2).ai_ProjectileSpeed
+ / Players In Slot(
+ Slot Of(Event Player), Team 2).ai_ProjectileSpeed
)
- + Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ + Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModX,
Vertical Angle From Direction(
Direction Towards(
- Eye Position(Players In Slot(Slot Of(Event Player), Team 2)),
- Eye Position(Players In Slot(Slot Of(Event Player), Team 1))
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModY
+ Arcsine In Degrees(
-15.800 * (
Distance Between(
- Eye Position(Players In Slot(Slot Of(Event Player), Team 2)),
- Eye Position(Players In Slot(Slot Of(Event Player), Team 1))
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
)
- / Players In Slot(Slot Of(Event Player), Team 2).ai_ProjectileSpeed ^ 2
+ / Players In Slot(
+ Slot Of(Event Player), Team 2).ai_ProjectileSpeed ^ 2
) / 2
),
Players In Slot(Slot Of(Event Player), Team 2).ai_AimTurnRate,
@@ -438,7 +534,9 @@ rule("aiSub_FacingStart")
);
// Position
- Else If(Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 2);
+ Else If(
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 2);
+
Start Facing(
Players In Slot(Slot Of(Event Player), Team 2),
Direction From Angles(
@@ -446,36 +544,46 @@ rule("aiSub_FacingStart")
Players In Slot(Slot Of(Event Player), Team 2),
World Vector Of(
Speed Of(Players In Slot(Slot Of(Event Player), Team 1))
- * Throttle Of(Players In Slot(Slot Of(Event Player), Team 1)),
+ * Throttle Of(
+ Players In Slot(Slot Of(Event Player), Team 1)),
Players In Slot(Slot Of(Event Player), Team 1),
Rotation
)
* (
Distance Between(
- Position Of(Players In Slot(Slot Of(Event Player), Team 2)),
- Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
- / Players In Slot(Slot Of(Event Player), Team 2).ai_ProjectileSpeed
+ / Players In Slot(
+ Slot Of(Event Player), Team 2).ai_ProjectileSpeed
)
- + Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ + Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModX,
Vertical Angle From Direction(
Direction Towards(
- Eye Position(Players In Slot(Slot Of(Event Player), Team 2)),
- Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModY
+ Arcsine In Degrees(
-15.800 * (
Distance Between(
- Eye Position(Players In Slot(Slot Of(Event Player), Team 2)),
- Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
)
- / Players In Slot(Slot Of(Event Player), Team 2).ai_ProjectileSpeed ^ 2
+ / Players In Slot(
+ Slot Of(Event Player), Team 2).ai_ProjectileSpeed ^ 2
) / 2
),
Players In Slot(Slot Of(Event Player), Team 2).ai_AimTurnRate,
@@ -484,7 +592,9 @@ rule("aiSub_FacingStart")
);
// Relative
- Else If(Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 3);
+ Else If(
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 3);
+
Start Facing(
Players In Slot(Slot Of(Event Player), Team 2),
Direction From Angles(
@@ -492,39 +602,52 @@ rule("aiSub_FacingStart")
Players In Slot(Slot Of(Event Player), Team 2),
World Vector Of(
Speed Of(Players In Slot(Slot Of(Event Player), Team 1))
- * Throttle Of(Players In Slot(Slot Of(Event Player), Team 1)),
+ * Throttle Of(
+ Players In Slot(Slot Of(Event Player), Team 1)),
Players In Slot(Slot Of(Event Player), Team 1),
Rotation
)
* (
Distance Between(
- Position Of(Players In Slot(Slot Of(Event Player), Team 2)),
- Position Of(Players In Slot(Slot Of(Event Player), Team 1))
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
)
- / Players In Slot(Slot Of(Event Player), Team 2).ai_ProjectileSpeed
+ / Players In Slot(
+ Slot Of(Event Player), Team 2).ai_ProjectileSpeed
)
- + Position Of(Players In Slot(Slot Of(Event Player), Team 1))
- + Players In Slot(Slot Of(Event Player), Team 2).ai_FacingRelPosMod
+ + Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
+ + Players In Slot(
+ Slot Of(Event Player), Team 2).ai_FacingRelPosMod
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModX,
Vertical Angle From Direction(
Direction Towards(
- Eye Position(Players In Slot(Slot Of(Event Player), Team 2)),
- Position Of(Players In Slot(Slot Of(Event Player), Team 1))
- + Players In Slot(Slot Of(Event Player), Team 2).ai_FacingRelPosMod
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
+ + Players In Slot(
+ Slot Of(Event Player), Team 2).ai_FacingRelPosMod
)
)
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimModY
+ Arcsine In Degrees(
-15.800 * (
Distance Between(
- Eye Position(Players In Slot(Slot Of(Event Player), Team 2)),
- Position Of(Players In Slot(Slot Of(Event Player), Team 1))
- + Players In Slot(Slot Of(Event Player), Team 2).ai_FacingRelPosMod
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2)),
+ Position Of(
+ Players In Slot(Slot Of(Event Player), Team 1))
+ + Players In Slot(
+ Slot Of(Event Player), Team 2).ai_FacingRelPosMod
)
)
- / Players In Slot(Slot Of(Event Player), Team 2).ai_ProjectileSpeed ^ 2
+ / Players In Slot(
+ Slot Of(Event Player), Team 2).ai_ProjectileSpeed ^ 2
) / 2
),
Players In Slot(Slot Of(Event Player), Team 2).ai_AimTurnRate,
@@ -548,15 +671,35 @@ rule("aiSub_FacingLookAt")
{
Players In Slot(Slot Of(Event Player), Team 2).ai_CnAim = False;
Wait(2 / 60, Ignore Condition);
- Players In Slot(Slot Of(Event Player), Team 2).ai_AimTurnRate = Random Real(Players In Slot(Slot Of(Event Player), Team 2)
- .ai_FacingCapMin, Players In Slot(Slot Of(Event Player), Team 2).ai_FacingCapMin * 1.500);
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimTurnRate
+ = Random Real(
+ Players In Slot(Slot Of(Event Player), Team 2).ai_FacingCapMin,
+ Players In Slot(
+ Slot Of(Event Player), Team 2).ai_FacingCapMin * 1.500
+ );
Stop Facing(Players In Slot(Slot Of(Event Player), Team 2));
- Start Facing(Players In Slot(Slot Of(Event Player), Team 2), Direction Towards(Eye Position(Players In Slot(Slot Of(Event Player),
- Team 2)), Players In Slot(Slot Of(Event Player), Team 2).ai_LookAtVector), Evaluate Once(Random Real(Players In Slot(Slot Of(
- Event Player), Team 2).ai_FacingCapMin, Players In Slot(Slot Of(Event Player), Team 2).ai_FacingCapMax)), To World,
+ Start Facing(Players In Slot(Slot Of(Event Player), Team 2),
+ Direction Towards(
+ Eye Position(Players In Slot(Slot Of(Event Player), Team 2)),
+ Players In Slot(Slot Of(Event Player), Team 2).ai_LookAtVector),
+ Evaluate Once(
+ Random Real(
+ Players In Slot(Slot Of(Event Player), Team 2).ai_FacingCapMin,
+ Players In Slot(Slot Of(Event Player), Team 2).ai_FacingCapMax)),
+ To World,
Direction and Turn Rate);
- Wait Until(Is In View Angle(Players In Slot(Slot Of(Event Player), Team 2), Players In Slot(Slot Of(Event Player), Team 2)
- .ai_LookAtVector - Vector(0, Y Component Of(Eye Position(Players In Slot(Slot Of(Event Player), Team 2))), 0), 12.500), 2);
+ Wait Until(
+ Is In View Angle(
+ Players In Slot(Slot Of(Event Player), Team 2),
+ Players In Slot(Slot Of(Event Player), Team 2).ai_LookAtVector
+ - Vector(
+ 0,
+ Y Component Of(
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2))),
+ 0),
+ 12.500),
+ 2);
Stop Facing(Players In Slot(Slot Of(Event Player), Team 2));
}
}
@@ -571,8 +714,10 @@ rule("aiSub_FacingReset")
actions
{
- Players In Slot(Slot Of(Event Player), Team 2).ai_AimType = Players In Slot(Slot Of(Event Player), Team 2).ai_AimTypeDefault;
- Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase = Players In Slot(Slot Of(Event Player), Team 2).ai_AimBaseDefault;
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimType
+ = Players In Slot(Slot Of(Event Player), Team 2).ai_AimTypeDefault;
+ Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase
+ = Players In Slot(Slot Of(Event Player), Team 2).ai_AimBaseDefault;
Call Subroutine(aiSub_FacingStart);
}
}
@@ -590,14 +735,22 @@ rule("AI Aim Mod Calculation")
Stop Chasing Player Variable(Event Player, ai_AimModX);
Stop Chasing Player Variable(Event Player, ai_AimModY);
- If(Array Contains(Global.c_ScopeHeroes, Hero Of(Event Player)) && Is Firing Secondary(Event Player));
- If(Horizontal Angle Towards(Event Player, Players In Slot(Slot Of(Event Player), Team 1)) > 0);
+ If(Array Contains(Global.c_ScopeHeroes, Hero Of(Event Player))
+ && Is Firing Secondary(Event Player));
+
+ If(
+ Horizontal Angle Towards(
+ Event Player,
+ Players In Slot(Slot Of(Event Player), Team 1)
+ ) > 0);
+
Chase Player Variable Over Time(
Event Player,
ai_AimModX,
Random Real(0,
- (Global.c_MaxDifficulty - Players In Slot(Slot Of(Event Player), Team 1).p_Difficulty) * 0.250 + 0.250
- ),
+ (Global.c_MaxDifficulty - Players In Slot(
+ Slot Of(Event Player), Team 1).p_Difficulty) * 0.250
+ + 0.250),
Random Real(0.100, 0.250),
None
);
@@ -606,26 +759,34 @@ rule("AI Aim Mod Calculation")
Event Player,
ai_AimModX,
Random Real(
- (Global.c_MaxDifficulty - Players In Slot(Slot Of(Event Player), Team 1).p_Difficulty) * -0.250 - 0.250,
- 0
- ),
+ (Global.c_MaxDifficulty - Players In Slot(
+ Slot Of(Event Player), Team 1).p_Difficulty) * -0.250
+ - 0.250,
+ 0),
Random Real(0.100, 0.250),
None
);
End;
Event Player.ai_AimModY = Random Real(
- (Global.c_MaxDifficulty - Players In Slot(Slot Of(Event Player), Team 1).p_Difficulty) * -0.250 - 0.250,
- (Global.c_MaxDifficulty - Players In Slot(Slot Of(Event Player), Team 1).p_Difficulty) * 0.250 + 0.250
+ (Global.c_MaxDifficulty - Players In Slot(
+ Slot Of(Event Player), Team 1).p_Difficulty) * -0.250 - 0.250,
+ (Global.c_MaxDifficulty - Players In Slot(
+ Slot Of(Event Player), Team 1).p_Difficulty) * 0.250 + 0.250
);
Else;
- If(Horizontal Angle Towards(Event Player, Players In Slot(Slot Of(Event Player), Team 1)) > 0);
+ If(
+ Horizontal Angle Towards(
+ Event Player,
+ Players In Slot(Slot Of(Event Player), Team 1)) > 0);
Chase Player Variable Over Time(
Event Player,
ai_AimModX,
Random Real(0,
- (Global.c_MaxDifficulty - Players In Slot(Slot Of(Event Player), Team 1).p_Difficulty) * 0.500 + 0.500
+ (Global.c_MaxDifficulty - Players In Slot(
+ Slot Of(Event Player), Team 1).p_Difficulty)
+ * 0.500 + 0.500
),
Random Real(0.100, 0.250),
None
@@ -635,7 +796,9 @@ rule("AI Aim Mod Calculation")
Event Player,
ai_AimModX,
Random Real(
- (Global.c_MaxDifficulty - Players In Slot(Slot Of(Event Player), Team 1).p_Difficulty) * -0.500 - 0.500,
+ (Global.c_MaxDifficulty - Players In Slot(
+ Slot Of(Event Player), Team 1).p_Difficulty)
+ * -0.500 - 0.500,
0
),
Random Real(0.100, 0.250),
@@ -644,8 +807,10 @@ rule("AI Aim Mod Calculation")
End;
Event Player.ai_AimModY = Random Real(
- (Global.c_MaxDifficulty - Players In Slot(Slot Of(Event Player), Team 1).p_Difficulty) * -0.350 - 0.350,
- (Global.c_MaxDifficulty - Players In Slot(Slot Of(Event Player), Team 1).p_Difficulty) * 0.350 + 0.350
+ (Global.c_MaxDifficulty - Players In Slot(
+ Slot Of(Event Player), Team 1).p_Difficulty) * -0.350 - 0.350,
+ (Global.c_MaxDifficulty - Players In Slot(
+ Slot Of(Event Player), Team 1).p_Difficulty) * 0.350 + 0.350
);
End;
}
@@ -669,14 +834,19 @@ rule("AI Aim Calculation")
Chase Player Variable Over Time(
Event Player,
ai_AimTurnRate,
- Random Real(Event Player.ai_FacingPadMin, Event Player.ai_FacingPadMax) / 1.5,
+ Random Real(Event Player.ai_FacingPadMin,
+ Event Player.ai_FacingPadMax) / 1.5,
Random Real(0.025, 0.200),
None
);
Wait(Random Real(0.025, 0.200), Ignore Condition);
Stop Chasing Player Variable(Event Player, ai_AimTurnRate);
- Else If(Event Player.ai_RetCastDistance < 10 && Random Real(0, 1) < 0.900 - Event Player.ai_ChanceMod);
+
+ Else If(Event Player.ai_RetCastDistance < 10 && Random Real(0, 1)
+ < 0.900 - Event Player.ai_ChanceMod);
+
Call Subroutine(aiSub_AimMouseStop);
+
Else;
Event Player.ai_AimTurnRate = (
Event Player.ai_FacingAngleMod
@@ -684,15 +854,20 @@ rule("AI Aim Calculation")
Facing Direction Of(Event Player),
Direction Towards(
Eye Position(Event Player),
- Eye Position(Players In Slot(Slot Of(Event Player), Team 1)) - Vector(0, 0.300, 0)
+ Eye Position(Players In Slot(
+ Slot Of(Event Player), Team 1)) - Vector(0, 0.300, 0)
)
)
- ) ^ Event Player.ai_FacingAnglePow + Random Real(Event Player.ai_FacingPadMin, Event Player.ai_FacingPadMax);
+ ) ^ Event Player.ai_FacingAnglePow
+ + Random Real(Event Player.ai_FacingPadMin,
+ Event Player.ai_FacingPadMax);
// Start Rule(aiSub_AimModSet, Restart Rule);
End;
- If(Array Contains(Global.c_ScopeHeroes, Hero Of(Event Player)) && Is Firing Secondary(Event Player));
+ If(Array Contains(Global.c_ScopeHeroes, Hero Of(Event Player))
+ && Is Firing Secondary(Event Player));
+
Event Player.ai_AimTurnRate = Event Player.ai_AimTurnRate / 1.500;
End;
}
@@ -712,10 +887,13 @@ rule("AI Aim Mouse Stop")
Small Message(Event Player, Custom String("aim stop"));
End;
- Event Player.ai_AimStopTime = Total Time Elapsed + Random Real(0.450, 0.900) - Event Player.ai_ChanceMod;
+ Event Player.ai_AimStopTime
+ = Total Time Elapsed
+ + Random Real(0.450, 0.900) - Event Player.ai_ChanceMod;
Stop Chasing Player Variable(Event Player, ai_AimTurnRate);
- Chase Player Variable At Rate(Event Player, ai_AimTurnRate, 0, Random Integer(360, 720), None);
+ Chase Player Variable At Rate(Event Player, ai_AimTurnRate,
+ 0, Random Integer(360, 720), None);
Wait Until(Event Player.ai_AimTurnRate == 0, 0.9);
Stop Chasing Player Variable(Event Player, ai_AimTurnRate);
}
@@ -733,22 +911,68 @@ rule("aiSub_FlickIn")
{
Stop Facing(Players In Slot(Slot Of(Event Player), Team 2));
If(Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 0);
- Start Facing(Players In Slot(Slot Of(Event Player), Team 2), Direction Towards(Eye Position(Event Player), Eye Position(
- Players In Slot(Slot Of(Event Player), Team 1)) - Vector(0, 0.250, 0)), Evaluate Once(Random Integer(Players In Slot(Slot Of(
- Event Player), Team 2).ai_FacingCapMax - 180, Players In Slot(Slot Of(Event Player), Team 2).ai_FacingCapMax)), To World,
+ Start Facing(Players In Slot(Slot Of(Event Player), Team 2),
+ Direction Towards(
+ Eye Position(Event Player),
+ Eye Position(Players In Slot(Slot Of(Event Player), Team 1))
+ - Vector(0, 0.250, 0)),
+ Evaluate Once(
+ Random Integer(
+ Players In Slot(Slot Of(Event Player), Team 2).ai_FacingCapMax
+ - 180,
+ Players In Slot(
+ Slot Of(Event Player), Team 2).ai_FacingCapMax)),
+ To World,
Direction and Turn Rate);
- Wait Until(Is In View Angle(Players In Slot(Slot Of(Event Player), Team 2), Vector(X Component Of(Eye Position(Players In Slot(
- Slot Of(Event Player), Team 1)) - Vector(0, 0.250, 0)), Y Component Of(Eye Position(Players In Slot(Slot Of(Event Player),
- Team 1)) - Vector(0, 0.250, 0)) - Y Component Of(Eye Position(Players In Slot(Slot Of(Event Player), Team 2)) - Vector(0,
- 0.250, 0)), Z Component Of(Eye Position(Players In Slot(Slot Of(Event Player), Team 1)))), 0.500), 1);
+ Wait Until(
+ Is In View Angle(
+ Players In Slot(Slot Of(Event Player), Team 2),
+ Vector(
+ X Component Of(
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 1))
+ - Vector(0, 0.250, 0)),
+ Y Component Of(
+ Eye Position(Players In Slot(Slot Of(Event Player),Team 1))
+ - Vector(0, 0.250, 0))
+ - Y Component Of(
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2))
+ - Vector(0, 0.250, 0)),
+ Z Component Of(
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 1)))),
+ 0.500),
+ 1);
Else If(Players In Slot(Slot Of(Event Player), Team 2).ai_AimBase == 1);
- Start Facing(Players In Slot(Slot Of(Event Player), Team 2), Direction Towards(Eye Position(Event Player), Eye Position(
- Players In Slot(Slot Of(Event Player), Team 1))), Evaluate Once(Random Integer(Players In Slot(Slot Of(Event Player), Team 2)
- .ai_FacingCapMax - 180, Players In Slot(Slot Of(Event Player), Team 2).ai_FacingCapMax)), To World, Direction and Turn Rate);
- Wait Until(Is In View Angle(Players In Slot(Slot Of(Event Player), Team 2), Vector(X Component Of(Eye Position(Players In Slot(
- Slot Of(Event Player), Team 1))), Y Component Of(Eye Position(Players In Slot(Slot Of(Event Player), Team 1)))
- - Y Component Of(Eye Position(Players In Slot(Slot Of(Event Player), Team 2))), Z Component Of(Eye Position(Players In Slot(
- Slot Of(Event Player), Team 1)))), 0.500), 1);
+ Start Facing(Players In Slot(Slot Of(Event Player), Team 2),
+ Direction Towards(Eye Position(Event Player),
+ Eye Position(Players In Slot(Slot Of(Event Player), Team 1))),
+ Evaluate Once(
+ Random Integer(
+ Players In Slot(Slot Of(Event Player), Team 2).ai_FacingCapMax
+ - 180,
+ Players In Slot(
+ Slot Of(Event Player), Team 2).ai_FacingCapMax)),
+ To World,
+ Direction and Turn Rate);
+ Wait Until(
+ Is In View Angle(Players In Slot(Slot Of(Event Player), Team 2),
+ Vector(
+ X Component Of(
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 1))),
+ Y Component Of(
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 1)))
+ - Y Component Of(
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 2))),
+ Z Component Of(
+ Eye Position(
+ Players In Slot(Slot Of(Event Player), Team 1)))),
+ 0.500),
+ 1);
End;
}
}
@@ -764,10 +988,21 @@ rule("aiSub_FlickOut")
actions
{
Stop Facing(Players In Slot(Slot Of(Event Player), Team 2));
- Start Facing(Players In Slot(Slot Of(Event Player), Team 2), Direction From Angles(Horizontal Facing Angle Of(Players In Slot(
- Slot Of(Event Player), Team 2)) - Random Real(0.600, 1), Vertical Facing Angle Of(Players In Slot(Slot Of(Event Player),
- Team 2)) - Random Real(0.300, 0.700)), Evaluate Once(Random Integer(Players In Slot(Slot Of(Event Player), Team 2)
- .ai_FacingCapMax - 180, Players In Slot(Slot Of(Event Player), Team 2).ai_FacingCapMax)), To World, None);
+ Start Facing(Players In Slot(Slot Of(Event Player), Team 2),
+ Direction From Angles(
+ Horizontal Facing Angle Of(
+ Players In Slot(Slot Of(Event Player), Team 2))
+ - Random Real(0.600, 1),
+ Vertical Facing Angle Of(
+ Players In Slot(Slot Of(Event Player),Team 2))
+ - Random Real(0.300, 0.700)),
+ Evaluate Once(
+ Random Integer(
+ Players In Slot(Slot Of(Event Player), Team 2).ai_FacingCapMax
+ - 180,
+ Players In Slot(Slot Of(Event Player), Team 2).ai_FacingCapMax)),
+ To World,
+ None);
Wait(Random Real(0.100, 0.200), Ignore Condition);
Call Subroutine(aiSub_FacingReset);
}
diff --git a/tools/trim_trailing_whitespace.sh b/tools/trim_trailing_whitespace.sh
new file mode 100755
index 0000000..d942f92
--- /dev/null
+++ b/tools/trim_trailing_whitespace.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+find . -type f -iregex '\(.*.ow\|.*.owh\|.*Makefile\|.*.sh\)' \
+ -exec sed -i 's/\s\+$//g' '{}' \;
+
+exit
From 897d15e8af155c38c973c7a15ffdf1a590ff9ff9 Mon Sep 17 00:00:00 2001
From: Luna R
Date: Tue, 15 Mar 2022 23:54:01 +0000
Subject: [PATCH 02/11] Begin adding rudimentary documentation to all rules
---
src/ai.ow | 25 +++++++++++++++++++++++++
src/defines.ow | 4 ++--
src/main.ow | 6 ++++++
tools/overwatch_workshop_minifier.sh | 1 +
tools/trim_trailing_whitespace.sh | 5 +++--
5 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/src/ai.ow b/src/ai.ow
index 11a8940..e156f67 100644
--- a/src/ai.ow
+++ b/src/ai.ow
@@ -1,3 +1,7 @@
+// ai.ow
+// Primary event rules for hero AI
+
+// Heal AI and call subroutine to enable AI
rule("AI Enable")
{
event
@@ -23,6 +27,7 @@ rule("AI Enable")
}
}
+// Start AI aim calculation loop
rule("AI Aim Calculation Loop")
{
event
@@ -75,6 +80,7 @@ rule("AI Aim Calculation Loop")
}
}
+// Stop AI aiming
rule("AI Aim Stop")
{
event
@@ -102,6 +108,7 @@ rule("AI Aim Stop")
}
}
+// Flick aim when Player is far away from the Bot's reticle
rule("AI Aim Flick")
{
event
@@ -132,6 +139,7 @@ rule("AI Aim Flick")
}
}
+// Bot melee Player when health is low
rule("AI Attack Melee")
{
event
@@ -160,6 +168,7 @@ rule("AI Attack Melee")
}
}
+// Start Bot facing Player
rule("AI Aim Start")
{
event
@@ -183,6 +192,7 @@ rule("AI Aim Start")
}
}
+// Whether or not the Bot is able to and allowed to aim
rule("AI Rule Can Aim")
{
event
@@ -209,6 +219,7 @@ rule("AI Rule Can Aim")
}
}
+// Whether or not the Bot is able to and allowed to attack
rule("AI Rule Can Attack")
{
event
@@ -235,6 +246,7 @@ rule("AI Rule Can Attack")
}
}
+// Whether or not the Bot is able to and allowed to use abilities
rule("AI Rule Can Use Abilities")
{
event
@@ -262,6 +274,7 @@ rule("AI Rule Can Use Abilities")
}
}
+// If hacked, the Bot cannot use abilities
rule("AI Rule Status Hacked")
{
event
@@ -284,6 +297,7 @@ rule("AI Rule Status Hacked")
}
}
+// If knocked down, the Bot cannot aim, attack, or use abilities
rule("AI Rule Status Knocked Down")
{
event
@@ -309,6 +323,7 @@ rule("AI Rule Status Knocked Down")
}
}
+// If asleep, the Bot cannot aim, attack, or use abilities
rule("AI Rule Status Asleep")
{
event
@@ -334,6 +349,7 @@ rule("AI Rule Status Asleep")
}
}
+// If frozen, the Bot cannot aim, attack, or use abilities
rule("AI Rule Status Frozen")
{
event
@@ -359,6 +375,7 @@ rule("AI Rule Status Frozen")
}
}
+// If phased out, the Bot cannot attack or use abilities
rule("AI Rule Status Phased Out")
{
event
@@ -382,6 +399,7 @@ rule("AI Rule Status Phased Out")
}
}
+// If stunned, the Bot cannot aim, attack, or use abilities
rule("AI Rule Status Stunned")
{
event
@@ -407,6 +425,7 @@ rule("AI Rule Status Stunned")
}
}
+// Bot briefly strafe in a random direction upon taking damage
rule("AI Movement WASD Strafe On Dmg")
{
event
@@ -439,6 +458,7 @@ rule("AI Movement WASD Strafe On Dmg")
}
}
+// Bot move closer if further than `ai_OptimalDistance`
rule("AI Movement WASD Move Closer")
{
event
@@ -499,6 +519,7 @@ rule("AI Movement WASD Move Closer")
}
}
+// Bot move further if closer than `ai_OptimalDistance`
rule("AI Movement WASD Move Farther")
{
event
@@ -542,6 +563,7 @@ rule("AI Movement WASD Move Farther")
}
}
+// i don't actually know what this does
rule("AI Optimal Distance Default Resize")
{
event
@@ -575,6 +597,7 @@ rule("AI Optimal Distance Default Resize")
}
}
+// Bot crouch
rule("AI Movement Crouch")
{
event
@@ -601,6 +624,7 @@ rule("AI Movement Crouch")
}
}
+// Bot jump
rule("AI Movement Jump")
{
event
@@ -626,6 +650,7 @@ rule("AI Movement Jump")
}
}
+// Enable AI if Player just turned on Quick Mode
rule("Quick Mode AI Enable")
{
event
diff --git a/src/defines.ow b/src/defines.ow
index 80043d3..377d056 100644
--- a/src/defines.ow
+++ b/src/defines.ow
@@ -13,8 +13,8 @@ rule("Global Defines")
//
// Info: version, build, links...
//
- Global.c_Version = Custom String("0.15.1");
- Global.c_BuildDate = Custom String("20220203");
+ Global.c_Version = Custom String("0.15.2");
+ Global.c_BuildDate = Custom String("20220315");
Global.c_WorkshopCode = Custom String("5DPKQ");
Global.c_DeveloperName = Custom String("Raven#112503");
Global.c_TwitchURL = Custom String("twitch.tv/RavenLuna");
diff --git a/src/main.ow b/src/main.ow
index c601dda..7e43959 100644
--- a/src/main.ow
+++ b/src/main.ow
@@ -1,3 +1,8 @@
+// main.ow
+// The inital portion of the workshop mode containing global settings and
+// the main tick loop
+
+// Workshop Settings that can be modified in the game lobby
rule("Global Settings")
{
event
@@ -135,6 +140,7 @@ rule("Global Settings")
}
}
+// Main 60hz tick loop used by rules to spread computations over ticks
rule("Global Main Tick Loop")
{
event
diff --git a/tools/overwatch_workshop_minifier.sh b/tools/overwatch_workshop_minifier.sh
index 01f9c91..d752e02 100755
--- a/tools/overwatch_workshop_minifier.sh
+++ b/tools/overwatch_workshop_minifier.sh
@@ -1,4 +1,5 @@
#!/bin/bash
+# overwatch_workshop_minifier.sh
# Minify Overwatch Workshop scripts from stdin or file
function minify_pipe
diff --git a/tools/trim_trailing_whitespace.sh b/tools/trim_trailing_whitespace.sh
index d942f92..08123b7 100755
--- a/tools/trim_trailing_whitespace.sh
+++ b/tools/trim_trailing_whitespace.sh
@@ -1,6 +1,7 @@
#!/bin/bash
-
+# trim_trailing_whitespace.sh
+# Find and trim trailing whitespace from project source
find . -type f -iregex '\(.*.ow\|.*.owh\|.*Makefile\|.*.sh\)' \
- -exec sed -i 's/\s\+$//g' '{}' \;
+ -exec sed -i 's/\s\+$//g' '{}' \;
exit
From 354c91e3d0fb0b19d98c88f27d36c542f29732d9 Mon Sep 17 00:00:00 2001
From: Luna R
Date: Mon, 4 Apr 2022 03:47:30 +0000
Subject: [PATCH 03/11] Update minifier to minimize function names, refactor
makefile to minify seperately, renamed mode extension from workshop to ow
---
Makefile | 6 ++--
tools/overwatch_workshop_minifier.sh | 54 ++++++++++++++++++++++++----
2 files changed, 51 insertions(+), 9 deletions(-)
diff --git a/Makefile b/Makefile
index af24a8c..f061549 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ SHELL = /bin/bash
.SUFFIXES:
.SUFFIXES: .owh .ow
-MODEFILE=practicefieldexpanse.workshop.txt
+MODEFILE=practicefieldexpanse.ow.txt
FILES= \
src/main.owh \
@@ -53,8 +53,8 @@ FILES= \
src/ai/ai_Zenyatta.ow
$(MODEFILE): $(FILES)
- cat $(FILES) | ./tools/overwatch_workshop_minifier.sh > $(MODEFILE)
- cat $(MODEFILE) | clip.exe
+ cat $(FILES) > $(MODEFILE)
+ ./tools/overwatch_workshop_minifier.sh $(MODEFILE)
clean:
rm -f $(MODEFILE)
diff --git a/tools/overwatch_workshop_minifier.sh b/tools/overwatch_workshop_minifier.sh
index d752e02..b4402d3 100755
--- a/tools/overwatch_workshop_minifier.sh
+++ b/tools/overwatch_workshop_minifier.sh
@@ -2,6 +2,21 @@
# overwatch_workshop_minifier.sh
# Minify Overwatch Workshop scripts from stdin or file
+function rename_functions
+{
+ # New names for functions: a-z, A-Z, then all possible two letter combos
+ min_chars=(`echo {{a..z},{A..Z},{a..z}{a..z}}`)
+
+ # There aren't going to be more than 256 of any variable
+ for i in `seq 0 255`; do
+ # Iterate through functions with the current $i number
+ # then rename each to their respective minified names
+ for j in $(grep -e "^\s*$i:.*$" $1 | sed 's/^.*:\s*//g'); do
+ sed -i "s/$j/${min_chars[$i]}/g" $1
+ done
+ done
+}
+
function minify_pipe
{
sed 's/\/\/.*$//' `# Remove C++ style one line comments "//"` \
@@ -11,12 +26,39 @@ function minify_pipe
| sed 's/\/\*.*\*\///' `# Remove C style comments "/* */"`
}
-if [ $# -eq 0 ]; then
- # No arguments given. Using stdin...
- minify_pipe
-else
- basename=$(echo $1 | sed 's/\..*$//')
- cat "$1" | minify_pipe > "$basename.min.workshop"
+# Set our new name for the minified file
+basename=$(echo $1 | sed 's/\..*$//')
+new_file="$basename"".min.ow.txt"
+
+# Check if it already exists and prompt for continue if it does
+if [ -f $new_file ]; then
+ echo
+ echo "WARNING: $new_file already exists"
+ while true; do
+ read -p "Would you like to overwrite it? (y/n): " yn
+ case $yn in
+ [Yy]* ) break;;
+ [Nn]* ) exit;;
+ * ) echo "Please answer yes or no.";;
+ esac
+ done
fi
+# Create a copy of the original file as our minified file
+cp "$1" "$new_file"
+
+# Do the minifying
+rename_functions "$new_file"
+echo $(cat "$new_file" | minify_pipe) > "$new_file"
+
+# Get the file sizes
+old_file_size=$(du -b $1)
+new_file_size=$(du -b $new_file)
+
+# All done messages
+echo
+echo "Wrote minified Overwatch Workshop script file '$new_file'"
+echo "Old: $old_file_size"
+echo "New: $new_file_size"
+
exit
From 16070d26b848c2f9b63f279df4a0153677a2af3c Mon Sep 17 00:00:00 2001
From: Luna R
Date: Mon, 4 Apr 2022 04:19:07 +0000
Subject: [PATCH 04/11] fix minifier outputting nothing due to recursion
---
.gitignore | 2 +-
tools/overwatch_workshop_minifier.sh | 8 +++++---
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/.gitignore b/.gitignore
index 273d7da..715c9d8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-practicefieldexpanse.workshop.txt
+practicefieldexpanse.*.txt
diff --git a/tools/overwatch_workshop_minifier.sh b/tools/overwatch_workshop_minifier.sh
index b4402d3..d5bb686 100755
--- a/tools/overwatch_workshop_minifier.sh
+++ b/tools/overwatch_workshop_minifier.sh
@@ -28,12 +28,13 @@ function minify_pipe
# Set our new name for the minified file
basename=$(echo $1 | sed 's/\..*$//')
-new_file="$basename"".min.ow.txt"
+new_file="$basename.min.ow.txt"
+echo "$new_file"
# Check if it already exists and prompt for continue if it does
if [ -f $new_file ]; then
echo
- echo "WARNING: $new_file already exists"
+ echo "WARNING: '$new_file' already exists"
while true; do
read -p "Would you like to overwrite it? (y/n): " yn
case $yn in
@@ -49,7 +50,8 @@ cp "$1" "$new_file"
# Do the minifying
rename_functions "$new_file"
-echo $(cat "$new_file" | minify_pipe) > "$new_file"
+cat "$new_file" | minify_pipe > "$new_file.tmp"
+mv "$new_file.tmp" "$new_file"
# Get the file sizes
old_file_size=$(du -b $1)
From 3bbe69add35f1753703527097a470ab6f1e1bd12 Mon Sep 17 00:00:00 2001
From: Luna R
Date: Mon, 4 Apr 2022 08:05:29 +0000
Subject: [PATCH 05/11] begin developing git page
---
docs/assets/css/style.css | 134 ++++++++++++++++++++++++++
docs/{ => assets/images}/PFEPromo.png | Bin
docs/index.html | 123 +++++++++++++++++++++++
3 files changed, 257 insertions(+)
create mode 100644 docs/assets/css/style.css
rename docs/{ => assets/images}/PFEPromo.png (100%)
create mode 100644 docs/index.html
diff --git a/docs/assets/css/style.css b/docs/assets/css/style.css
new file mode 100644
index 0000000..037ea12
--- /dev/null
+++ b/docs/assets/css/style.css
@@ -0,0 +1,134 @@
+@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@570&display=swap");
+:root {
+}
+
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+body {
+ background-color: rgb(230, 230, 230);
+}
+
+h1,
+h2,
+h3,
+h4,
+h5 {
+ font-family: "Montserrat", sans-serif;
+ font-weight: 700;
+ line-height: 1.3em;
+}
+
+header nav {
+ height: 100px;
+ background-color: rgb(138, 198, 209);
+}
+
+header nav ul {
+ display: flex;
+ justify-content: space-evenly;
+ align-items: center;
+ height: 100%;
+}
+
+header nav ul li a {
+ text-decoration: none;
+ height: 100%;
+}
+
+header nav ul li {
+ font-family: "Montserrat", sans-serif;
+ font-weight: 700;
+ font-size: 1.2em;
+ color: hsl(177, 53%, 15%);
+ list-style: none;
+}
+
+header nav ul li:first-of-type {
+ font-size: 1.7em;
+ font-weight: 900;
+}
+
+a,
+a:visited,
+a:hover,
+a:active {
+ color: inherit;
+}
+
+header nav ul li a:hover {
+ text-shadow: 1px 2px 2px rgba(0, 0, 0, 0.25);
+}
+
+.main-content {
+ width: 100%;
+ max-width: 960px;
+ margin: 0 auto;
+ padding: 0 25px;
+ /* text-align: center; */
+}
+
+.main-content p {
+ font-family: "Montserrat", sans-serif;
+ font-size: 1em;
+ font-weight: 200;
+ text-align: justify;
+ line-height: 1.4em;
+}
+
+.main-content h2 {
+ margin-top: 20px;
+}
+
+.about {
+ display: flex;
+ align-items: center;
+ margin: 15px;
+ padding: 10px;
+}
+
+.about p,
+.about h3 {
+ margin-top: 15px;
+}
+
+.about #about-txt {
+ padding-left: 100px;
+}
+
+#hero {
+ width: 400px;
+ margin: 15px;
+ border-radius: 15px;
+}
+
+.donate {
+ text-align: center;
+}
+
+footer {
+ background-color: bisque;
+ text-align: center;
+ width: 100%;
+}
+
+footer p {
+ max-width: 960px;
+ margin: 0 auto;
+}
+
+@media screen and (max-width: 800px) {
+ header nav {
+ height: 50px;
+ }
+
+ #hero {
+ width: 80%;
+ }
+ .about {
+ flex-direction: column;
+ }
+}
diff --git a/docs/PFEPromo.png b/docs/assets/images/PFEPromo.png
similarity index 100%
rename from docs/PFEPromo.png
rename to docs/assets/images/PFEPromo.png
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 0000000..7427e3d
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,123 @@
+
+
+
+
+
+ Practice Field: Expanse
+
+
+
+
+
+
+
+
+
+
+
Practice Field: Expanse
+
+ is a sandbox practice game mode for the Overwatch Workshop.
+
+
+ Up to six players are spread across the map "Workshop
+ Expanse". Each player is put in a bubble against an enemy
+ dummy bot. The player kills the enemy bot and progresses to
+ the next hero in the list when the "Kill Goal" is met. The
+ player can select any hero they would like to practice on. The
+ enemy spawn distances and play area will automatically be
+ adapted to the optimal sizes for the chosen hero.
+
+
+
+
AI Bots
+
+ Lorem ipsum, dolor sit amet consectetur adipisicing elit. Tenetur
+ perferendis unde minima perspiciatis ea dolorem dignissimos facere
+ culpa cupiditate voluptatibus sit exercitationem necessitatibus eum
+ placeat libero laudantium, molestias rerum voluptatum.
+
+
Scaling Difficulties
+
In-Game Menu
+
Sandbox Approach To Practice
+
Development History
+
+ I started this project in January 2020 as soon as the "Workshop
+ Expanse" map was released on the PTR.
+
+
+ The idea came from my first practice mode on the Practice Range that
+ spawned random types of enemies and gave them
+ very rudimentary movement.
+
+
+ I knew I wanted something that would spawn enemies at random
+ distances from me facing a random direction. Initially I only
+ intended it to be a small Widowmaker warmup and flick practice mode.
+
+
+ It is currently in the pre-release stage with changes happening
+ rapidly.
+
+
+
Donate
+
+
+ I greatly appreciate any and all donations. This is a passion
+ project of mine that I have put countless hours into. Any support
+ is very welcome. 🥰
+
- Lorem ipsum, dolor sit amet consectetur adipisicing elit. Tenetur
- perferendis unde minima perspiciatis ea dolorem dignissimos facere
- culpa cupiditate voluptatibus sit exercitationem necessitatibus eum
- placeat libero laudantium, molestias rerum voluptatum.
-
-
Scaling Difficulties
-
In-Game Menu
-
Sandbox Approach To Practice
+
+
AI Bots
+
+ The bots have AI scripting for every hero that I have
+ meticulously programmed over many months.
+
+
+
+
Scaling Difficulties
+
+ The are currently 11 difficulties ranging from "No AI Easy" ('No
+ AI' meaning they do not have AI or attack, but simply move.) to
+ "AI Bronze" to "AI Top 500". The difficulties named for
+ competitive tiers approximately reflect the aim, movement, and
+ reaction time of real players at those tiers.
+
+
+
+
In-Game Menu
+
+ The custom in-game menu can be accessed at any time with a quick
+ key combination. The menu is navigated with the WASD keys.
+
+
The menu allows the player to:
+
+
Set difficulty to the desired level
+
Enable or Disable various modes that affect play
+
Set the language
+
and more...
+
+
+
+
Sandbox Approach To Practice
+
+ Practice Field: Expanse is designed so that players can configure
+ their own settings to best aid what they would like to practice.
+
+
A few examples:
+
+ The player wishes to get better at
+ Roadhog's
+ Chain Hook combo against supports.
+
+
+
Open the in-game menu,
+
+ set the "1 Second Cooldown" mode to "Player" so that the
+ player's cooldowns are automatically refreshed
+
+
+ While still in the menu, set the "Hero Class" to "Support"
+
+
Close the menu and hook to your heart's content
+
+
+ The player would just like to practice a
+ Widowmaker 1v1 as long as they are
+ in queue.
+
+
+
+ Select Widowmaker * Using the
+ key combination described in the top left to select a specific
+ enemy hero, select Widowmaker
+
+
+ Open the in-game menu, set the difficulty to the desired
+ difficulty and set the "Kill Goal" to "Infinite"
+
+
Close the menu and begin the 1v1
+
+
Development History
I started this project in January 2020 as soon as the "Workshop
@@ -78,46 +140,49 @@
Development History
It is currently in the pre-release stage with changes happening
rapidly.
-
+
Donate
-
I greatly appreciate any and all donations. This is a passion
project of mine that I have put countless hours into. Any support
is very welcome. 🥰